Changes during Git migration:

- Added Extended Allocator support for Boost.Container.
- Improved Doxygen generated reference
- Fixed ticket #9338 ("VS2005 compiler errors in swap() definition after including container/memory_util.hpp")
This commit is contained in:
Ion Gaztañaga
2013-12-23 10:47:20 +01:00
parent b1d4ef3a2e
commit f2947c115e
95 changed files with 2248 additions and 2692 deletions
+31 -31
View File
@@ -6,7 +6,7 @@
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -38,7 +38,7 @@
#include <boost/container/detail/preprocessor.hpp>
#endif
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
namespace container {
@@ -56,7 +56,7 @@ struct is_std_allocator< std::allocator<T> >
} //namespace container_detail {
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! The class template allocator_traits supplies a uniform interface to all allocator types.
//! This class is a C++03-compatible implementation of std::allocator_traits
@@ -94,29 +94,29 @@ struct allocator_traits
//!
typedef see_documentation size_type;
//! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
//! type with internal constant static member <code>value</code> == false.
typedef see_documentation propagate_on_container_copy_assignment;
//! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
//! type with internal constant static member <code>value</code> == false.
typedef see_documentation propagate_on_container_move_assignment;
//! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant
//! type with internal constant static member `value` == false.
//! type with internal constant static member <code>value</code> == false.
typedef see_documentation propagate_on_container_swap;
//! Defines an allocator: Alloc::rebind<T>::other if such a type exists; otherwise, Alloc<T, Args>
//! if Alloc is a class template instantiation of the form Alloc<U, Args>, where Args is zero or
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
//!
//! In C++03 compilers `rebind_alloc` is a struct derived from an allocator
//! In C++03 compilers <code>rebind_alloc</code> is a struct derived from an allocator
//! deduced by previously detailed rules.
template <class T> using rebind_alloc = see_documentation;
//! In C++03 compilers `rebind_traits` is a struct derived from
//! `allocator_traits<OtherAlloc>`, where `OtherAlloc` is
//! the allocator deduced by rules explained in `rebind_alloc`.
//! In C++03 compilers <code>rebind_traits</code> is a struct derived from
//! <code>allocator_traits<OtherAlloc></code>, where <code>OtherAlloc</code> is
//! the allocator deduced by rules explained in <code>rebind_alloc</code>.
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
//! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
//! <code>type</code> is an allocator related to Alloc deduced deduced by rules explained in <code>rebind_alloc</code>.
template <class T>
struct portable_rebind_alloc
{ typedef see_documentation type; };
@@ -206,19 +206,19 @@ struct allocator_traits
{ typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type; };
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>: `a.allocate(n)`
//! <b>Returns</b>: <code>a.allocate(n)</code>
//!
static pointer allocate(Alloc &a, size_type n)
{ return a.allocate(n); }
//! <b>Returns</b>: `a.deallocate(p, n)`
//! <b>Returns</b>: <code>a.deallocate(p, n)</code>
//!
//! <b>Throws</b>: Nothing
static void deallocate(Alloc &a, pointer p, size_type n)
{ a.deallocate(p, n); }
//! <b>Effects</b>: calls `a.allocate(n, p)` if that call is well-formed;
//! otherwise, invokes `a.allocate(n)`
//! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed;
//! otherwise, invokes <code>a.allocate(n)</code>
static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
{
const bool value = boost::container::container_detail::
@@ -228,10 +228,10 @@ struct allocator_traits
return allocator_traits::priv_allocate(flag, a, n, p);
}
//! <b>Effects</b>: calls `a.destroy(p)` if that call is well-formed;
//! otherwise, invokes `p->~T()`.
//! <b>Effects</b>: calls <code>a.destroy(p)</code> if that call is well-formed;
//! otherwise, invokes <code>p->~T()</code>.
template<class T>
static void destroy(Alloc &a, T*p)
static void destroy(Alloc &a, T*p) BOOST_CONTAINER_NOEXCEPT
{
typedef T* destroy_pointer;
const bool value = boost::container::container_detail::
@@ -241,9 +241,9 @@ struct allocator_traits
allocator_traits::priv_destroy(flag, a, p);
}
//! <b>Returns</b>: `a.max_size()` if that expression is well-formed; otherwise,
//! `numeric_limits<size_type>::max()`.
static size_type max_size(const Alloc &a)
//! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise,
//! <code>numeric_limits<size_type>::max()</code>.
static size_type max_size(const Alloc &a) BOOST_CONTAINER_NOEXCEPT
{
const bool value = boost::container::container_detail::
has_member_function_callable_with_max_size
@@ -252,7 +252,7 @@ struct allocator_traits
return allocator_traits::priv_max_size(flag, a);
}
//! <b>Returns</b>: `a.select_on_container_copy_construction()` if that expression is well-formed;
//! <b>Returns</b>: <code>a.select_on_container_copy_construction()</code> if that expression is well-formed;
//! otherwise, a.
static
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -276,8 +276,8 @@ struct allocator_traits
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: calls `a.construct(p, std::forward<Args>(args)...)` if that call is well-formed;
//! otherwise, invokes `::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)`
//! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
//! otherwise, invokes <code>::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
template <class T, class ...Args>
static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args)
{
@@ -285,7 +285,7 @@ struct allocator_traits
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
}
#endif
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
private:
static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p)
@@ -295,23 +295,23 @@ struct allocator_traits
{ return allocator_traits::allocate(a, n); }
template<class T>
static void priv_destroy(boost::true_type, Alloc &a, T* p)
static void priv_destroy(boost::true_type, Alloc &a, T* p) BOOST_CONTAINER_NOEXCEPT
{ a.destroy(p); }
template<class T>
static void priv_destroy(boost::false_type, Alloc &, T* p)
static void priv_destroy(boost::false_type, Alloc &, T* p) BOOST_CONTAINER_NOEXCEPT
{ p->~T(); (void)p; }
static size_type priv_max_size(boost::true_type, const Alloc &a)
static size_type priv_max_size(boost::true_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
{ return a.max_size(); }
static size_type priv_max_size(boost::false_type, const Alloc &)
static size_type priv_max_size(boost::false_type, const Alloc &) BOOST_CONTAINER_NOEXCEPT
{ return (std::numeric_limits<size_type>::max)(); }
static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
{ return a.select_on_container_copy_construction(); }
static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
{ return a; }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -394,7 +394,7 @@ struct allocator_traits
{ ::new((void*)p) T; }
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
} //namespace container {
+90 -24
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -15,11 +15,35 @@
# pragma once
#endif
//! \file
//! This header file forward declares the following classes:
//! - boost::container::vector
//! - boost::container::stable_vector
//! - boost::container::static_vector
//! - boost::container::slist
//! - boost::container::list
//! - boost::container::set
//! - boost::container::multiset
//! - boost::container::map
//! - boost::container::multimap
//! - boost::container::flat_set
//! - boost::container::flat_multiset
//! - boost::container::flat_map
//! - boost::container::flat_multimap
//! - boost::container::basic_string
//! - boost::container::string
//! - boost::container::wstring
//! - boost::container::allocator
//! - boost::container::node_allocator
//! - boost::container::adaptive_pool
//!
//! and defines the following types:
//////////////////////////////////////////////////////////////////////////////
// Standard predeclarations
//////////////////////////////////////////////////////////////////////////////
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost{
namespace intrusive{
@@ -32,13 +56,14 @@ namespace bi = boost::intrusive;
}}}
#include <cstddef>
#include <utility>
#include <memory>
#include <functional>
#include <iosfwd>
#include <string>
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//////////////////////////////////////////////////////////////////////////////
// Containers
@@ -47,89 +72,120 @@ namespace bi = boost::intrusive;
namespace boost {
namespace container {
//vector class
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T
,class Allocator = std::allocator<T> >
class vector;
//vector class
template <class T
,class Allocator = std::allocator<T> >
class stable_vector;
//vector class
template <class T, std::size_t Capacity>
class static_vector;
template <class T
,class Allocator = std::allocator<T> >
class deque;
//list class
template <class T
,class Allocator = std::allocator<T> >
class list;
//slist class
template <class T
,class Allocator = std::allocator<T> >
class slist;
//set class
template <class Key
,class Compare = std::less<Key>
,class Allocator = std::allocator<Key> >
class set;
//multiset class
template <class Key
,class Compare = std::less<Key>
,class Allocator = std::allocator<Key> >
class multiset;
//map class
template <class Key
,class T
,class Compare = std::less<Key>
,class Allocator = std::allocator<std::pair<const Key, T> > >
class map;
//multimap class
template <class Key
,class T
,class Compare = std::less<Key>
,class Allocator = std::allocator<std::pair<const Key, T> > >
class multimap;
//flat_set class
template <class Key
,class Compare = std::less<Key>
,class Allocator = std::allocator<Key> >
class flat_set;
//flat_multiset class
template <class Key
,class Compare = std::less<Key>
,class Allocator = std::allocator<Key> >
class flat_multiset;
//flat_map class
template <class Key
,class T
,class Compare = std::less<Key>
,class Allocator = std::allocator<std::pair<Key, T> > >
class flat_map;
//flat_multimap class
template <class Key
,class T
,class Compare = std::less<Key>
,class Allocator = std::allocator<std::pair<Key, T> > >
class flat_multimap;
//basic_string class
template <class CharT
,class Traits = std::char_traits<CharT>
,class Allocator = std::allocator<CharT> >
class basic_string;
typedef basic_string
<char
,std::char_traits<char>
,std::allocator<char> >
string;
typedef basic_string
<wchar_t
,std::char_traits<wchar_t>
,std::allocator<wchar_t> >
wstring;
static const std::size_t ADP_nodes_per_block = 256u;
static const std::size_t ADP_max_free_blocks = 2u;
static const std::size_t ADP_overhead_percent = 1u;
static const std::size_t ADP_only_alignment = 0u;
template < class T
, std::size_t NodesPerBlock = ADP_nodes_per_block
, std::size_t MaxFreeBlocks = ADP_max_free_blocks
, std::size_t OverheadPercent = ADP_overhead_percent
, unsigned Version = 2
>
class adaptive_pool;
template < class T
, unsigned Version = 2
, unsigned int AllocationDisableMask = 0>
class allocator;
static const std::size_t NodeAlloc_nodes_per_block = 256u;
template
< class T
, std::size_t NodesPerBlock = NodeAlloc_nodes_per_block
, std::size_t Version = 2>
class node_allocator;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! Type used to tag that the input range is
//! guaranteed to be ordered
struct ordered_range_t
@@ -149,17 +205,27 @@ struct ordered_unique_range_t
//! 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
//! Type used to tag that the inserted values
//! should be default initialized
struct default_init_t
{};
//! Value used to tag that the input range is
//! guaranteed to be ordered and unique
//! Value used to tag that the inserted values
//! should be default initialized
static const default_init_t default_init = default_init_t();
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace detail_really_deep_namespace {
//! Type used to tag that the inserted values
//! should be value initialized
struct value_init_t
{};
//! Value used to tag that the inserted values
//! should be value initialized
static const value_init_t value_init = value_init_t();
namespace container_detail_really_deep_namespace {
//Otherwise, gcc issues a warning of previously defined
//anonymous_instance and unique_instance
@@ -175,7 +241,7 @@ struct dummy
} //detail_really_deep_namespace {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}} //namespace boost { namespace container {
+52 -50
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -45,7 +45,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class Allocator = std::allocator<T> >
#else
@@ -465,7 +465,7 @@ class deque_base
const allocator_type &alloc() const BOOST_CONTAINER_NOEXCEPT
{ return members_; }
};
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! Deque class
//!
@@ -476,10 +476,10 @@ template <class T, class Allocator>
#endif
class deque : protected deque_base<Allocator>
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
typedef deque_base<Allocator> Base;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -503,7 +503,7 @@ class deque : protected deque_base<Allocator>
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private: // Internal typedefs
BOOST_COPYABLE_AND_MOVABLE(deque)
@@ -512,7 +512,7 @@ class deque : protected deque_base<Allocator>
{ return Base::s_buffer_size(); }
typedef allocator_traits<Allocator> allocator_traits_type;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -549,8 +549,8 @@ class deque : protected deque_base<Allocator>
explicit deque(size_type n)
: Base(n, allocator_type())
{
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
proxy.uninitialized_copy_n_and_update(this->begin(), n);
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
//deque_base will deallocate in case of exception...
}
@@ -566,8 +566,8 @@ class deque : protected deque_base<Allocator>
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);
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n);
//deque_base will deallocate in case of exception...
}
@@ -978,7 +978,7 @@ 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_value_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
container_detail::insert_value_initialized_n_proxy<Allocator, iterator> proxy;
priv_insert_back_aux_impl(n, proxy);
}
}
@@ -998,7 +998,7 @@ 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_initialized_n_proxy<Allocator, iterator> proxy(this->alloc());
container_detail::insert_default_initialized_n_proxy<Allocator, iterator> proxy;
priv_insert_back_aux_impl(n, proxy);
}
}
@@ -1155,7 +1155,7 @@ class deque : protected deque_base<Allocator>
}
else{
typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
this->priv_insert_front_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
}
}
@@ -1177,7 +1177,7 @@ class deque : protected deque_base<Allocator>
}
else{
typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
this->priv_insert_back_aux_impl(1, type(this->alloc(), boost::forward<Args>(args)...));
this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
}
}
@@ -1203,7 +1203,7 @@ class deque : protected deque_base<Allocator>
}
else{
typedef container_detail::insert_emplace_proxy<Allocator, iterator, Args...> type;
return this->priv_insert_aux_impl(p, 1, type(this->alloc(), boost::forward<Args>(args)...));
return this->priv_insert_aux_impl(p, 1, type(boost::forward<Args>(args)...));
}
}
@@ -1222,10 +1222,10 @@ class deque : protected deque_base<Allocator>
priv_push_front_simple_commit(); \
} \
else{ \
container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
priv_insert_front_aux_impl(1, proxy); \
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
priv_insert_front_aux_impl \
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
} \
\
@@ -1240,10 +1240,10 @@ class deque : protected deque_base<Allocator>
priv_push_back_simple_commit(); \
} \
else{ \
container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
priv_insert_back_aux_impl(1, proxy); \
typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
priv_insert_back_aux_impl \
(1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
} \
\
@@ -1260,10 +1260,10 @@ class deque : protected deque_base<Allocator>
return (this->end()-1); \
} \
else{ \
container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
return this->priv_insert_aux_impl(p, 1, proxy); \
typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
<Allocator, iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
return this->priv_insert_aux_impl \
(p, 1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
} \
} \
//!
@@ -1397,7 +1397,7 @@ class deque : protected deque_base<Allocator>
#endif
)
{
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(this->alloc(), first);
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first);
return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
}
#endif
@@ -1537,7 +1537,7 @@ class deque : protected deque_base<Allocator>
this->members_.m_finish = this->members_.m_start;
}
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
void priv_erase_last_n(size_type n)
@@ -1570,7 +1570,8 @@ class deque : protected deque_base<Allocator>
}
else {
return priv_insert_aux_impl
(position, (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
( position, (size_type)1
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
}
}
@@ -1584,7 +1585,8 @@ class deque : protected deque_base<Allocator>
}
else{
priv_insert_aux_impl
(this->cbegin(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
( this->cbegin(), (size_type)1
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
}
}
@@ -1598,8 +1600,8 @@ class deque : protected deque_base<Allocator>
}
else{
priv_insert_aux_impl
(this->cend(), (size_type)1, container_detail::get_insert_value_proxy<iterator>(this->alloc(), ::boost::forward<U>(x)));
container_detail::insert_copy_proxy<Allocator, iterator> proxy(this->alloc(), x);
( this->cend(), (size_type)1
, container_detail::get_insert_value_proxy<iterator, Allocator>(::boost::forward<U>(x)));
}
}
@@ -1652,7 +1654,7 @@ class deque : protected deque_base<Allocator>
}
template<class InsertProxy>
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy interf)
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
{
iterator pos(p.unconst());
const size_type pos_n = p - this->cbegin();
@@ -1667,7 +1669,7 @@ class deque : protected deque_base<Allocator>
const iterator new_start = this->priv_reserve_elements_at_front(n);
const iterator old_start = this->members_.m_start;
if(!elemsbefore){
interf.uninitialized_copy_n_and_update(new_start, n);
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
this->members_.m_start = new_start;
}
else{
@@ -1678,17 +1680,17 @@ class deque : protected deque_base<Allocator>
(this->alloc(), this->members_.m_start, start_n, new_start);
this->members_.m_start = new_start;
boost::move(start_n, pos, old_start);
interf.copy_n_and_update(pos - n, n);
proxy.copy_n_and_update(this->alloc(), pos - n, n);
}
else {
const size_type mid_count = n - elemsbefore;
const iterator mid_start = old_start - mid_count;
interf.uninitialized_copy_n_and_update(mid_start, mid_count);
proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
this->members_.m_start = mid_start;
::boost::container::uninitialized_move_alloc
(this->alloc(), old_start, pos, new_start);
this->members_.m_start = new_start;
interf.copy_n_and_update(old_start, elemsbefore);
proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
}
}
}
@@ -1697,7 +1699,7 @@ class deque : protected deque_base<Allocator>
const iterator old_finish = this->members_.m_finish;
const size_type elemsafter = length - elemsbefore;
if(!elemsafter){
interf.uninitialized_copy_n_and_update(old_finish, n);
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
this->members_.m_finish = new_finish;
}
else{
@@ -1708,15 +1710,15 @@ class deque : protected deque_base<Allocator>
(this->alloc(), finish_n, old_finish, old_finish);
this->members_.m_finish = new_finish;
boost::move_backward(pos, finish_n, old_finish);
interf.copy_n_and_update(pos, n);
proxy.copy_n_and_update(this->alloc(), pos, n);
}
else {
const size_type raw_gap = n - elemsafter;
::boost::container::uninitialized_move_alloc
(this->alloc(), pos, old_finish, old_finish + raw_gap);
BOOST_TRY{
interf.copy_n_and_update(pos, elemsafter);
interf.uninitialized_copy_n_and_update(old_finish, raw_gap);
proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
}
BOOST_CATCH(...){
this->priv_destroy_range(old_finish, old_finish + elemsafter);
@@ -1731,7 +1733,7 @@ class deque : protected deque_base<Allocator>
}
template <class InsertProxy>
iterator priv_insert_back_aux_impl(size_type n, InsertProxy interf)
iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
{
if(!this->members_.m_map){
this->priv_initialize_map(0);
@@ -1739,20 +1741,20 @@ class deque : protected deque_base<Allocator>
iterator new_finish = this->priv_reserve_elements_at_back(n);
iterator old_finish = this->members_.m_finish;
interf.uninitialized_copy_n_and_update(old_finish, n);
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
this->members_.m_finish = new_finish;
return iterator(this->members_.m_finish - n);
}
template <class InsertProxy>
iterator priv_insert_front_aux_impl(size_type n, InsertProxy interf)
iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy)
{
if(!this->members_.m_map){
this->priv_initialize_map(0);
}
iterator new_start = this->priv_reserve_elements_at_front(n);
interf.uninitialized_copy_n_and_update(new_start, n);
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
this->members_.m_start = new_start;
return new_start;
}
@@ -1934,7 +1936,7 @@ class deque : protected deque_base<Allocator>
this->members_.m_start.priv_set_node(new_nstart);
this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
}
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
// Nonmember functions.
@@ -1972,7 +1974,7 @@ inline void swap(deque<T, Allocator>& x, deque<T, Allocator>& y)
}}
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
@@ -1985,7 +1987,7 @@ struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
}
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#include <boost/container/detail/config_end.hpp>
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -15,9 +15,10 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -15,8 +15,373 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/move/utility.hpp>
#include <iterator> //std::iterator_traits
#include <boost/assert.hpp>
#include <boost/detail/no_exceptions_support.hpp>
namespace boost { namespace container { namespace container_detail {
template<class A, class FwdIt, class Iterator>
struct move_insert_range_proxy
{
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
explicit move_insert_range_proxy(FwdIt first)
: first_(first)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
{
this->first_ = ::boost::container::uninitialized_move_alloc_n_source
(a, this->first_, n, p);
}
void copy_n_and_update(A &, Iterator p, size_type n)
{
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
}
FwdIt first_;
};
template<class A, class FwdIt, class Iterator>
struct insert_range_proxy
{
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
explicit insert_range_proxy(FwdIt first)
: first_(first)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
{
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p);
}
void copy_n_and_update(A &, Iterator p, size_type n)
{
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
}
FwdIt first_;
};
template<class A, class Iterator>
struct insert_n_copies_proxy
{
typedef typename allocator_traits<A>::size_type size_type;
typedef typename allocator_traits<A>::value_type value_type;
explicit insert_n_copies_proxy(const value_type &v)
: v_(v)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
{ boost::container::uninitialized_fill_alloc_n(a, v_, n, p); }
void copy_n_and_update(A &, Iterator p, size_type n) const
{ std::fill_n(p, n, v_); }
const value_type &v_;
};
template<class A, class Iterator>
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;
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
{ boost::container::uninitialized_value_init_alloc_n(a, n, p); }
void copy_n_and_update(A &, Iterator, size_type) const
{ BOOST_ASSERT(false); }
};
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;
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
{ boost::container::uninitialized_default_init_alloc_n(a, n, p); }
void copy_n_and_update(A &, Iterator, size_type) const
{ BOOST_ASSERT(false); }
};
template<class A, class Iterator>
struct insert_copy_proxy
{
typedef boost::container::allocator_traits<A> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
explicit insert_copy_proxy(const value_type &v)
: v_(v)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a, container_detail::to_raw_pointer(&*p), v_);
}
void copy_n_and_update(A &, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p =v_;
}
const value_type &v_;
};
template<class A, class Iterator>
struct insert_move_proxy
{
typedef boost::container::allocator_traits<A> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
explicit insert_move_proxy(value_type &v)
: v_(v)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a
, container_detail::to_raw_pointer(&*p)
, ::boost::move(v_)
);
}
void copy_n_and_update(A &, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p = ::boost::move(v_);
}
value_type &v_;
};
template<class It, class A>
insert_move_proxy<A, It> get_insert_value_proxy(BOOST_RV_REF(typename std::iterator_traits<It>::value_type) v)
{
return insert_move_proxy<A, It>(v);
}
template<class It, class A>
insert_copy_proxy<A, It> get_insert_value_proxy(const typename std::iterator_traits<It>::value_type &v)
{
return insert_copy_proxy<A, It>(v);
}
}}} //namespace boost { namespace container { namespace container_detail {
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
#include <boost/move/utility.hpp>
#include <typeinfo>
//#include <iostream> //For debugging purposes
namespace boost {
namespace container {
namespace container_detail {
template<class A, class Iterator, class ...Args>
struct insert_non_movable_emplace_proxy
{
typedef boost::container::allocator_traits<A> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t;
explicit insert_non_movable_emplace_proxy(Args&&... args)
: args_(args...)
{}
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
{ this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); }
private:
template<int ...IdxPack>
void priv_uninitialized_copy_some_and_update(A &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a
, container_detail::to_raw_pointer(&*p)
, ::boost::forward<Args>(get<IdxPack>(this->args_))...
);
}
protected:
tuple<Args&...> args_;
};
template<class A, class Iterator, class ...Args>
struct insert_emplace_proxy
: public insert_non_movable_emplace_proxy<A, Iterator, Args...>
{
typedef insert_non_movable_emplace_proxy<A, Iterator, Args...> base_t;
typedef boost::container::allocator_traits<A> alloc_traits;
typedef typename base_t::value_type value_type;
typedef typename base_t::size_type size_type;
typedef typename base_t::index_tuple_t index_tuple_t;
explicit insert_emplace_proxy(Args&&... args)
: base_t(::boost::forward<Args>(args)...)
{}
void copy_n_and_update(A &a, Iterator p, size_type n)
{ this->priv_copy_some_and_update(a, index_tuple_t(), p, n); }
private:
template<int ...IdxPack>
void priv_copy_some_and_update(A &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
{
BOOST_ASSERT(n ==1); (void)n;
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
alloc_traits::construct(a, vp,
::boost::forward<Args>(get<IdxPack>(this->args_))...);
BOOST_TRY{
*p = ::boost::move(*vp);
}
BOOST_CATCH(...){
alloc_traits::destroy(a, vp);
BOOST_RETHROW
}
BOOST_CATCH_END
alloc_traits::destroy(a, vp);
}
};
}}} //namespace boost { namespace container { namespace container_detail {
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/preprocessor.hpp>
#include <boost/container/detail/value_init.hpp>
namespace boost {
namespace container {
namespace container_detail {
#define BOOST_PP_LOCAL_MACRO(N) \
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
{ \
typedef boost::container::allocator_traits<A> alloc_traits; \
typedef typename alloc_traits::size_type size_type; \
typedef typename alloc_traits::value_type value_type; \
\
explicit BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
BOOST_PP_EXPR_IF(N, :) BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \
{} \
\
void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) \
{ \
BOOST_ASSERT(n == 1); (void)n; \
alloc_traits::construct \
( a \
, container_detail::to_raw_pointer(&*p) \
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \
); \
} \
\
void copy_n_and_update(A &, Iterator, size_type) \
{ BOOST_ASSERT(false); } \
\
protected: \
BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
}; \
\
template<class A, class Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, class P) > \
struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
: BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
< A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \
{ \
typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \
<A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > base_t; \
typedef typename base_t::value_type value_type; \
typedef typename base_t::size_type size_type; \
typedef boost::container::allocator_traits<A> alloc_traits; \
\
explicit BOOST_PP_CAT(insert_emplace_proxy_arg, N) \
( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
: base_t(BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \
{} \
\
void copy_n_and_update(A &a, Iterator p, size_type n) \
{ \
BOOST_ASSERT(n == 1); (void)n; \
aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v)); \
alloc_traits::construct(a, vp \
BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \
BOOST_TRY{ \
*p = ::boost::move(*vp); \
} \
BOOST_CATCH(...){ \
alloc_traits::destroy(a, vp); \
BOOST_RETHROW \
} \
BOOST_CATCH_END \
alloc_traits::destroy(a, vp); \
} \
}; \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
}}} //namespace boost { namespace container { namespace container_detail {
#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
/*
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/destroyers.hpp>
#include <boost/aligned_storage.hpp>
@@ -391,3 +756,4 @@ struct BOOST_PP_CAT(insert_emplace_proxy_arg, N)
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
*/
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Ion Gaztanaga 2005-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,7 +17,7 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -15,13 +15,13 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
enum allocation_type_v
{
// constants for allocation commands
@@ -37,7 +37,7 @@ enum allocation_type_v
};
typedef int allocation_type;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
static const allocation_type allocate_new = (allocation_type)allocate_new_v;
static const allocation_type expand_fwd = (allocation_type)expand_fwd_v;
static const allocation_type expand_bwd = (allocation_type)expand_bwd_v;
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -17,6 +17,7 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/allocator_traits.hpp> //allocator_traits
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -18,6 +18,10 @@
#define BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#ifndef _SCL_SECURE_NO_WARNINGS
#define BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
#define _SCL_SECURE_NO_WARNINGS
#endif
#pragma warning (push)
#pragma warning (disable : 4702) // unreachable code
#pragma warning (disable : 4706) // assignment within conditional expression
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -13,5 +13,9 @@
#undef BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
#undef _CRT_SECURE_NO_DEPRECATE
#endif
#ifdef BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
#undef BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS
#undef _SCL_SECURE_NO_WARNINGS
#endif
#endif
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Ion Gaztanaga 2005-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,8 +17,9 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/allocator_traits.hpp>
@@ -231,6 +232,9 @@ struct null_scoped_destructor_n
void increment_size_backwards(size_type)
{}
void shrink_forward(size_type)
{}
void release()
{}
};
+2 -2
View File
@@ -1,6 +1,6 @@
////////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -15,7 +15,7 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2009-2012.
// (C) Copyright Ion Gaztanaga 2009-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
+2 -2
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Ion Gaztanaga 2005-2013.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.
@@ -18,7 +18,7 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/utility.hpp>
#include <boost/container/allocator_traits.hpp>
@@ -1,7 +1,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Stephen Cleary 2000.
// (C) Copyright Ion Gaztanaga 2007-2012.
// (C) Copyright Ion Gaztanaga 2007-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -16,7 +16,9 @@
#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <climits>
#include <boost/static_assert.hpp>
+6 -1
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Ion Gaztanaga 2005-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,6 +17,9 @@
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <cstddef>
namespace boost {
@@ -156,5 +159,7 @@ template <> struct unvoid<const void> { struct type { }; };
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -11,7 +11,9 @@
#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/type_traits.hpp>
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -15,7 +15,7 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <utility>
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -15,9 +15,10 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
+2 -2
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Ion Gaztanaga 2005-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,7 +17,7 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/mpl.hpp>
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -8,14 +8,16 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
#ifndef BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
#define BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
#if defined(_MSC_VER)
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/intrusive/slist.hpp>
#include <new>
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Ion Gaztanaga 2005-2013.
// (C) Copyright Gennaro Prota 2003 - 2004.
//
// Distributed under the Boost Software License, Version 1.0.
@@ -18,8 +18,9 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <iterator>
+2 -2
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_TREE_HPP
#define BOOST_CONTAINER_TREE_HPP
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
// (C) Copyright John Maddock 2000.
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Ion Gaztanaga 2005-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -19,7 +19,8 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/utility.hpp>
+36 -16
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -11,8 +11,9 @@
#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#include "config_begin.hpp"
#include "workaround.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <cstdio>
#include <cstring> //for ::memcpy
#include <boost/type_traits/is_fundamental.hpp>
@@ -110,18 +111,37 @@ template<class T>
const T &min_value(const T &a, const T &b)
{ return a < b ? a : b; }
template <class SizeType>
SizeType
get_next_capacity(const SizeType max_size
,const SizeType capacity
,const SizeType n)
enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent };
template<class SizeType, NextCapacityOption Option>
struct next_capacity_calculator;
template<class SizeType>
struct next_capacity_calculator<SizeType, NextCapacityDouble>
{
const SizeType remaining = max_size - capacity;
if ( remaining < n )
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
const SizeType additional = max_value(n, capacity);
return ( remaining < additional ) ? max_size : ( capacity + additional );
#if 0 //Alternative for 50% grow
static SizeType get(const SizeType max_size
,const SizeType capacity
,const SizeType n)
{
const SizeType remaining = max_size - capacity;
if ( remaining < n )
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
const SizeType additional = max_value(n, capacity);
return ( remaining < additional ) ? max_size : ( capacity + additional );
}
};
template<class SizeType>
struct next_capacity_calculator<SizeType, NextCapacity60Percent>
{
static SizeType get(const SizeType max_size
,const SizeType capacity
,const SizeType n)
{
const SizeType remaining = max_size - capacity;
if ( remaining < n )
boost::container::throw_length_error("get_next_capacity, allocator's max_size reached");
const SizeType m3 = max_size/3;
if (capacity < m3)
@@ -130,8 +150,8 @@ SizeType
if (capacity < m3*2)
return capacity + max_value((capacity+1)/2, n);
return max_size;
#endif
}
}
};
template <class T>
inline T* to_raw_pointer(T* p)
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012.
// (C) Copyright Ion Gaztanaga 2005-2013.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,7 +17,7 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
namespace boost {
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -15,8 +15,9 @@
# pragma once
#endif
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <cstddef> //std::size_t
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -16,7 +16,8 @@
#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
#include "config_begin.hpp"
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
@@ -87,6 +88,6 @@ struct version
} //namespace container {
} //namespace boost{
#include "config_end.hpp"
#include <boost/container/detail/config_end.hpp>
#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
+15 -15
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -34,7 +34,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
// Forward declarations of operators == and <, needed for friend declarations.
template <class Key, class T, class Compare, class Allocator>
class flat_map;
@@ -63,7 +63,7 @@ static D force_copy(S s)
} //namespace container_detail{
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! A flat_map is a kind of associative container that supports unique keys (contains at
//! most one of each key value) and provides for fast retrieval of values of another
@@ -95,7 +95,7 @@ template <class Key, class T, class Compare, class Allocator>
#endif
class flat_map
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(flat_map)
//This is the tree that we should store if pair was movable
@@ -129,7 +129,7 @@ class flat_map
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -842,7 +842,7 @@ class flat_map
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class K1, class T1, class C1, class A1>
friend bool operator== (const flat_map<K1, T1, C1, A1>&,
const flat_map<K1, T1, C1, A1>&);
@@ -872,7 +872,7 @@ class flat_map
}
return (*i).second;
}
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class Key, class T, class Compare, class Allocator>
@@ -910,7 +910,7 @@ inline void swap(flat_map<Key,T,Compare,Allocator>& x,
flat_map<Key,T,Compare,Allocator>& y)
{ x.swap(y); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
} //namespace container {
@@ -935,7 +935,7 @@ inline bool operator==(const flat_multimap<Key,T,Compare,Allocator>& x,
template <class Key, class T, class Compare, class Allocator>
inline bool operator<(const flat_multimap<Key,T,Compare,Allocator>& x,
const flat_multimap<Key,T,Compare,Allocator>& y);
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! A flat_multimap is a kind of associative container that supports equivalent keys
//! (possibly containing multiple copies of the same key value) and provides for
@@ -967,7 +967,7 @@ template <class Key, class T, class Compare, class Allocator>
#endif
class flat_multimap
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
typedef container_detail::flat_tree<Key,
@@ -999,7 +999,7 @@ class flat_multimap
<typename allocator_traits<Allocator>::pointer>::reverse_iterator reverse_iterator_impl;
typedef typename container_detail::get_flat_tree_iterators
<typename allocator_traits<Allocator>::pointer>::const_reverse_iterator const_reverse_iterator_impl;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -1637,7 +1637,7 @@ class flat_multimap
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
{ return container_detail::force_copy<std::pair<const_iterator,const_iterator> >(m_flat_tree.equal_range(x)); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class K1, class T1, class C1, class A1>
friend bool operator== (const flat_multimap<K1, T1, C1, A1>& x,
const flat_multimap<K1, T1, C1, A1>& y);
@@ -1645,7 +1645,7 @@ class flat_multimap
template <class K1, class T1, class C1, class A1>
friend bool operator< (const flat_multimap<K1, T1, C1, A1>& x,
const flat_multimap<K1, T1, C1, A1>& y);
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class Key, class T, class Compare, class Allocator>
@@ -1684,7 +1684,7 @@ inline void swap(flat_multimap<Key,T,Compare,Allocator>& x, flat_multimap<Key,T,
}}
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
@@ -1698,7 +1698,7 @@ struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T,
} //namespace boost {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#include <boost/container/detail/config_end.hpp>
+15 -15
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -31,7 +31,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
// Forward declarations of operators < and ==, needed for friend declaration.
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -48,7 +48,7 @@ inline bool operator==(const flat_set<Key,Compare,Allocator>& x,
template <class Key, class Compare, class Allocator>
inline bool operator<(const flat_set<Key,Compare,Allocator>& x,
const flat_set<Key,Compare,Allocator>& y);
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! flat_set is a Sorted Associative Container that stores objects of type Key.
//! It is also a Unique Associative Container, meaning that no two elements are the same.
@@ -68,12 +68,12 @@ template <class Key, class Compare, class Allocator>
#endif
class flat_set
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(flat_set)
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> tree_t;
tree_t m_flat_tree; // flat tree representing flat_set
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -678,7 +678,7 @@ class flat_set
std::pair<iterator,iterator> equal_range(const key_type& x)
{ return m_flat_tree.equal_range(x); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class K1, class C1, class A1>
friend bool operator== (const flat_set<K1,C1,A1>&, const flat_set<K1,C1,A1>&);
@@ -693,7 +693,7 @@ class flat_set
template<class KeyType>
iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
{ return m_flat_tree.insert_unique(p, ::boost::forward<KeyType>(x)); }
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class Key, class Compare, class Allocator>
@@ -730,7 +730,7 @@ template <class Key, class Compare, class Allocator>
inline void swap(flat_set<Key,Compare,Allocator>& x, flat_set<Key,Compare,Allocator>& y)
{ x.swap(y); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
} //namespace container {
@@ -760,7 +760,7 @@ inline bool operator==(const flat_multiset<Key,Compare,Allocator>& x,
template <class Key, class Compare, class Allocator>
inline bool operator<(const flat_multiset<Key,Compare,Allocator>& x,
const flat_multiset<Key,Compare,Allocator>& y);
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! flat_multiset is a Sorted Associative Container that stores objects of type Key.
//!
@@ -781,12 +781,12 @@ template <class Key, class Compare, class Allocator>
#endif
class flat_multiset
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
typedef container_detail::flat_tree<Key, Key, container_detail::identity<Key>, Compare, Allocator> tree_t;
tree_t m_flat_tree; // flat tree representing flat_multiset
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -1353,7 +1353,7 @@ class flat_multiset
std::pair<iterator,iterator> equal_range(const key_type& x)
{ return m_flat_tree.equal_range(x); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class K1, class C1, class A1>
friend bool operator== (const flat_multiset<K1,C1,A1>&,
const flat_multiset<K1,C1,A1>&);
@@ -1368,7 +1368,7 @@ class flat_multiset
template <class KeyType>
iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
{ return m_flat_tree.insert_equal(p, ::boost::forward<KeyType>(x)); }
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class Key, class Compare, class Allocator>
@@ -1405,7 +1405,7 @@ template <class Key, class Compare, class Allocator>
inline void swap(flat_multiset<Key,Compare,Allocator>& x, flat_multiset<Key,Compare,Allocator>& y)
{ x.swap(y); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
} //namespace container {
@@ -1419,7 +1419,7 @@ struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, C,
namespace container {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}}
+9 -9
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -47,7 +47,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace container_detail {
template<class VoidPointer>
@@ -99,7 +99,7 @@ struct intrusive_list_type
};
} //namespace container_detail {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! A list is a doubly linked list. That is, it is a Sequence that supports both
//! forward and backward traversal, and (amortized) constant time insertion and
@@ -120,7 +120,7 @@ class list
: protected container_detail::node_alloc_holder
<Allocator, typename container_detail::intrusive_list_type<Allocator>::type>
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef typename
container_detail::intrusive_list_type<Allocator>::type Icont;
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
@@ -167,7 +167,7 @@ class list
typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
typedef container_detail::iterator<typename Icont::iterator, true> const_iterator_impl;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -1216,7 +1216,7 @@ class list
void reverse() BOOST_CONTAINER_NOEXCEPT
{ this->icont().reverse(); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
bool priv_try_shrink(size_type new_size)
@@ -1303,7 +1303,7 @@ class list
bool operator()(const value_type &a, const value_type &b) const
{ return a == b; }
};
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
@@ -1362,7 +1362,7 @@ inline void swap(list<T, Allocator>& x, list<T, Allocator>& y)
x.swap(y);
}
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
} //namespace container {
@@ -1375,7 +1375,7 @@ struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
namespace container {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}}
+15 -15
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -39,7 +39,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
// Forward declarations of operators == and <, needed for friend declarations.
template <class Key, class T, class Compare, class Allocator>
inline bool operator==(const map<Key,T,Compare,Allocator>& x,
@@ -48,7 +48,7 @@ inline bool operator==(const map<Key,T,Compare,Allocator>& x,
template <class Key, class T, class Compare, class Allocator>
inline bool operator<(const map<Key,T,Compare,Allocator>& x,
const map<Key,T,Compare,Allocator>& y);
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! A map is a kind of associative container that supports unique keys (contains at
//! most one of each key value) and provides for fast retrieval of values of another
@@ -69,7 +69,7 @@ template <class Key, class T, class Compare, class Allocator>
#endif
class map
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(map)
@@ -81,7 +81,7 @@ class map
< Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
> value_compare_impl;
tree_t m_tree; // red-black tree representing map
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -755,7 +755,7 @@ class map
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
{ return m_tree.equal_range(x); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class K1, class T1, class C1, class A1>
friend bool operator== (const map<K1, T1, C1, A1>&,
const map<K1, T1, C1, A1>&);
@@ -790,7 +790,7 @@ class map
return (*i).second;
}
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class Key, class T, class Compare, class Allocator>
@@ -827,7 +827,7 @@ template <class Key, class T, class Compare, class Allocator>
inline void swap(map<Key,T,Compare,Allocator>& x, map<Key,T,Compare,Allocator>& y)
{ x.swap(y); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
// Forward declaration of operators < and ==, needed for friend declaration.
@@ -851,7 +851,7 @@ struct has_trivial_destructor_after_move<boost::container::map<K, T, C, Allocato
namespace container {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! A multimap is a kind of associative container that supports equivalent keys
//! (possibly containing multiple copies of the same key value) and provides for
@@ -873,7 +873,7 @@ template <class Key, class T, class Compare, class Allocator>
#endif
class multimap
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(multimap)
@@ -885,7 +885,7 @@ class multimap
< Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
> value_compare_impl;
tree_t m_tree; // red-black tree representing map
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -1463,7 +1463,7 @@ class multimap
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
{ return m_tree.equal_range(x); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class K1, class T1, class C1, class A1>
friend bool operator== (const multimap<K1, T1, C1, A1>& x,
const multimap<K1, T1, C1, A1>& y);
@@ -1471,7 +1471,7 @@ class multimap
template <class K1, class T1, class C1, class A1>
friend bool operator< (const multimap<K1, T1, C1, A1>& x,
const multimap<K1, T1, C1, A1>& y);
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class Key, class T, class Compare, class Allocator>
@@ -1508,7 +1508,7 @@ template <class Key, class T, class Compare, class Allocator>
inline void swap(multimap<Key,T,Compare,Allocator>& x, multimap<Key,T,Compare,Allocator>& y)
{ x.swap(y); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
} //namespace container {
@@ -1522,7 +1522,7 @@ struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, All
namespace container {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}}
+66 -66
View File
@@ -6,7 +6,7 @@
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -46,7 +46,7 @@ namespace boost { namespace container {
//! and if T is used in a context where a container must call such a constructor, then the program is
//! ill-formed.
//!
//! [Example:
//! <code>
//! template <class T, class Allocator = allocator<T> >
//! class Z {
//! public:
@@ -64,7 +64,7 @@ namespace boost { namespace container {
//! template <class T, class Allocator = allocator<T> >
//! struct constructible_with_allocator_suffix<Z<T,Allocator> >
//! : ::boost::true_type { };
//! -- end example]
//! </code>
//!
//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
@@ -90,7 +90,7 @@ struct constructible_with_allocator_suffix
//! called with these initial arguments, and if T is used in a context where a container must call such
//! a constructor, then the program is ill-formed.
//!
//! [Example:
//! <code>
//! template <class T, class Allocator = allocator<T> >
//! class Y {
//! public:
@@ -115,7 +115,7 @@ struct constructible_with_allocator_suffix
//! struct constructible_with_allocator_prefix<Y<T,Allocator> >
//! : ::boost::true_type { };
//!
//! -- end example]
//! </code>
//!
//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
@@ -130,7 +130,7 @@ struct constructible_with_allocator_prefix
: ::boost::false_type
{};
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace container_detail {
@@ -159,7 +159,7 @@ struct uses_allocator_imp
} //namespace container_detail {
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Remark</b>: Automatically detects if T has a nested allocator_type that is convertible from
//! Alloc. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may
@@ -173,7 +173,7 @@ struct uses_allocator
: boost::integral_constant<bool, container_detail::uses_allocator_imp<T, Alloc>::value>
{};
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace container_detail {
@@ -675,16 +675,16 @@ class scoped_allocator_adaptor_base
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
{ l.swap(r); }
inner_allocator_type& inner_allocator()
inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT
{ return m_inner; }
inner_allocator_type const& inner_allocator() const
inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return m_inner; }
outer_allocator_type & outer_allocator()
outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT
{ return static_cast<outer_allocator_type&>(*this); }
const outer_allocator_type &outer_allocator() const
const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT
{ return static_cast<const outer_allocator_type&>(*this); }
scoped_allocator_type select_on_container_copy_construction() const
@@ -1008,7 +1008,7 @@ class scoped_allocator_adaptor_base
} //namespace container_detail {
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//Scoped allocator
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1038,14 +1038,14 @@ class scoped_allocator_adaptor_base
//! scoped_allocator_adaptor is derived from the outer allocator type so it can be
//! substituted for the outer allocator type in most expressions. -end note]
//!
//! In the construct member functions, `OUTERMOST(x)` is x if x does not have
//! an `outer_allocator()` member function and
//! `OUTERMOST(x.outer_allocator())` otherwise; `OUTERMOST_ALLOC_TRAITS(x)` is
//! `allocator_traits<decltype(OUTERMOST(x))>`.
//! In the construct member functions, <code>OUTERMOST(x)</code> is x if x does not have
//! an <code>outer_allocator()</code> member function and
//! <code>OUTERMOST(x.outer_allocator())</code> otherwise; <code>OUTERMOST_ALLOC_TRAITS(x)</code> is
//! <code>allocator_traits<decltype(OUTERMOST(x))></code>.
//!
//! [<b>Note</b>: `OUTERMOST(x)` and
//! `OUTERMOST_ALLOC_TRAITS(x)` are recursive operations. It is incumbent upon
//! the definition of `outer_allocator()` to ensure that the recursion terminates.
//! [<b>Note</b>: <code>OUTERMOST(x)</code> and
//! <code>OUTERMOST_ALLOC_TRAITS(x)</code> are recursive operations. It is incumbent upon
//! the definition of <code>outer_allocator()</code> to ensure that the recursion terminates.
//! It will terminate for all instantiations of scoped_allocator_adaptor. -end note]
template <typename OuterAlloc, typename ...InnerAllocs>
class scoped_allocator_adaptor
@@ -1076,7 +1076,7 @@ class scoped_allocator_adaptor
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
public:
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef container_detail::scoped_allocator_adaptor_base
<OuterAlloc
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1086,13 +1086,13 @@ class scoped_allocator_adaptor
#endif
> base_type;
typedef typename base_type::internal_type_t internal_type_t;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef OuterAlloc outer_allocator_type;
//! Type: For exposition only
//!
typedef allocator_traits<OuterAlloc> outer_traits_type;
//! Type: `scoped_allocator_adaptor<OuterAlloc>` if `sizeof...(InnerAllocs)` is zero; otherwise,
//! `scoped_allocator_adaptor<InnerAllocs...>`.
//! Type: <code>scoped_allocator_adaptor<OuterAlloc></code> if <code>sizeof...(InnerAllocs)</code> is zero; otherwise,
//! <code>scoped_allocator_adaptor<InnerAllocs...></code>.
typedef typename base_type::inner_allocator_type inner_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef typename outer_traits_type::value_type value_type;
@@ -1102,23 +1102,23 @@ class scoped_allocator_adaptor
typedef typename outer_traits_type::const_pointer const_pointer;
typedef typename outer_traits_type::void_pointer void_pointer;
typedef typename outer_traits_type::const_void_pointer const_void_pointer;
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_copy_assignment::value` is
//! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_copy_assignment::value</code> is
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
typedef typename base_type::
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_move_assignment::value` is
//! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_move_assignment::value</code> is
//! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
typedef typename base_type::
propagate_on_container_move_assignment propagate_on_container_move_assignment;
//! Type: `true_type` if `allocator_traits<Allocator>::propagate_on_container_swap::value` is true for any
//! `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type.
//! Type: <code>true_type</code> if <code>allocator_traits<Allocator>::propagate_on_container_swap::value</code> is true for any
//! <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>; otherwise, false_type.
typedef typename base_type::
propagate_on_container_swap propagate_on_container_swap;
//! Type: Rebinds scoped allocator to
//! `typedef scoped_allocator_adaptor
//! <code>typedef scoped_allocator_adaptor
//! < typename outer_traits_type::template portable_rebind_alloc<U>::type
//! , InnerAllocs... >`
//! , InnerAllocs... ></code>
template <class U>
struct rebind
{
@@ -1224,55 +1224,55 @@ class scoped_allocator_adaptor
friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
//! <b>Returns</b>:
//! `static_cast<OuterAlloc&>(*this)`.
outer_allocator_type & outer_allocator();
//! <code>static_cast<OuterAlloc&>(*this)</code>.
outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT;
//! <b>Returns</b>:
//! `static_cast<const OuterAlloc&>(*this)`.
const outer_allocator_type &outer_allocator() const;
//! <code>static_cast<const OuterAlloc&>(*this)</code>.
const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT;
//! <b>Returns</b>:
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
inner_allocator_type& inner_allocator();
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT;
//! <b>Returns</b>:
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
inner_allocator_type const& inner_allocator() const;
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT;
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>:
//! `allocator_traits<OuterAlloc>::max_size(outer_allocator())`.
size_type max_size() const
//! <code>allocator_traits<OuterAlloc>::max_size(outer_allocator())</code>.
size_type max_size() const BOOST_CONTAINER_NOEXCEPT
{
return outer_traits_type::max_size(this->outer_allocator());
}
//! <b>Effects</b>:
//! calls `OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)`.
//! calls <code>OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)</code>.
template <class T>
void destroy(T* p)
void destroy(T* p) BOOST_CONTAINER_NOEXCEPT
{
allocator_traits<typename outermost_allocator<OuterAlloc>::type>
::destroy(get_outermost_allocator(this->outer_allocator()), p);
}
//! <b>Returns</b>:
//! `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)`.
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
pointer allocate(size_type n)
{
return outer_traits_type::allocate(this->outer_allocator(), n);
}
//! <b>Returns</b>:
//! `allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)`.
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n, hint)</code>.
pointer allocate(size_type n, const_void_pointer hint)
{
return outer_traits_type::allocate(this->outer_allocator(), n, hint);
}
//! <b>Effects</b>:
//! `allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)`.
//! <code>allocator_traits<OuterAlloc>::deallocate(outer_allocator(), p, n)</code>.
void deallocate(pointer p, size_type n)
{
outer_traits_type::deallocate(this->outer_allocator(), p, n);
@@ -1281,45 +1281,45 @@ class scoped_allocator_adaptor
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>: Allocator new scoped_allocator_adaptor object where each allocator
//! A in the adaptor is initialized from the result of calling
//! `allocator_traits<Allocator>::select_on_container_copy_construction()` on
//! <code>allocator_traits<Allocator>::select_on_container_copy_construction()</code> on
//! the corresponding allocator in *this.
scoped_allocator_adaptor select_on_container_copy_construction() const;
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
base_type &base() { return *this; }
const base_type &base() const { return *this; }
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>:
//! 1) If `uses_allocator<T, inner_allocator_type>::value` is false calls
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct
//! (OUTERMOST(*this), p, std::forward<Args>(args)...)`.
//! 1) If <code>uses_allocator<T, inner_allocator_type>::value</code> is false calls
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct
//! (OUTERMOST(*this), p, std::forward<Args>(args)...)</code>.
//!
//! 2) Otherwise, if `uses_allocator<T, inner_allocator_type>::value` is true and
//! `is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value` is true, calls
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
//! inner_allocator(), std::forward<Args>(args)...)`.
//! 2) Otherwise, if <code>uses_allocator<T, inner_allocator_type>::value</code> is true and
//! <code>is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value</code> is true, calls
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg,
//! inner_allocator(), std::forward<Args>(args)...)</code>.
//!
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, `is_constructible` can't
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't
//! be implemented so that condition will be replaced by
//! constructible_with_allocator_prefix<T>::value. -end note]
//!
//! 3) Otherwise, if uses_allocator<T, inner_allocator_type>::value is true and
//! `is_constructible<T, Args..., inner_allocator_type>::value` is true, calls
//! `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p,
//! std::forward<Args>(args)..., inner_allocator())`.
//! <code>is_constructible<T, Args..., inner_allocator_type>::value</code> is true, calls
//! <code>OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p,
//! std::forward<Args>(args)..., inner_allocator())</code>.
//!
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, `is_constructible` can't be
//! [<b>Note</b>: In compilers without advanced decltype SFINAE support, <code>is_constructible</code> can't be
//! implemented so that condition will be replaced by
//! `constructible_with_allocator_suffix<T>::value`. -end note]
//! <code>constructible_with_allocator_suffix<T>::value</code>. -end note]
//!
//! 4) Otherwise, the program is ill-formed.
//!
//! [<b>Note</b>: An error will result if `uses_allocator` evaluates
//! [<b>Note</b>: An error will result if <code>uses_allocator</code> evaluates
//! to true but the specific constructor does not take an allocator. This definition prevents a silent
//! failure to pass an inner allocator to a contained element. -end note]
template < typename T, class ...Args>
@@ -1395,7 +1395,7 @@ class scoped_allocator_adaptor
, BOOST_RV_REF_BEG container_detail::pair<U, V> BOOST_RV_REF_END x)
{ this->construct_pair(p, x); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
template <class Pair>
void construct_pair(Pair* p)
@@ -1463,7 +1463,7 @@ class scoped_allocator_adaptor
: base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
{}
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <typename OuterA1, typename OuterA2
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -11,6 +11,10 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
//! \file
//! This header file forward declares boost::container::scoped_allocator_adaptor
//! and defines the following types:
#if defined(_MSC_VER)
# pragma once
#endif
@@ -25,7 +29,7 @@
namespace boost { namespace container {
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -55,7 +59,7 @@ class scoped_allocator_adaptor;
#endif
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! The allocator_arg_t struct is an empty structure type used as a unique type to
//! disambiguate constructor and function overloading. Specifically, several types
+15 -15
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -35,7 +35,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
// Forward declarations of operators < and ==, needed for friend declaration.
template <class Key, class Compare, class Allocator>
inline bool operator==(const set<Key,Compare,Allocator>& x,
@@ -44,7 +44,7 @@ inline bool operator==(const set<Key,Compare,Allocator>& x,
template <class Key, class Compare, class Allocator>
inline bool operator<(const set<Key,Compare,Allocator>& x,
const set<Key,Compare,Allocator>& y);
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! A set is a kind of associative container that supports unique keys (contains at
//! most one of each key value) and provides for fast retrieval of the keys themselves.
@@ -60,13 +60,13 @@ template <class Key, class Compare, class Allocator>
#endif
class set
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(set)
typedef container_detail::rbtree<Key, Key,
container_detail::identity<Key>, Compare, Allocator> tree_t;
tree_t m_tree; // red-black tree representing set
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -600,7 +600,7 @@ class set
std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
{ return m_tree.equal_range(x); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class K1, class C1, class A1>
friend bool operator== (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
@@ -615,7 +615,7 @@ class set
template <class KeyType>
iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
{ return m_tree.insert_unique(p, ::boost::forward<KeyType>(x)); }
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class Key, class Compare, class Allocator>
@@ -652,7 +652,7 @@ template <class Key, class Compare, class Allocator>
inline void swap(set<Key,Compare,Allocator>& x, set<Key,Compare,Allocator>& y)
{ x.swap(y); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
} //namespace container {
@@ -675,7 +675,7 @@ inline bool operator==(const multiset<Key,Compare,Allocator>& x,
template <class Key, class Compare, class Allocator>
inline bool operator<(const multiset<Key,Compare,Allocator>& x,
const multiset<Key,Compare,Allocator>& y);
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! A multiset is a kind of associative container that supports equivalent keys
//! (possibly contains multiple copies of the same key value) and provides for
@@ -691,13 +691,13 @@ template <class Key, class Compare, class Allocator>
#endif
class multiset
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(multiset)
typedef container_detail::rbtree<Key, Key,
container_detail::identity<Key>, Compare, Allocator> tree_t;
tree_t m_tree; // red-black tree representing multiset
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -1221,7 +1221,7 @@ class multiset
std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
{ return m_tree.equal_range(x); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class K1, class C1, class A1>
friend bool operator== (const multiset<K1,C1,A1>&,
const multiset<K1,C1,A1>&);
@@ -1237,7 +1237,7 @@ class multiset
iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
{ return m_tree.insert_equal(p, ::boost::forward<KeyType>(x)); }
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class Key, class Compare, class Allocator>
@@ -1274,7 +1274,7 @@ template <class Key, class Compare, class Allocator>
inline void swap(multiset<Key,Compare,Allocator>& x, multiset<Key,Compare,Allocator>& y)
{ x.swap(y); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
} //namespace container {
@@ -1288,7 +1288,7 @@ struct has_trivial_destructor_after_move<boost::container::multiset<Key, C, Allo
namespace container {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}}
+11 -11
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -48,7 +48,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class T, class Allocator>
class slist;
@@ -106,7 +106,7 @@ struct intrusive_slist_type
} //namespace container_detail {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! An slist is a singly linked list: a list where each element is linked to the next
//! element, but not to the previous element. That is, it is a Sequence that
@@ -149,7 +149,7 @@ class slist
: protected container_detail::node_alloc_holder
<Allocator, typename container_detail::intrusive_slist_type<Allocator>::type>
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef typename
container_detail::intrusive_slist_type<Allocator>::type Icont;
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
@@ -195,7 +195,7 @@ class slist
BOOST_COPYABLE_AND_MOVABLE(slist)
typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
typedef container_detail::iterator<typename Icont::iterator, true > const_iterator_impl;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -1423,7 +1423,7 @@ class slist
void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
{ this->splice(p, static_cast<slist&>(x), first, last); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
void priv_push_front (const T &x)
@@ -1505,7 +1505,7 @@ class slist
const value_type &m_ref;
};
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class T, class Allocator>
@@ -1561,7 +1561,7 @@ inline void swap(slist<T,Allocator>& x, slist<T,Allocator>& y)
}}
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
@@ -1574,14 +1574,14 @@ struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
namespace container {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}} //namespace boost{ namespace container {
// Specialization of insert_iterator so that insertions will be constant
// time rather than linear time.
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//Ummm, I don't like to define things in namespace std, but
//there is no other way
@@ -1620,7 +1620,7 @@ class insert_iterator<boost::container::slist<T, Allocator> >
} //namespace std;
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#include <boost/container/detail/config_end.hpp>
+13 -13
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -47,18 +47,18 @@
#include <memory>
#include <new> //placement new
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#include <boost/container/vector.hpp>
//#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
namespace container {
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace stable_vector_detail{
@@ -393,7 +393,7 @@ struct index_traits
#endif //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector
//! drop-in replacement implemented as a node container, offering iterator and reference
@@ -433,7 +433,7 @@ template <class T, class Allocator>
#endif
class stable_vector
{
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef allocator_traits<Allocator> allocator_traits_type;
typedef boost::intrusive::
pointer_traits
@@ -504,7 +504,7 @@ class stable_vector
typedef stable_vector_detail::iterator
< typename allocator_traits<Allocator>::pointer
, false> const_iterator_impl;
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -526,7 +526,7 @@ class stable_vector
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
///@cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(stable_vector)
static const size_type ExtraPointers = index_traits_type::ExtraPointers;
@@ -536,7 +536,7 @@ class stable_vector
class push_back_rollback;
friend class push_back_rollback;
///@endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -1510,7 +1510,7 @@ class stable_vector
void clear() BOOST_CONTAINER_NOEXCEPT
{ this->erase(this->cbegin(),this->cend()); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
@@ -1836,7 +1836,7 @@ class stable_vector
const node_allocator_type &priv_node_alloc() const { return internal_data; }
index_type index;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <typename T,typename Allocator>
@@ -1883,11 +1883,11 @@ void swap(stable_vector<T,Allocator>& x,stable_vector<T,Allocator>& y)
x.swap(y);
}
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#undef STABLE_VECTOR_CHECK_INVARIANT
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
/*
+32 -30
View File
@@ -21,6 +21,8 @@
namespace boost { namespace container {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace container_detail {
template<class T, std::size_t N>
@@ -61,46 +63,46 @@ class static_storage_allocator
} //namespace container_detail {
/**
* @defgroup static_vector_non_member static_vector non-member functions
*/
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
/**
* @brief A variable-size array container with fixed capacity.
*
* static_vector is a sequence container like boost::container::vector with contiguous storage that can
* change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
*
* A static_vector is a sequence that supports random access to elements, constant time insertion and
* removal of elements at the end, and linear time insertion and removal of elements at the beginning or
* in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity
* because elements are stored within the object itself similarly to an array. However, objects are
* initialized as they are inserted into static_vector unlike C arrays or std::array which must construct
* all elements on instantiation. The behavior of static_vector enables the use of statically allocated
* elements in cases with complex object lifetime requirements that would otherwise not be trivially
* possible.
*
* @par Error Handling
* Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or
* calling throw_bad_alloc() if not enabled.
*
* std::out_of_range is thrown if out of bound access is performed in `at()` if exceptions are
* enabled, throw_out_of_range() if not enabled.
*
* @tparam Value The type of element that will be stored.
* @tparam Capacity The maximum number of elements static_vector can store, fixed at compile time.
*/
//!
//!@brief A variable-size array container with fixed capacity.
//!
//!static_vector is a sequence container like boost::container::vector with contiguous storage that can
//!change in size, along with the static allocation, low overhead, and fixed capacity of boost::array.
//!
//!A static_vector is a sequence that supports random access to elements, constant time insertion and
//!removal of elements at the end, and linear time insertion and removal of elements at the beginning or
//!in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity
//!because elements are stored within the object itself similarly to an array. However, objects are
//!initialized as they are inserted into static_vector unlike C arrays or std::array which must construct
//!all elements on instantiation. The behavior of static_vector enables the use of statically allocated
//!elements in cases with complex object lifetime requirements that would otherwise not be trivially
//!possible.
//!
//!@par Error Handling
//! Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or
//! calling throw_bad_alloc() if not enabled.
//!
//! std::out_of_range is thrown if out of bound access is performed in <code>at()</code> if exceptions are
//! enabled, throw_out_of_range() if not enabled.
//!
//!@tparam Value The type of element that will be stored.
//!@tparam Capacity The maximum number of elements static_vector can store, fixed at compile time.
template <typename Value, std::size_t Capacity>
class static_vector
: public vector<Value, container_detail::static_storage_allocator<Value, Capacity> >
{
typedef vector<Value, container_detail::static_storage_allocator<Value, Capacity> > base_t;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef vector<Value, container_detail::static_storage_allocator<Value, Capacity> > base_t;
BOOST_COPYABLE_AND_MOVABLE(static_vector)
BOOST_COPYABLE_AND_MOVABLE(static_vector)
template<class U, std::size_t OtherCapacity>
friend class static_vector;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//! @brief The type of elements stored in the container.
typedef typename base_t::value_type value_type;
+82 -39
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -52,7 +52,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace container_detail {
// ------------------------------------------------------------
// Class basic_string_base.
@@ -268,7 +268,12 @@ class basic_string_base
}
size_type next_capacity(size_type additional_objects) const
{ return get_next_capacity(allocator_traits_type::max_size(this->alloc()), this->priv_storage(), additional_objects); }
{
return next_capacity_calculator
<size_type, NextCapacityDouble /*NextCapacity60Percent*/>::
get( allocator_traits_type::max_size(this->alloc())
, this->priv_storage(), additional_objects );
}
void deallocate(pointer p, size_type n)
{
@@ -433,7 +438,7 @@ class basic_string_base
} //namespace container_detail {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! The basic_string class represents a Sequence of characters. It contains all the
//! usual operations of a Sequence, and, additionally, it contains standard string
@@ -471,7 +476,7 @@ template <class CharT, class Traits, class Allocator>
class basic_string
: private container_detail::basic_string_base<Allocator>
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
typedef allocator_traits<Allocator> allocator_traits_type;
BOOST_COPYABLE_AND_MOVABLE(basic_string)
@@ -509,7 +514,7 @@ class basic_string
std::bind1st(Eq_traits<Tr>(), x)) == m_last;
}
};
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -533,14 +538,14 @@ class basic_string
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
static const size_type npos = size_type(-1);
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
typedef constant_iterator<CharT, difference_type> cvalue_iterator;
typedef typename base_t::allocator_v1 allocator_v1;
typedef typename base_t::allocator_v2 allocator_v2;
typedef typename base_t::alloc_version alloc_version;
typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public: // Constructor, destructor, assignment.
//////////////////////////////////////////////
@@ -548,7 +553,7 @@ class basic_string
// construct/copy/destroy
//
//////////////////////////////////////////////
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
struct reserve_t {};
basic_string(reserve_t, size_type n,
@@ -559,7 +564,7 @@ class basic_string
, n + 1)
{ this->priv_terminate_string(); }
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Effects</b>: Default constructs a basic_string.
//!
@@ -668,6 +673,15 @@ class basic_string
this->assign(n, c);
}
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and is initialized by n default-initialized characters.
basic_string(size_type n, default_init_t, const allocator_type& a = allocator_type())
: base_t(a, n + 1)
{
this->priv_size(n);
this->priv_terminate_string();
}
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
//! and a range of iterators.
template <class InputIterator>
@@ -945,6 +959,26 @@ class basic_string
void resize(size_type n)
{ resize(n, CharT()); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are uninitialized.
//!
//! <b>Throws</b>: If memory allocation 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)
{
if (n <= this->size())
this->erase(this->begin() + n, this->end());
else{
this->priv_reserve(n, false);
this->priv_size(n);
this->priv_terminate_string();
}
}
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
//!
@@ -961,29 +995,7 @@ class basic_string
//!
//! <b>Throws</b>: If memory allocation allocation throws
void reserve(size_type res_arg)
{
if (res_arg > this->max_size()){
throw_length_error("basic_string::reserve max_size() exceeded");
}
if (this->capacity() < res_arg){
size_type n = container_detail::max_value(res_arg, this->size()) + 1;
size_type new_cap = this->next_capacity(n);
pointer new_start = this->allocation_command
(allocate_new, n, new_cap, new_cap).first;
size_type new_length = 0;
const pointer addr = this->priv_addr();
new_length += priv_uninitialized_copy
(addr, addr + this->priv_size(), new_start);
this->priv_construct_null(new_start + new_length);
this->deallocate_block();
this->is_short(false);
this->priv_long_addr(new_start);
this->priv_long_size(new_length);
this->priv_storage(new_cap);
}
}
{ this->priv_reserve(res_arg); }
//! <b>Effects</b>: Tries to deallocate the excess of memory created
//! with previous allocations. The size of the string is unchanged
@@ -2296,8 +2308,35 @@ class basic_string
int compare(size_type pos1, size_type n1, const CharT* s) const
{ return this->compare(pos1, n1, s, Traits::length(s)); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
void priv_reserve(size_type res_arg, const bool null_terminate = true)
{
if (res_arg > this->max_size()){
throw_length_error("basic_string::reserve max_size() exceeded");
}
if (this->capacity() < res_arg){
size_type n = container_detail::max_value(res_arg, this->size()) + 1;
size_type new_cap = this->next_capacity(n);
pointer new_start = this->allocation_command
(allocate_new, n, new_cap, new_cap).first;
size_type new_length = 0;
const pointer addr = this->priv_addr();
new_length += priv_uninitialized_copy
(addr, addr + this->priv_size(), new_start);
if(null_terminate){
this->priv_construct_null(new_start + new_length);
}
this->deallocate_block();
this->is_short(false);
this->priv_long_addr(new_start);
this->priv_long_size(new_length);
this->priv_storage(new_cap);
}
}
static int s_compare(const_pointer f1, const_pointer l1,
const_pointer f2, const_pointer l2)
{
@@ -2431,9 +2470,11 @@ class basic_string
return this->priv_replace(first, last, f, l, Category());
}
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
//!Typedef for a basic_string of
//!narrow characters
typedef basic_string
@@ -2450,6 +2491,8 @@ typedef basic_string
,std::allocator<wchar_t> >
wstring;
#endif
// ------------------------------------------------------------
// Non-member functions.
@@ -2663,7 +2706,7 @@ template <class CharT, class Traits, class Allocator>
inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
{ x.swap(y); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
// I/O.
namespace container_detail {
@@ -2683,7 +2726,7 @@ string_fill(std::basic_ostream<CharT, Traits>& os,
}
} //namespace container_detail {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
@@ -2814,7 +2857,7 @@ inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator>
}}
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
@@ -2827,7 +2870,7 @@ struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Al
}
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#include <boost/container/detail/config_end.hpp>
@@ -76,26 +76,82 @@ namespace container {
#else //defined(BOOST_NO_EXCEPTIONS)
//! Exception callback called by Boost.Container when fails to allocate the requested storage space.
//! <ul>
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::bad_alloc()</code> is thrown.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
//! is NOT defined <code>BOOST_ASSERT(!"boost::container bad_alloc thrown")</code> is called
//! and <code>std::abort()</code> if the former returns.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
//! the user must provide an implementation and the function should not return.</li>
//! </ul>
inline void throw_bad_alloc()
{
throw std::bad_alloc();
}
//! Exception callback called by Boost.Container to signal arguments out of range.
//! <ul>
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::out_of_range(str)</code> is thrown.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str)</code> is called
//! and <code>std::abort()</code> if the former returns.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
//! the user must provide an implementation and the function should not return.</li>
//! </ul>
inline void throw_out_of_range(const char* str)
{
throw std::out_of_range(str);
}
//! Exception callback called by Boost.Container to signal errors resizing.
//! <ul>
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::length_error(str)</code> is thrown.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container length_error thrown", str)</code> is called
//! and <code>std::abort()</code> if the former returns.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
//! the user must provide an implementation and the function should not return.</li>
//! </ul>
inline void throw_length_error(const char* str)
{
throw std::length_error(str);
}
//! Exception callback called by Boost.Container to report errors in the internal logical
//! of the program, such as violation of logical preconditions or class invariants.
//! <ul>
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::logic_error(str)</code> is thrown.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str)</code> is called
//! and <code>std::abort()</code> if the former returns.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
//! the user must provide an implementation and the function should not return.</li>
//! </ul>
inline void throw_logic_error(const char* str)
{
throw std::logic_error(str);
}
//! Exception callback called by Boost.Container to report errors that can only be detected during runtime.
//! <ul>
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined <code>std::runtime_error(str)</code> is thrown.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str)</code> is called
//! and <code>std::abort()</code> if the former returns.</li>
//!
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
//! the user must provide an implementation and the function should not return.</li>
//! </ul>
inline void throw_runtime_error(const char* str)
{
throw std::runtime_error(str);
+243 -229
View File
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -53,7 +53,7 @@
namespace boost {
namespace container {
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//#define BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
@@ -80,7 +80,7 @@ class vec_iterator
, value_type&
>::type reference;
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
Pointer m_ptr;
@@ -94,7 +94,7 @@ class vec_iterator
explicit vec_iterator(Pointer ptr) BOOST_CONTAINER_NOEXCEPT
: m_ptr(ptr)
{}
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -245,17 +245,10 @@ struct vector_value_traits
<trivial_dctr
,container_detail::null_scoped_destructor_n<Allocator>
,container_detail::scoped_destructor_n<Allocator>
>::type OldArrayDestructor;
//This is the anti-exception array destructor
//to destroy objects created with copy construction
typedef typename container_detail::if_c
<nothrow_copy
,container_detail::null_scoped_destructor_n<Allocator>
,container_detail::scoped_destructor_n<Allocator>
>::type ArrayDestructor;
//This is the anti-exception array deallocator
typedef typename container_detail::if_c
<nothrow_copy
<false//nothrow_copy
,container_detail::null_scoped_array_deallocator<Allocator>
,container_detail::scoped_array_deallocator<Allocator>
>::type ArrayDeallocator;
@@ -294,7 +287,7 @@ struct vector_alloc_holder
//Constructor, does not throw
template<class AllocConvertible>
explicit vector_alloc_holder(uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
vector_alloc_holder(uninitialized_size_t, 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
@@ -306,7 +299,7 @@ struct vector_alloc_holder
}
//Constructor, does not throw
explicit vector_alloc_holder(uninitialized_size_t, size_type initial_size)
vector_alloc_holder(uninitialized_size_t, size_type initial_size)
: Allocator()
, m_start()
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this
@@ -347,7 +340,7 @@ struct vector_alloc_holder
}
std::pair<pointer, bool>
allocation_command(allocation_type command,
allocation_command(boost::container::allocation_type command,
size_type limit_size,
size_type preferred_size,
size_type &received_size, const pointer &reuse = pointer())
@@ -358,8 +351,10 @@ struct vector_alloc_holder
size_type next_capacity(size_type additional_objects) const
{
return get_next_capacity( allocator_traits_type::max_size(this->alloc())
, this->m_capacity, additional_objects);
return next_capacity_calculator
<size_type, /*NextCapacityDouble*/NextCapacity60Percent>::
get( allocator_traits_type::max_size(this->alloc())
, this->m_capacity, additional_objects );
}
pointer m_start;
@@ -526,9 +521,8 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
} //namespace container_detail {
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! \class vector
//! A vector is a sequence that supports random access to elements, constant
//! time insertion and removal of elements at the end, and linear time insertion
//! and removal of elements at the beginning or in the middle. The number of
@@ -542,7 +536,7 @@ template <class T, class Allocator>
#endif
class vector
{
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef container_detail::integral_constant
<unsigned, boost::container::container_detail::version
<Allocator>::value > alloc_version;
@@ -557,7 +551,7 @@ class vector
typedef container_detail::vec_iterator<pointer_impl, false> iterator_impl;
typedef container_detail::vec_iterator<pointer_impl, true > const_iterator_impl;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
//
@@ -584,7 +578,7 @@ class vector
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator;
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(vector)
typedef container_detail::vector_value_traits<value_type, Allocator> value_traits;
@@ -594,7 +588,7 @@ class vector
typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef constant_iterator<T, difference_type> cvalue_iterator;
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -645,7 +639,7 @@ class vector
//! <b>Complexity</b>: Linear to n.
//!
//! <b>Note</b>: Non-standard extension
explicit vector(size_type n, default_init_t)
vector(size_type n, default_init_t)
: m_holder(container_detail::uninitialized_size, n)
{
boost::container::uninitialized_default_init_alloc_n
@@ -810,7 +804,7 @@ class vector
vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
{
if (&x != this){
this->priv_copy_assign(boost::move(x), alloc_version());
this->priv_copy_assign(x, alloc_version());
}
return *this;
}
@@ -860,8 +854,9 @@ class vector
void assign(InIt first, InIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< !container_detail::is_convertible<InIt, size_type>::value
//&& container_detail::is_input_iterator<InIt>::value
< !container_detail::is_convertible<InIt, size_type>::value &&
( container_detail::is_input_iterator<InIt>::value ||
container_detail::is_same<alloc_version, allocator_v0>::value )
>::type * = 0
#endif
)
@@ -885,6 +880,64 @@ class vector
}
}
//! <b>Effects</b>: Assigns the the range [first, last) to *this.
//!
//! <b>Throws</b>: If memory allocation throws or T's copy/move constructor/assignment or
//! T's constructor/assignment from dereferencing InpIt throws.
//!
//! <b>Complexity</b>: Linear to n.
template <class FwdIt>
void assign(FwdIt first, FwdIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< !container_detail::is_convertible<FwdIt, size_type>::value &&
( !container_detail::is_input_iterator<FwdIt>::value &&
!container_detail::is_same<alloc_version, allocator_v0>::value )
>::type * = 0
#endif
)
{
//For Fwd iterators the standard only requires EmplaceConstructible and assignble from *first
//so we can't do any backwards allocation
const size_type input_sz = static_cast<size_type>(std::distance(first, last));
const size_type old_capacity = this->capacity();
if(input_sz > old_capacity){ //If input range is too big, we need to reallocate
size_type real_cap;
std::pair<pointer, bool> ret =
this->m_holder.allocation_command(allocate_new, input_sz, input_sz, real_cap, this->m_holder.start());
if(!ret.second){ //New allocation, just emplace new values
pointer const old_p = this->m_holder.start();
if(old_p){
this->priv_destroy_all();
this->m_holder.alloc().deallocate(old_p, old_capacity);
}
this->m_holder.start(ret.first);
this->m_holder.capacity(real_cap);
this->m_holder.m_size = 0;
this->priv_uninitialized_construct_at_end(first, last);
return;
}
else{
//Forward expansion, use assignment + back deletion/construction that comes later
}
}
//Overwrite all elements we can from [first, last)
iterator cur = this->begin();
const iterator end_it = this->end();
for ( ; first != last && cur != end_it; ++cur, ++first){
*cur = *first;
}
if (first == last){
//There are no more elements in the sequence, erase remaining
this->priv_destroy_last_n(this->size() - input_sz);
}
else{
//Uninitialized construct at end the remaining range
this->priv_uninitialized_construct_at_end(first, last);
}
}
//! <b>Effects</b>: Assigns the n copies of val to *this.
//!
//! <b>Throws</b>: If memory allocation throws or
@@ -1067,18 +1120,7 @@ class vector
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size)
{
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_value_initialized_n_proxy<Allocator, T*> proxy(this->m_holder.alloc());
this->priv_forward_range_insert_at_end(n, proxy, alloc_version());
}
}
{ this->priv_resize(new_size, value_init); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are value initialized.
@@ -1089,18 +1131,7 @@ class vector
//!
//! <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());
}
}
{ this->priv_resize(new_size, default_init); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
//! the size becomes n. New elements are copy constructed from x.
@@ -1109,18 +1140,7 @@ class vector
//!
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type new_size, const T& x)
{
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_n_copies_proxy<Allocator, T*> proxy(this->m_holder.alloc(), x);
this->priv_forward_range_insert_at_end(n, proxy, alloc_version());
}
}
{ this->priv_resize(new_size, x); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
@@ -1297,7 +1317,7 @@ class vector
else{
typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
this->priv_forward_range_insert_no_capacity
(vector_iterator_get_ptr(this->cend()), 1, type(this->m_holder.alloc(), ::boost::forward<Args>(args)...), alloc_version());
(vector_iterator_get_ptr(this->cend()), 1, type(::boost::forward<Args>(args)...), alloc_version());
}
}
@@ -1316,8 +1336,8 @@ class vector
{
//Just call more general insert(pos, size, value) and return iterator
typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1, type(this->m_holder.alloc()
, ::boost::forward<Args>(args)...), alloc_version());
return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1
, type(::boost::forward<Args>(args)...), alloc_version());
}
#else
@@ -1334,11 +1354,11 @@ class vector
++this->m_holder.m_size; \
} \
else{ \
container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
<Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->m_holder.alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
<Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
this->priv_forward_range_insert_no_capacity \
(vector_iterator_get_ptr(this->cend()), 1, proxy, alloc_version()); \
( vector_iterator_get_ptr(this->cend()), 1 \
, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)), alloc_version()); \
} \
} \
\
@@ -1346,11 +1366,11 @@ class vector
iterator emplace(const_iterator pos \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
<Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> proxy \
(this->m_holder.alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \
<Allocator, T* BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
return this->priv_forward_range_insert \
(container_detail::to_raw_pointer(vector_iterator_get_ptr(pos)), 1, proxy, alloc_version()); \
( container_detail::to_raw_pointer(vector_iterator_get_ptr(pos)), 1 \
, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)), alloc_version()); \
} \
//!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@@ -1414,7 +1434,7 @@ class vector
//! <b>Complexity</b>: Linear to n.
iterator insert(const_iterator p, size_type n, const T& x)
{
container_detail::insert_n_copies_proxy<Allocator, T*> proxy(this->m_holder.alloc(), x);
container_detail::insert_n_copies_proxy<Allocator, T*> proxy(x);
return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy, alloc_version());
}
@@ -1456,7 +1476,7 @@ class vector
>::type * = 0
)
{
container_detail::insert_range_proxy<Allocator, FwdIt, T*> proxy(this->m_holder.alloc(), first);
container_detail::insert_range_proxy<Allocator, FwdIt, T*> proxy(first);
return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), std::distance(first, last), proxy, alloc_version());
}
#endif
@@ -1536,9 +1556,7 @@ class vector
//! <b>Note</b>: non-standard extension.
template<class OtherAllocator>
void swap(vector<T, OtherAllocator> & x)
{
this->m_holder.swap(x.m_holder);
}
{ this->m_holder.swap(x.m_holder); }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -1550,7 +1568,7 @@ class vector
void clear() BOOST_CONTAINER_NOEXCEPT
{ this->priv_destroy_all(); }
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//Absolutely experimental. This function might change, disappear or simply crash!
template<class BiDirPosConstIt, class BiDirValueIt>
@@ -1590,9 +1608,7 @@ class vector
< !container_detail::is_same<AllocVersion, allocator_v0>::value ||
container_detail::is_same<OtherAllocator, allocator_type>::value
>::type * = 0)
{
this->priv_move_assign_impl(boost::move(x), AllocVersion());
}
{ this->priv_move_assign_impl(boost::move(x), AllocVersion()); }
template<class OtherAllocator, class AllocVersion>
void priv_move_assign_impl(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
@@ -1671,29 +1687,23 @@ class vector
}
void priv_reserve(size_type, allocator_v0)
{ throw_bad_alloc(); }
container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*> priv_dummy_empty_proxy()
{
throw_bad_alloc();
return container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
(::boost::make_move_iterator((T *)0));
}
void priv_reserve(size_type new_cap, allocator_v1)
{
//There is not enough memory, allocate a new buffer
pointer p = this->m_holder.allocate(new_cap);
//Backwards (and possibly forward) expansion
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc;
#endif
T * const raw_beg = container_detail::to_raw_pointer(this->m_holder.start());
const size_type sz = m_holder.m_size;
::boost::container::uninitialized_move_alloc_n_source
( this->m_holder.alloc(), raw_beg, sz, container_detail::to_raw_pointer(p) );
if(this->m_holder.capacity()){
if(!value_traits::trivial_dctr_after_move)
boost::container::destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz);
this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity());
}
this->m_holder.start(p);
this->m_holder.capacity(new_cap);
//We will reuse insert code, so create a dummy input iterator
this->priv_forward_range_insert_new_allocation
( container_detail::to_raw_pointer(p), new_cap
, container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size
, 0, this->priv_dummy_empty_proxy());
}
void priv_reserve(size_type new_cap, allocator_v2)
@@ -1702,10 +1712,8 @@ class vector
//buffer or expand the old one.
bool same_buffer_start;
size_type real_cap = 0;
std::pair<pointer, bool> ret =
this->m_holder.allocation_command
(allocate_new | expand_fwd | expand_bwd,
new_cap, new_cap, real_cap, this->m_holder.start());
std::pair<pointer, bool> ret = this->m_holder.allocation_command
(allocate_new | expand_fwd | expand_bwd, new_cap, new_cap, real_cap, this->m_holder.start());
//Check for forward expansion
same_buffer_start = ret.second && this->m_holder.start() == ret.first;
@@ -1715,52 +1723,26 @@ class vector
#endif
this->m_holder.capacity(real_cap);
}
//If there is no forward expansion, move objects
else{
//Backwards (and possibly forward) expansion
if(ret.second){
//We will reuse insert code, so create a dummy input iterator
container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
proxy(this->m_holder.alloc(), ::boost::make_move_iterator((T *)0));
else{ //If there is no forward expansion, move objects, we will reuse insertion code
T * const new_mem = container_detail::to_raw_pointer(ret.first);
T * const ins_pos = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
if(ret.second){ //Backwards (and possibly forward) expansion
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_expand_bwd;
#endif
this->priv_forward_range_insert_expand_backwards
( container_detail::to_raw_pointer(ret.first)
, real_cap
, container_detail::to_raw_pointer(this->m_holder.start())
, 0
, proxy);
( new_mem , real_cap, ins_pos, 0, this->priv_dummy_empty_proxy());
}
//New buffer
else{
else{ //New buffer
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc;
#endif
T * const raw_beg = container_detail::to_raw_pointer(this->m_holder.start());
const size_type sz = m_holder.m_size;
::boost::container::uninitialized_move_alloc_n_source
( this->m_holder.alloc(), raw_beg, sz, container_detail::to_raw_pointer(ret.first) );
if(this->m_holder.capacity()){
if(!value_traits::trivial_dctr_after_move)
boost::container::destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz);
this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity());
}
this->m_holder.start(ret.first);
this->m_holder.capacity(real_cap);
this->priv_forward_range_insert_new_allocation
( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy());
}
}
}
template<class Proxy>
void priv_uninitialized_fill(Proxy proxy, size_type n) const
{
//Copy first new elements in pos
proxy.uninitialized_copy_n_and_update
(container_detail::to_raw_pointer(this->m_holder.start()), n);
//m_holder.size was already initialized to n in vector_alloc_holder's constructor
}
void priv_destroy(value_type* p) BOOST_CONTAINER_NOEXCEPT
{
if(!value_traits::trivial_dctr)
@@ -1774,6 +1756,16 @@ class vector
this->m_holder.m_size -= n;
}
template<class InpIt>
void priv_uninitialized_construct_at_end(InpIt first, InpIt last)
{
T* end_pos = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
for(; first != last; ++first, ++end_pos, ++this->m_holder.m_size){
//There is more memory, just construct a new object at the end
allocator_traits_type::construct(this->m_holder.alloc(), end_pos, *first);
}
}
void priv_destroy_all() BOOST_CONTAINER_NOEXCEPT
{
boost::container::destroy_alloc_n
@@ -1785,39 +1777,54 @@ class vector
iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x)
{
return this->priv_forward_range_insert
( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy<T*>(this->m_holder.alloc()
, ::boost::forward<U>(x)), alloc_version());
( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy<T*, Allocator>
(::boost::forward<U>(x)), alloc_version());
}
void priv_push_back(const T &x)
container_detail::insert_copy_proxy<Allocator, T*> priv_single_insert_proxy(const T &x)
{ return container_detail::insert_copy_proxy<Allocator, T*> (x); }
container_detail::insert_move_proxy<Allocator, T*> priv_single_insert_proxy(BOOST_RV_REF(T) x)
{ return container_detail::insert_move_proxy<Allocator, T*> (x); }
template <class U>
void priv_push_back(BOOST_FWD_REF(U) u)
{
if (this->m_holder.m_size < this->m_holder.capacity()){
//There is more memory, just construct a new object at the end
allocator_traits_type::construct
( this->m_holder.alloc()
, container_detail::to_raw_pointer(this->m_holder.start() + this->m_holder.m_size)
, x );
, ::boost::forward<U>(u) );
++this->m_holder.m_size;
}
else{
container_detail::insert_copy_proxy<Allocator, T*> proxy(this->m_holder.alloc(), x);
this->priv_forward_range_insert_no_capacity(vector_iterator_get_ptr(this->cend()), 1, proxy, alloc_version());
this->priv_forward_range_insert_no_capacity
( vector_iterator_get_ptr(this->cend()), 1
, this->priv_single_insert_proxy(::boost::forward<U>(u)), alloc_version());
}
}
void priv_push_back(BOOST_RV_REF(T) x)
container_detail::insert_n_copies_proxy<Allocator, T*> priv_resize_proxy(const T &x)
{ return container_detail::insert_n_copies_proxy<Allocator, T*>(x); }
container_detail::insert_default_initialized_n_proxy<Allocator, T*> priv_resize_proxy(default_init_t)
{ return container_detail::insert_default_initialized_n_proxy<Allocator, T*>(); }
container_detail::insert_value_initialized_n_proxy<Allocator, T*> priv_resize_proxy(value_init_t)
{ return container_detail::insert_value_initialized_n_proxy<Allocator, T*>(); }
template <class U>
void priv_resize(size_type new_size, const U& u)
{
if (this->m_holder.m_size < this->m_holder.capacity()){
//There is more memory, just construct a new object at the end
allocator_traits_type::construct
( this->m_holder.alloc()
, container_detail::to_raw_pointer(this->m_holder.start() + this->m_holder.m_size)
, ::boost::move(x) );
++this->m_holder.m_size;
const size_type sz = this->size();
if (new_size < sz){
//Destroy last elements
this->priv_destroy_last_n(sz - new_size);
}
else{
container_detail::insert_move_proxy<Allocator, T*> proxy(this->m_holder.alloc(), x);
this->priv_forward_range_insert_no_capacity(vector_iterator_get_ptr(this->cend()), 1, proxy, alloc_version());
const size_type n = new_size - this->size();
this->priv_forward_range_insert_at_end(n, this->priv_resize_proxy(u), alloc_version());
}
}
@@ -1839,17 +1846,13 @@ class vector
pointer p = this->m_holder.allocate(sz);
//We will reuse insert code, so create a dummy input iterator
container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*>
proxy(this->m_holder.alloc(), ::boost::make_move_iterator((T *)0));
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc;
#endif
this->priv_forward_range_insert_new_allocation
( container_detail::to_raw_pointer(p)
, sz
( container_detail::to_raw_pointer(p), sz
, container_detail::to_raw_pointer(this->m_holder.start())
, 0
, proxy);
, 0, this->priv_dummy_empty_proxy());
}
}
}
@@ -1981,8 +1984,7 @@ class vector
if (n <= remaining){
const size_type n_pos = raw_pos - container_detail::to_raw_pointer(this->m_holder.start());
this->priv_forward_range_insert_expand_forward
(raw_pos, n, insert_range_proxy);
this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
return iterator(this->m_holder.start() + n_pos);
}
else{
@@ -2164,7 +2166,7 @@ class vector
T* const last_ptr = begin_ptr + last_pos;
size_type hole_size = 0;
//Case Allocator:
//Case A:
if((last_pos + shift_count) <= limit_pos){
//All move assigned
boost::move_backward(first_ptr, last_ptr, last_ptr + shift_count);
@@ -2193,7 +2195,7 @@ class vector
void priv_forward_range_insert_at_end_expand_forward(const size_type n, InsertionProxy insert_range_proxy)
{
T* const old_finish = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n);
insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
this->m_holder.m_size += n;
}
@@ -2207,7 +2209,7 @@ class vector
const size_type elems_after = old_finish - pos;
if (!elems_after){
insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n);
insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
this->m_holder.m_size += n;
}
else if (elems_after >= n){
@@ -2219,7 +2221,7 @@ class vector
//Copy previous to last objects to the initialized end
boost::move_backward(pos, old_finish - n, old_finish);
//Insert new objects in the pos
insert_range_proxy.copy_n_and_update(pos, n);
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n);
}
else {
//The new elements don't fit in the [pos, end()) range.
@@ -2228,9 +2230,9 @@ class vector
::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pos, old_finish, pos + n);
BOOST_TRY{
//Copy first new elements in pos (gap is still there)
insert_range_proxy.copy_n_and_update(pos, elems_after);
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elems_after);
//Copy to the beginning of the unallocated zone the last new elements (the gap is closed).
insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n - elems_after);
insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n - elems_after);
this->m_holder.m_size += n;
}
BOOST_CATCH(...){
@@ -2249,21 +2251,22 @@ class vector
T *new_finish = new_start;
T *old_finish;
//Anti-exception rollbacks
typename value_traits::ArrayDeallocator scoped_alloc(new_start, this->m_holder.alloc(), new_cap);
typename value_traits::ArrayDestructor constructed_values_destroyer(new_start, this->m_holder.alloc(), 0u);
typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, this->m_holder.alloc(), new_cap);
typename value_traits::ArrayDestructor new_values_destroyer(new_start, this->m_holder.alloc(), 0u);
//Initialize with [begin(), pos) old buffer
//the start of the new buffer
T *old_buffer = container_detail::to_raw_pointer(this->m_holder.start());
T * const old_buffer = container_detail::to_raw_pointer(this->m_holder.start());
if(old_buffer){
new_finish = ::boost::container::uninitialized_move_alloc
(this->m_holder.alloc(), container_detail::to_raw_pointer(this->m_holder.start()), pos, old_finish = new_finish);
constructed_values_destroyer.increment_size(new_finish - old_finish);
new_values_destroyer.increment_size(new_finish - old_finish);
}
//Initialize new objects, starting from previous point
insert_range_proxy.uninitialized_copy_n_and_update(old_finish = new_finish, n);
old_finish = new_finish;
insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
new_finish += n;
constructed_values_destroyer.increment_size(new_finish - old_finish);
new_values_destroyer.increment_size(new_finish - old_finish);
//Initialize from the rest of the old buffer,
//starting from previous point
if(old_buffer){
@@ -2279,8 +2282,8 @@ class vector
this->m_holder.m_size = new_finish - new_start;
this->m_holder.capacity(new_cap);
//All construction successful, disable rollbacks
constructed_values_destroyer.release();
scoped_alloc.release();
new_values_destroyer.release();
new_buffer_deallocator.release();
}
template <class InsertionProxy>
@@ -2291,8 +2294,8 @@ class vector
//n can be zero to just expand capacity
//Backup old data
T* const old_start = container_detail::to_raw_pointer(this->m_holder.start());
T* const old_finish = old_start + this->m_holder.m_size;
const size_type old_size = this->m_holder.m_size;
T* const old_finish = old_start + old_size;
//We can have 8 possibilities:
const size_type elemsbefore = static_cast<size_type>(pos - old_start);
@@ -2306,17 +2309,18 @@ class vector
//If anything goes wrong, this object will destroy
//all the old objects to fulfill previous vector state
typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->m_holder.alloc(), old_size);
typename value_traits::ArrayDestructor old_values_destroyer(old_start, this->m_holder.alloc(), old_size);
//Check if s_before is big enough to hold the beginning of old data + new data
if(s_before >= before_plus_new){
//Copy first old values before pos, after that the new objects
T *const new_elem_pos = ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), old_start, pos, new_start);
T *const new_elem_pos =
::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), old_start, pos, new_start);
this->m_holder.m_size = elemsbefore;
insert_range_proxy.uninitialized_copy_n_and_update(new_elem_pos, n);
this->m_holder.m_size += n;
insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_elem_pos, n);
this->m_holder.m_size = before_plus_new;
const size_type new_size = old_size + n;
//Check if s_before is so big that even copying the old data + new data
//there is a gap between the new data and the old data
const size_type new_size = old_size + n;
if(s_before >= new_size){
//Old situation:
// _________________________________________________________
@@ -2329,10 +2333,12 @@ class vector
//|___________|__________|_________|________________________|
//
//Now initialize the rest of memory with the last old values
::boost::container::uninitialized_move_alloc
(this->m_holder.alloc(), pos, old_finish, new_start + before_plus_new);
//All new elements correctly constructed, avoid new element destruction
this->m_holder.m_size = new_size;
if(before_plus_new != new_size){ //Special case to avoid operations in back insertion
::boost::container::uninitialized_move_alloc
(this->m_holder.alloc(), pos, old_finish, new_start + before_plus_new);
//All new elements correctly constructed, avoid new element destruction
this->m_holder.m_size = new_size;
}
//Old values destroyed automatically with "old_values_destroyer"
//when "old_values_destroyer" goes out of scope unless the have trivial
//destructor after move.
@@ -2354,22 +2360,28 @@ class vector
//Now initialize the rest of memory with the last old values
//All new elements correctly constructed, avoid new element destruction
const size_type raw_gap = s_before - before_plus_new;
//Now initialize the rest of s_before memory with the
//first of elements after new values
::boost::container::uninitialized_move_alloc_n
(this->m_holder.alloc(), pos, raw_gap, new_start + before_plus_new);
//Update size since we have a contiguous buffer
this->m_holder.m_size = old_size + s_before;
//All new elements correctly constructed, avoid old element destruction
old_values_destroyer.release();
//Now copy remaining last objects in the old buffer begin
T * const to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start);
//Now destroy redundant elements except if they were moved and
//they have trivial destructor after move
size_type n_destroy = old_finish - to_destroy;
if(!value_traits::trivial_dctr_after_move)
boost::container::destroy_alloc_n(this->get_stored_allocator(), to_destroy, n_destroy);
this->m_holder.m_size -= n_destroy;
if(!value_traits::trivial_dctr){
//Now initialize the rest of s_before memory with the
//first of elements after new values
::boost::container::uninitialized_move_alloc_n
(this->m_holder.alloc(), pos, raw_gap, new_start + before_plus_new);
//Now we have a contiguous buffer so program trailing element destruction
//and update size to the final size.
old_values_destroyer.shrink_forward(elemsbefore + raw_gap);
this->m_holder.m_size = new_size;
//Now move remaining last objects in the old buffer begin
::boost::move(pos + raw_gap, old_finish, old_start);
//Once moved, avoid calling the destructors if trivial after move
if(value_traits::trivial_dctr_after_move){
old_values_destroyer.release();
}
}
else{ //If trivial destructor, we can uninitialized copy + copy in a single uninitialized copy
::boost::container::uninitialized_move_alloc_n
(this->m_holder.alloc(), pos, old_finish - pos, new_start + before_plus_new);
this->m_holder.m_size = new_size;
old_values_destroyer.release();
}
}
}
else{
@@ -2423,27 +2435,30 @@ class vector
//Copy the first part of old_begin to raw_mem
::boost::container::uninitialized_move_alloc_n
(this->m_holder.alloc(), old_start, s_before, new_start);
//The buffer is all constructed until old_end,
//release destroyer and update size
old_values_destroyer.release();
this->m_holder.m_size = old_size + s_before;
//Now copy the second part of old_begin overwriting itself
T *const next = ::boost::move(old_start + s_before, pos, old_start);
//The buffer is all constructed until old_end
if(do_after){
//release destroyer and update size
old_values_destroyer.release();
this->m_holder.m_size = old_size + s_before;
//Now copy the second part of old_begin overwriting itself
T *const next = ::boost::move(old_start + s_before, pos, old_start);
//Now copy the new_beg elements
insert_range_proxy.copy_n_and_update(next, s_before);
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, s_before);
}
else{
//Now copy the all the new elements
insert_range_proxy.copy_n_and_update(next, n);
//Now displace old_end elements
T* const move_end = ::boost::move(pos, old_finish, next + n);
//Destroy remaining moved elements from old_end except if
//they have trivial destructor after being moved
//The buffer is all constructed until old_end,
//so program trailing destruction and assign final size
this->m_holder.m_size = old_size + n;
const size_type n_destroy = s_before - n;
if(!value_traits::trivial_dctr_after_move)
boost::container::destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy);
this->m_holder.m_size -= n_destroy;
old_values_destroyer.shrink_forward(old_size - n_destroy);
//Now copy the second part of old_begin overwriting itself
T *const next = ::boost::move(old_start + s_before, pos, old_start);
//Now copy the all the new elements
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, n);
//Now displace old_end elements
::boost::move(pos, old_finish, next + n);
if(value_traits::trivial_dctr_after_move)
old_values_destroyer.release();
}
}
else {
@@ -2477,7 +2492,7 @@ class vector
(this->m_holder.alloc(), old_start, pos, new_start);
this->m_holder.m_size = elemsbefore;
const size_type mid_n = s_before - elemsbefore;
insert_range_proxy.uninitialized_copy_n_and_update(new_pos, mid_n);
insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_pos, mid_n);
//The buffer is all constructed until old_end,
//release destroyer
this->m_holder.m_size = old_size + s_before;
@@ -2485,15 +2500,15 @@ class vector
if(do_after){
//Copy new_beg part
insert_range_proxy.copy_n_and_update(old_start, elemsbefore);
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, elemsbefore);
}
else{
//Copy all new elements
const size_type rest_new = n - mid_n;
insert_range_proxy.copy_n_and_update(old_start, rest_new);
T* move_start = old_start + rest_new;
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, rest_new);
T* const move_start = old_start + rest_new;
//Displace old_end
T* move_end = ::boost::move(pos, old_finish, move_start);
T* const move_end = ::boost::move(pos, old_finish, move_start);
//Destroy remaining moved elements from old_end except if they
//have trivial destructor after being moved
size_type n_destroy = s_before - n;
@@ -2548,7 +2563,7 @@ class vector
boost::move_backward(pos, finish_n, old_finish);
//Now overwrite with new_end
//The new_end part is [first + (n - n_after), last)
insert_range_proxy.copy_n_and_update(pos, n_after);
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n_after);
}
else {
//The raw_mem from end will divide new_end part
@@ -2573,9 +2588,9 @@ class vector
BOOST_TRY{
//Copy the first part to the already constructed old_end zone
insert_range_proxy.copy_n_and_update(pos, elemsafter);
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elemsafter);
//Copy the rest to the uninitialized zone filling the gap
insert_range_proxy.uninitialized_copy_n_and_update(old_finish, mid_last_dist);
insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, mid_last_dist);
this->m_holder.m_size += n_after;
}
BOOST_CATCH(...){
@@ -2617,7 +2632,7 @@ class vector
void reset_alloc_stats()
{ num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; }
#endif
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
template <class T, class Allocator>
@@ -2649,7 +2664,7 @@ inline void swap(vector<T, Allocator>& x, vector<T, Allocator>& y)
}}
/// @cond
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
@@ -2678,9 +2693,8 @@ inline void swap(boost::container::vector<T, Allocator>& x, boost::container::ve
#endif
/// @endcond
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#include <boost/container/detail/config_end.hpp>
#endif // #ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP