summaryrefslogtreecommitdiff
path: root/boost/container
diff options
context:
space:
mode:
Diffstat (limited to 'boost/container')
-rw-r--r--boost/container/adaptive_pool.hpp86
-rw-r--r--boost/container/allocator.hpp61
-rw-r--r--boost/container/allocator_traits.hpp458
-rw-r--r--boost/container/container_fwd.hpp45
-rw-r--r--boost/container/deque.hpp569
-rw-r--r--boost/container/detail/adaptive_node_pool.hpp9
-rw-r--r--boost/container/detail/adaptive_node_pool_impl.hpp26
-rw-r--r--boost/container/detail/addressof.hpp41
-rw-r--r--boost/container/detail/advanced_insert_int.hpp376
-rw-r--r--boost/container/detail/algorithm.hpp35
-rw-r--r--boost/container/detail/algorithms.hpp62
-rw-r--r--boost/container/detail/alloc_helpers.hpp60
-rw-r--r--boost/container/detail/alloc_lib_auto_link.hpp6
-rw-r--r--boost/container/detail/allocation_type.hpp8
-rw-r--r--boost/container/detail/allocator_version_traits.hpp36
-rw-r--r--boost/container/detail/auto_link.hpp6
-rw-r--r--boost/container/detail/compare_functors.hpp74
-rw-r--r--boost/container/detail/config_begin.hpp22
-rw-r--r--boost/container/detail/construct_in_place.hpp62
-rw-r--r--boost/container/detail/copy_move_algo.hpp (renamed from boost/container/detail/utilities.hpp)608
-rw-r--r--boost/container/detail/destroyers.hpp86
-rw-r--r--boost/container/detail/flat_tree.hpp239
-rw-r--r--boost/container/detail/function_detector.hpp6
-rw-r--r--boost/container/detail/hash_table.hpp24
-rw-r--r--boost/container/detail/iterator.hpp39
-rw-r--r--boost/container/detail/iterator_to_raw_pointer.hpp58
-rw-r--r--boost/container/detail/iterators.hpp137
-rw-r--r--boost/container/detail/math_functions.hpp6
-rw-r--r--boost/container/detail/memory_util.hpp90
-rw-r--r--boost/container/detail/min_max.hpp37
-rw-r--r--boost/container/detail/minimal_char_traits_header.hpp32
-rw-r--r--boost/container/detail/mpl.hpp19
-rw-r--r--boost/container/detail/multiallocation_chain.hpp18
-rw-r--r--boost/container/detail/mutex.hpp10
-rw-r--r--boost/container/detail/next_capacity.hpp75
-rw-r--r--boost/container/detail/node_alloc_holder.hpp225
-rw-r--r--boost/container/detail/node_pool.hpp9
-rw-r--r--boost/container/detail/node_pool_impl.hpp31
-rw-r--r--boost/container/detail/pair.hpp56
-rw-r--r--boost/container/detail/placement_new.hpp11
-rw-r--r--boost/container/detail/pool_common.hpp6
-rw-r--r--boost/container/detail/pool_common_alloc.hpp6
-rw-r--r--boost/container/detail/preprocessor.hpp228
-rw-r--r--boost/container/detail/singleton.hpp6
-rw-r--r--boost/container/detail/std_fwd.hpp17
-rw-r--r--boost/container/detail/to_raw_pointer.hpp33
-rw-r--r--boost/container/detail/transform_iterator.hpp15
-rw-r--r--boost/container/detail/tree.hpp343
-rw-r--r--boost/container/detail/type_traits.hpp252
-rw-r--r--boost/container/detail/value_init.hpp6
-rw-r--r--boost/container/detail/variadic_templates_tools.hpp6
-rw-r--r--boost/container/detail/version_type.hpp13
-rw-r--r--boost/container/detail/workaround.hpp18
-rw-r--r--boost/container/flat_map.hpp401
-rw-r--r--boost/container/flat_set.hpp349
-rw-r--r--boost/container/list.hpp315
-rw-r--r--boost/container/map.hpp363
-rw-r--r--boost/container/new_allocator.hpp175
-rw-r--r--boost/container/node_allocator.hpp74
-rw-r--r--boost/container/options.hpp6
-rw-r--r--boost/container/scoped_allocator.hpp1061
-rw-r--r--boost/container/scoped_allocator_fwd.hpp49
-rw-r--r--boost/container/set.hpp211
-rw-r--r--boost/container/slist.hpp346
-rw-r--r--boost/container/small_vector.hpp565
-rw-r--r--boost/container/stable_vector.hpp390
-rw-r--r--boost/container/static_vector.hpp170
-rw-r--r--boost/container/string.hpp228
-rw-r--r--boost/container/throw_exception.hpp6
-rw-r--r--boost/container/vector.hpp1203
70 files changed, 6052 insertions, 4667 deletions
diff --git a/boost/container/adaptive_pool.hpp b/boost/container/adaptive_pool.hpp
index c12d511c65..1f6b6667e9 100644
--- a/boost/container/adaptive_pool.hpp
+++ b/boost/container/adaptive_pool.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_ADAPTIVE_POOL_HPP
#define BOOST_CONTAINER_ADAPTIVE_POOL_HPP
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -25,15 +29,11 @@
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/alloc_lib_auto_link.hpp>
#include <boost/container/detail/singleton.hpp>
-
#include <boost/container/detail/placement_new.hpp>
#include <boost/assert.hpp>
-#include <boost/utility/addressof.hpp>
#include <boost/static_assert.hpp>
#include <boost/move/utility_core.hpp>
-#include <memory>
-#include <algorithm>
#include <cstddef>
@@ -57,7 +57,7 @@ template < class T
, std::size_t NodesPerBlock BOOST_CONTAINER_DOCONLY(= ADP_nodes_per_block)
, std::size_t MaxFreeBlocks BOOST_CONTAINER_DOCONLY(= ADP_max_free_blocks)
, std::size_t OverheadPercent BOOST_CONTAINER_DOCONLY(= ADP_overhead_percent)
- BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I unsigned Version)
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I unsigned Version)
>
class adaptive_pool
{
@@ -67,7 +67,7 @@ class adaptive_pool
typedef unsigned int allocation_type;
typedef adaptive_pool
<T, NodesPerBlock, MaxFreeBlocks, OverheadPercent
- BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I Version)
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
> self_t;
static const std::size_t nodes_per_block = NodesPerBlock;
@@ -110,7 +110,7 @@ class adaptive_pool
, NodesPerBlock
, MaxFreeBlocks
, OverheadPercent
- BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I Version)
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)
> other;
};
@@ -127,34 +127,34 @@ class adaptive_pool
public:
//!Default constructor
- adaptive_pool() BOOST_CONTAINER_NOEXCEPT
+ adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Copy constructor from other adaptive_pool.
- adaptive_pool(const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
+ adaptive_pool(const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Copy constructor from related adaptive_pool.
template<class T2>
adaptive_pool
(const adaptive_pool<T2, NodesPerBlock, MaxFreeBlocks, OverheadPercent
- BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I Version)> &) BOOST_CONTAINER_NOEXCEPT
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I Version)> &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Destructor
- ~adaptive_pool() BOOST_CONTAINER_NOEXCEPT
+ ~adaptive_pool() BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Returns the number of elements that could be allocated.
//!Never throws
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return size_type(-1)/sizeof(T); }
//!Allocate memory for an array of count elements.
//!Throws std::bad_alloc if there is no enough memory
pointer allocate(size_type count, const void * = 0)
{
- if(count > this->max_size())
+ if(BOOST_UNLIKELY(count > this->max_size()))
boost::container::throw_bad_alloc();
if(Version == 1 && count == 1){
@@ -170,7 +170,7 @@ class adaptive_pool
//!Deallocate allocated memory.
//!Never throws
- void deallocate(const pointer &ptr, size_type count) BOOST_CONTAINER_NOEXCEPT
+ void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW
{
(void)count;
if(Version == 1 && count == 1){
@@ -184,22 +184,20 @@ class adaptive_pool
}
}
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ pointer allocation_command(allocation_type command,
size_type limit_size,
- size_type preferred_size,
- size_type &received_size, pointer reuse = pointer())
+ size_type &prefer_in_recvd_out_size,
+ pointer &reuse)
{
- std::pair<pointer, bool> ret =
- this->priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
- if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
+ pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+ if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
boost::container::throw_bad_alloc();
return ret;
}
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
- size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
+ size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
{ return boost_cont_size(p); }
//!Allocates just one object. Memory allocated with this function
@@ -230,7 +228,7 @@ class adaptive_pool
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
- void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef container_detail::shared_adaptive_node_pool
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
@@ -238,7 +236,7 @@ class adaptive_pool
singleton_t::instance().deallocate_node(p);
}
- void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef container_detail::shared_adaptive_node_pool
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
@@ -255,14 +253,15 @@ class adaptive_pool
BOOST_STATIC_ASSERT(( Version > 1 ));/*
boost_cont_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
- if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
+ if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after(chain.before_begin()
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
- if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
+ if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes
+ (n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain)))){
boost::container::throw_bad_alloc();
}
}
@@ -274,19 +273,20 @@ class adaptive_pool
BOOST_STATIC_ASSERT(( Version > 1 ));/*
boost_cont_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
- if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
+ if(BOOST_UNLIKELY(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after(chain.before_begin()
,(T*)BOOST_CONTAINER_MEMCHAIN_FIRSTMEM(&ch)
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
- if(!boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain))){
+ if(BOOST_UNLIKELY(!boost_cont_multialloc_arrays
+ (n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<boost_cont_memchain *>(&chain)))){
boost::container::throw_bad_alloc();
}
}
- void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
{/*
boost_cont_memchain ch;
void *beg(&*chain.begin()), *last(&*chain.last());
@@ -297,7 +297,7 @@ class adaptive_pool
}
//!Deallocates all free blocks of the pool
- static void deallocate_free_blocks() BOOST_CONTAINER_NOEXCEPT
+ static void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW
{
typedef container_detail::shared_adaptive_node_pool
<sizeof(T), NodesPerBlock, MaxFreeBlocks, OverheadPercent> shared_pool_t;
@@ -307,37 +307,39 @@ class adaptive_pool
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different memory segment, the result is undefined.
- friend void swap(adaptive_pool &, adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
+ friend void swap(adaptive_pool &, adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!An allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
- friend bool operator==(const adaptive_pool &, const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator==(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{ return true; }
//!An allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
- friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{ return false; }
private:
- std::pair<pointer, bool> priv_allocation_command
+ pointer priv_allocation_command
(allocation_type command, std::size_t limit_size
- ,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
+ ,size_type &prefer_in_recvd_out_size, pointer &reuse_ptr)
{
+ std::size_t const preferred_size = prefer_in_recvd_out_size;
boost_cont_command_ret_t ret = {0 , 0};
- if(limit_size > this->max_size() || preferred_size > this->max_size()){
-// ret.first = 0;
- return std::pair<pointer, bool>(pointer(), false);
+ if(BOOST_UNLIKELY(limit_size > this->max_size() || preferred_size > this->max_size())){
+ return pointer();
}
std::size_t l_size = limit_size*sizeof(T);
std::size_t p_size = preferred_size*sizeof(T);
std::size_t r_size;
{
- ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
+ void* reuse_ptr_void = reuse_ptr;
+ ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
+ reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
}
- received_size = r_size/sizeof(T);
- return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
+ prefer_in_recvd_out_size = r_size/sizeof(T);
+ return (pointer)ret.first;
}
};
diff --git a/boost/container/allocator.hpp b/boost/container/allocator.hpp
index 14d56452b6..9f757c73e8 100644
--- a/boost/container/allocator.hpp
+++ b/boost/container/allocator.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_HPP
#define BOOST_CONTAINER_ALLOCATOR_HPP
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -25,7 +29,6 @@
#include <boost/static_assert.hpp>
#include <cstddef>
#include <cassert>
-#include <new>
namespace boost {
namespace container {
@@ -156,12 +159,12 @@ class allocator
//!Default constructor
//!Never throws
- allocator() BOOST_CONTAINER_NOEXCEPT
+ allocator() BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Constructor from other allocator.
//!Never throws
- allocator(const allocator &) BOOST_CONTAINER_NOEXCEPT
+ allocator(const allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Constructor from related allocator.
@@ -171,7 +174,7 @@ class allocator
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
, Version, AllocationDisableMask
#endif
- > &) BOOST_CONTAINER_NOEXCEPT
+ > &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Allocates memory for an array of count elements.
@@ -191,45 +194,43 @@ class allocator
//!Deallocates previously allocated memory.
//!Never throws
- void deallocate(pointer ptr, size_type) BOOST_CONTAINER_NOEXCEPT
+ void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW
{ boost_cont_free(ptr); }
//!Returns the maximum number of elements that could be allocated.
//!Never throws
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return size_type(-1)/sizeof(T); }
//!Swaps two allocators, does nothing
//!because this allocator is stateless
- friend void swap(self_t &, self_t &) BOOST_CONTAINER_NOEXCEPT
+ friend void swap(self_t &, self_t &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!An allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
- friend bool operator==(const allocator &, const allocator &) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator==(const allocator &, const allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return true; }
//!An allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
- friend bool operator!=(const allocator &, const allocator &) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator!=(const allocator &, const allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return false; }
//!An advanced function that offers in-place expansion shrink to fit and new allocation
//!capabilities. Memory allocated with this function can only be deallocated with deallocate()
//!or deallocate_many().
//!This function is available only with Version == 2
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ pointer allocation_command(allocation_type command,
size_type limit_size,
- size_type preferred_size,
- size_type &received_size, pointer reuse = pointer())
+ size_type &prefer_in_recvd_out_size,
+ pointer &reuse)
{
BOOST_STATIC_ASSERT(( Version > 1 ));
const allocation_type mask(AllocationDisableMask);
command &= ~mask;
- std::pair<pointer, bool> ret =
- priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
- if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
+ pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+ if(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
boost::container::throw_bad_alloc();
return ret;
}
@@ -239,7 +240,7 @@ class allocator
//!Memory must not have been allocated with
//!allocate_one or allocate_individual.
//!This function is available only with Version == 2
- size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
+ size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_STATIC_ASSERT(( Version > 1 ));
return boost_cont_size(p);
@@ -268,7 +269,7 @@ class allocator
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one() or allocate_individual.
//Never throws
- void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_STATIC_ASSERT(( Version > 1 ));
return this->deallocate(p, 1);
@@ -276,7 +277,7 @@ class allocator
//!Deallocates memory allocated with allocate_one() or allocate_individual().
//!This function is available only with Version == 2
- void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_STATIC_ASSERT(( Version > 1 ));
return this->deallocate_many(chain);
@@ -326,7 +327,7 @@ class allocator
//!Deallocates several elements allocated by
//!allocate_many(), allocate(), or allocation_command().
//!This function is available only with Version == 2
- void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_STATIC_ASSERT(( Version > 1 ));
boost_cont_memchain ch;
@@ -339,22 +340,26 @@ class allocator
private:
- std::pair<pointer, bool> priv_allocation_command
- (allocation_type command, std::size_t limit_size
- ,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
+ pointer priv_allocation_command
+ (allocation_type command, std::size_t limit_size
+ ,size_type &prefer_in_recvd_out_size
+ ,pointer &reuse_ptr)
{
+ std::size_t const preferred_size = prefer_in_recvd_out_size;
boost_cont_command_ret_t ret = {0 , 0};
if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
- return std::pair<pointer, bool>(pointer(), false);
+ return pointer();
}
std::size_t l_size = limit_size*sizeof(T);
std::size_t p_size = preferred_size*sizeof(T);
std::size_t r_size;
{
- ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
+ void* reuse_ptr_void = reuse_ptr;
+ ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
+ reuse_ptr = ret.second ? static_cast<T*>(reuse_ptr_void) : 0;
}
- received_size = r_size/sizeof(T);
- return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
+ prefer_in_recvd_out_size = r_size/sizeof(T);
+ return (pointer)ret.first;
}
};
diff --git a/boost/container/allocator_traits.hpp b/boost/container/allocator_traits.hpp
index a85831f984..cdaf2eacf0 100644
--- a/boost/container/allocator_traits.hpp
+++ b/boost/container/allocator_traits.hpp
@@ -13,43 +13,82 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+
+// container
#include <boost/container/container_fwd.hpp>
-#include <boost/intrusive/pointer_traits.hpp>
-#include <boost/intrusive/detail/memory_util.hpp>
-#include <boost/container/detail/memory_util.hpp>
#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/type_traits.hpp> //is_empty
#include <boost/container/detail/placement_new.hpp>
+#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
+#include <boost/container/detail/std_fwd.hpp>
+#endif
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
+// move
#include <boost/move/utility_core.hpp>
-
+// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-#include <boost/container/detail/preprocessor.hpp>
+#include <boost/move/detail/fwd_macros.hpp>
#endif
+// other boost
+#include <boost/static_assert.hpp>
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 2
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9
+#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
+#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
namespace allocator_traits_detail {
-}
+BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size)
+BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction)
-#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+} //namespace allocator_traits_detail {
namespace container_detail {
//workaround needed for C++03 compilers with no construct()
//supporting rvalue references
-template<class A>
+template<class Allocator>
struct is_std_allocator
{ static const bool value = false; };
@@ -57,56 +96,77 @@ template<class T>
struct is_std_allocator< std::allocator<T> >
{ static const bool value = true; };
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
+BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
+BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_void_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_always_equal)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_partially_propagable)
+
} //namespace container_detail {
#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
-template <typename Alloc>
+template <typename Allocator>
struct allocator_traits
{
//allocator_type
- typedef Alloc allocator_type;
+ typedef Allocator allocator_type;
//value_type
- typedef typename Alloc::value_type value_type;
+ typedef typename allocator_type::value_type value_type;
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! Alloc::pointer if such a type exists; otherwise, value_type*
+ //! Allocator::pointer if such a type exists; otherwise, value_type*
//!
typedef unspecified pointer;
- //! Alloc::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
+ //! Allocator::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
//!
typedef see_documentation const_pointer;
//! Non-standard extension
- //! Alloc::reference if such a type exists; otherwise, value_type&
+ //! Allocator::reference if such a type exists; otherwise, value_type&
typedef see_documentation reference;
//! Non-standard extension
- //! Alloc::const_reference if such a type exists ; otherwise, const value_type&
+ //! Allocator::const_reference if such a type exists ; otherwise, const value_type&
typedef see_documentation const_reference;
- //! Alloc::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
+ //! Allocator::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
//!
typedef see_documentation void_pointer;
- //! Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
+ //! Allocator::const_void_pointer if such a type exists ; otherwis e, pointer_traits<pointer>::rebind<const
//!
typedef see_documentation const_void_pointer;
- //! Alloc::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
+ //! Allocator::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
//!
typedef see_documentation difference_type;
- //! Alloc::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
+ //! Allocator::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
//!
typedef see_documentation size_type;
- //! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant
- //! type with internal constant static member <code>value</code> == false.
+ //! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type
+ //! with an internal constant static boolean 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 <code>value</code> == false.
+ //! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise a type
+ //! with an internal constant static boolean 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 <code>value</code> == false.
+ //! Allocator::propagate_on_container_swap if such a type exists, otherwise a type
+ //! with an internal constant static boolean 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
+ //! Allocator::is_always_equal if such a type exists, otherwise a type
+ //! with an internal constant static boolean member <code>value</code> == is_empty<Allocator>::value
+ typedef see_documentation is_always_equal;
+ //! Allocator::is_partially_propagable if such a type exists, otherwise a type
+ //! with an internal constant static boolean member <code>value</code> == false
+ //! <b>Note</b>: Non-standard extension used to implement `small_vector_allocator`.
+ typedef see_documentation is_partially_propagable;
+ //! Defines an allocator: Allocator::rebind<T>::other if such a type exists; otherwise, Allocator<T, Args>
+ //! if Allocator is a class template instantiation of the form Allocator<U, Args>, where Args is zero or
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
//!
//! In C++03 compilers <code>rebind_alloc</code> is a struct derived from an allocator
@@ -119,114 +179,121 @@ struct allocator_traits
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
- //! <code>type</code> is an allocator related to Alloc deduced deduced by rules explained in <code>rebind_alloc</code>.
+ //! <code>type</code> is an allocator related to Allocator deduced deduced by rules explained in <code>rebind_alloc</code>.
template <class T>
struct portable_rebind_alloc
{ typedef see_documentation type; };
#else
//pointer
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
pointer, value_type*)
pointer;
//const_pointer
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const value_type>)
const_pointer;
//reference
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
reference, typename container_detail::unvoid<value_type>::type&)
reference;
//const_reference
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
const_reference, const typename container_detail::unvoid<value_type>::type&)
const_reference;
//void_pointer
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<void>)
void_pointer;
//const_void_pointer
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Allocator,
const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
rebind_pointer<const void>)
const_void_pointer;
//difference_type
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
difference_type, std::ptrdiff_t)
difference_type;
//size_type
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
size_type, std::size_t)
size_type;
//propagate_on_container_copy_assignment
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
propagate_on_container_copy_assignment, container_detail::false_type)
propagate_on_container_copy_assignment;
//propagate_on_container_move_assignment
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
propagate_on_container_move_assignment, container_detail::false_type)
propagate_on_container_move_assignment;
//propagate_on_container_swap
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
propagate_on_container_swap, container_detail::false_type)
propagate_on_container_swap;
-
+ //is_always_equal
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
+ is_always_equal, container_detail::is_empty<Allocator>)
+ is_always_equal;
+ //is_partially_propagable
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Allocator,
+ is_partially_propagable, container_detail::false_type)
+ is_partially_propagable;
+
+ //rebind_alloc & rebind_traits
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//C++11
- template <typename T> using rebind_alloc = typename boost::intrusive::pointer_rebind<Alloc, T>::type;
+ template <typename T> using rebind_alloc = typename boost::intrusive::pointer_rebind<Allocator, T>::type;
template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
#else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//Some workaround for C++03 or C++11 compilers with no template aliases
template <typename T>
- struct rebind_alloc : boost::intrusive::pointer_rebind<Alloc,T>::type
+ struct rebind_alloc : boost::intrusive::pointer_rebind<Allocator,T>::type
{
- typedef typename boost::intrusive::pointer_rebind<Alloc,T>::type Base;
+ typedef typename boost::intrusive::pointer_rebind<Allocator,T>::type Base;
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- template <typename... Args>
- rebind_alloc(BOOST_FWD_REF(Args)... args)
- : Base(boost::forward<Args>(args)...)
- {}
+ template <typename... Args>
+ rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward<Args>(args)...) {}
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
+ explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC)
+ #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
};
template <typename T>
struct rebind_traits
- : allocator_traits<typename boost::intrusive::pointer_rebind<Alloc, T>::type>
+ : allocator_traits<typename boost::intrusive::pointer_rebind<Allocator, T>::type>
{};
#endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+
+ //portable_rebind_alloc
template <class T>
struct portable_rebind_alloc
- { typedef typename boost::intrusive::pointer_rebind<Alloc, T>::type type; };
+ { typedef typename boost::intrusive::pointer_rebind<Allocator, T>::type type; };
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>: <code>a.allocate(n)</code>
//!
- static pointer allocate(Alloc &a, size_type n)
+ static pointer allocate(Allocator &a, size_type n)
{ return a.allocate(n); }
//! <b>Returns</b>: <code>a.deallocate(p, n)</code>
//!
//! <b>Throws</b>: Nothing
- static void deallocate(Alloc &a, pointer p, size_type n)
+ static void deallocate(Allocator &a, pointer p, size_type n)
{ a.deallocate(p, 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)
+ static pointer allocate(Allocator &a, size_type n, const_void_pointer p)
{
const bool value = boost::container::container_detail::
has_member_function_callable_with_allocate
- <Alloc, const size_type, const const_void_pointer>::value;
+ <Allocator, const size_type, const const_void_pointer>::value;
container_detail::bool_<value> flag;
return allocator_traits::priv_allocate(flag, a, n, p);
}
@@ -234,46 +301,35 @@ struct allocator_traits
//! <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) BOOST_CONTAINER_NOEXCEPT
+ static void destroy(Allocator &a, T*p) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef T* destroy_pointer;
const bool value = boost::container::container_detail::
has_member_function_callable_with_destroy
- <Alloc, const destroy_pointer>::value;
+ <Allocator, const destroy_pointer>::value;
container_detail::bool_<value> flag;
allocator_traits::priv_destroy(flag, a, p);
}
//! <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
+ static size_type max_size(const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
{
- const bool value = boost::container::container_detail::
- has_member_function_callable_with_max_size
- <const Alloc>::value;
+ const bool value = allocator_traits_detail::has_max_size<Allocator, size_type (Allocator::*)() const>::value;
container_detail::bool_<value> flag;
return allocator_traits::priv_max_size(flag, a);
}
//! <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)
- typename container_detail::if_c
- < boost::container::container_detail::
- has_member_function_callable_with_select_on_container_copy_construction
- <const Alloc>::value
- , Alloc
- , const Alloc &
- >::type
- #else
- Alloc
- #endif
- select_on_container_copy_construction(const Alloc &a)
+ static BOOST_CONTAINER_DOC1ST(Allocator,
+ typename container_detail::if_c
+ < allocator_traits_detail::has_select_on_container_copy_construction<Allocator BOOST_MOVE_I Allocator (Allocator::*)() const>::value
+ BOOST_MOVE_I Allocator BOOST_MOVE_I const Allocator & >::type)
+ select_on_container_copy_construction(const Allocator &a)
{
- const bool value = boost::container::container_detail::
- has_member_function_callable_with_select_on_container_copy_construction
- <const Alloc>::value;
+ const bool value = allocator_traits_detail::has_select_on_container_copy_construction
+ <Allocator, Allocator (Allocator::*)() const>::value;
container_detail::bool_<value> flag;
return allocator_traits::priv_select_on_container_copy_construction(flag, a);
}
@@ -282,123 +338,149 @@ struct allocator_traits
//! <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)
+ static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args)
{
- container_detail::bool_<container_detail::is_std_allocator<Alloc>::value> flag;
+ container_detail::bool_<container_detail::is_std_allocator<Allocator>::value> flag;
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
}
#endif
- #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+ //! <b>Returns</b>: <code>a.storage_is_unpropagable(p)</code> if is_partially_propagable::value is true; otherwise,
+ //! <code>false</code>.
+ static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ container_detail::bool_<is_partially_propagable::value> flag;
+ return allocator_traits::priv_storage_is_unpropagable(flag, a, p);
+ }
+
+ //! <b>Returns</b>: <code>true</code> if <code>is_always_equal::value == true</code>, otherwise,
+ //! <code>a == b</code>.
+ static bool equal(const Allocator &a, const Allocator &b) BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ container_detail::bool_<is_always_equal::value> flag;
+ return allocator_traits::priv_equal(flag, a, b);
+ }
+
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- private:
- static pointer priv_allocate(container_detail::true_type, Alloc &a, size_type n, const_void_pointer p)
- { return a.allocate(n, p); }
+ private:
+ static pointer priv_allocate(container_detail::true_type, Allocator &a, size_type n, const_void_pointer p)
+ { return a.allocate(n, p); }
- static pointer priv_allocate(container_detail::false_type, Alloc &a, size_type n, const_void_pointer)
- { return allocator_traits::allocate(a, n); }
+ static pointer priv_allocate(container_detail::false_type, Allocator &a, size_type n, const_void_pointer)
+ { return a.allocate(n); }
- template<class T>
- static void priv_destroy(container_detail::true_type, Alloc &a, T* p) BOOST_CONTAINER_NOEXCEPT
- { a.destroy(p); }
+ template<class T>
+ static void priv_destroy(container_detail::true_type, Allocator &a, T* p) BOOST_NOEXCEPT_OR_NOTHROW
+ { a.destroy(p); }
- template<class T>
- static void priv_destroy(container_detail::false_type, Alloc &, T* p) BOOST_CONTAINER_NOEXCEPT
- { p->~T(); (void)p; }
+ template<class T>
+ static void priv_destroy(container_detail::false_type, Allocator &, T* p) BOOST_NOEXCEPT_OR_NOTHROW
+ { p->~T(); (void)p; }
- static size_type priv_max_size(container_detail::true_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
- { return a.max_size(); }
+ static size_type priv_max_size(container_detail::true_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
+ { return a.max_size(); }
- static size_type priv_max_size(container_detail::false_type, const Alloc &) BOOST_CONTAINER_NOEXCEPT
- { return size_type(-1); }
+ static size_type priv_max_size(container_detail::false_type, const Allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ { return size_type(-1)/sizeof(value_type); }
- static Alloc priv_select_on_container_copy_construction(container_detail::true_type, const Alloc &a)
- { return a.select_on_container_copy_construction(); }
+ static Allocator priv_select_on_container_copy_construction(container_detail::true_type, const Allocator &a)
+ { return a.select_on_container_copy_construction(); }
- static const Alloc &priv_select_on_container_copy_construction(container_detail::false_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT
- { return a; }
+ static const Allocator &priv_select_on_container_copy_construction(container_detail::false_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW
+ { return a; }
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- template<class T, class ...Args>
- static void priv_construct(container_detail::false_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
- {
- const bool value = boost::container::container_detail::
- has_member_function_callable_with_construct
- < Alloc, T*, Args... >::value;
- container_detail::bool_<value> flag;
- priv_construct_dispatch2(flag, a, p, ::boost::forward<Args>(args)...);
- }
-
- template<class T, class ...Args>
- static void priv_construct(container_detail::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
- {
- priv_construct_dispatch2(container_detail::false_type(), a, p, ::boost::forward<Args>(args)...);
- }
-
- template<class T, class ...Args>
- static void priv_construct_dispatch2(container_detail::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
- { a.construct( p, ::boost::forward<Args>(args)...); }
-
- template<class T, class ...Args>
- static void priv_construct_dispatch2(container_detail::false_type, Alloc &, T *p, BOOST_FWD_REF(Args) ...args)
- { ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); }
- #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- public:
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
- static void construct(Alloc &a, T *p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- container_detail::bool_ \
- <container_detail::is_std_allocator<Alloc>::value> flag; \
- allocator_traits::priv_construct(flag, a, p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- //
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- private:
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
- static void priv_construct(container_detail::false_type, Alloc &a, T *p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
- { \
- const bool value = \
- boost::container::container_detail::has_member_function_callable_with_construct \
- < Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value; \
- container_detail::bool_<value> flag; \
- priv_construct_dispatch2(flag, a, p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- } \
- \
- template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
- static void priv_construct(container_detail::true_type, Alloc &a, T *p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
- { \
- priv_construct_dispatch2(container_detail::false_type(), a, p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- } \
- \
- template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
- static void priv_construct_dispatch2(container_detail::true_type, Alloc &a, T *p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_)) \
- { a.construct( p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); } \
- \
- template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
- static void priv_construct_dispatch2(container_detail::false_type, Alloc &, T *p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
- { ::new((void*)p, boost_container_new_t()) T(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\
- //
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
- #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- template<class T>
- static void priv_construct_dispatch2(container_detail::false_type, Alloc &, T *p, ::boost::container::default_init_t)
- { ::new((void*)p) T; }
- #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template<class T, class ...Args>
+ static void priv_construct(container_detail::false_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
+ {
+ const bool value = boost::container::container_detail::
+ has_member_function_callable_with_construct
+ < Allocator, T*, Args... >::value;
+ container_detail::bool_<value> flag;
+ (priv_construct_dispatch_next)(flag, a, p, ::boost::forward<Args>(args)...);
+ }
+
+ template<class T, class ...Args>
+ static void priv_construct(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
+ { (priv_construct_dispatch_next)(container_detail::false_type(), a, p, ::boost::forward<Args>(args)...); }
+
+ template<class T, class ...Args>
+ static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args)
+ { a.construct( p, ::boost::forward<Args>(args)...); }
+
+ template<class T, class ...Args>
+ static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args)
+ { ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); }
+ #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ public:
+
+ #define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \
+ template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+ static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ container_detail::bool_<container_detail::is_std_allocator<Allocator>::value> flag;\
+ (priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL)
+ #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL
+
+ private:
+
+ //////////////////
+ // priv_construct
+ //////////////////
+ #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \
+ template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+ static void priv_construct(container_detail::false_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ const bool value = boost::container::container_detail::has_member_function_callable_with_construct\
+ < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N>::value;\
+ container_detail::bool_<value> flag;\
+ (priv_construct_dispatch_next)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ }\
+ \
+ template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+ static void priv_construct(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { (priv_construct_dispatch_next)(container_detail::false_type(), a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+ //
+ BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL)
+ #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL
+
+ /////////////////////////////////
+ // priv_construct_dispatch_next
+ /////////////////////////////////
+ #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL(N) \
+ template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+ static void priv_construct_dispatch_next(container_detail::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\
+ \
+ template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+ static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\
+ //
+ BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL)
+ #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_DISPATCH_NEXT_IMPL
+
+ #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ template<class T>
+ static void priv_construct_dispatch_next(container_detail::false_type, Allocator &, T *p, const ::boost::container::default_init_t&)
+ { ::new((void*)p) T; }
+
+ static bool priv_storage_is_unpropagable(container_detail::true_type, const Allocator &a, pointer p)
+ { return a.storage_is_unpropagable(p); }
+
+ static bool priv_storage_is_unpropagable(container_detail::false_type, const Allocator &, pointer)
+ { return false; }
- #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ static bool priv_equal(container_detail::true_type, const Allocator &, const Allocator &)
+ { return true; }
+
+ static bool priv_equal(container_detail::false_type, const Allocator &a, const Allocator &b)
+ { return a == b; }
+
+ #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
};
} //namespace container {
diff --git a/boost/container/container_fwd.hpp b/boost/container/container_fwd.hpp
index 20ac77861d..a9b421c2b2 100644
--- a/boost/container/container_fwd.hpp
+++ b/boost/container/container_fwd.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
#define BOOST_CONTAINER_CONTAINER_FWD_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -80,27 +84,34 @@ enum tree_type_enum
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+template<class T>
+class new_allocator;
+
template <class T
- ,class Allocator = std::allocator<T> >
+ ,class Allocator = new_allocator<T> >
class vector;
template <class T
- ,class Allocator = std::allocator<T> >
+ ,class Allocator = new_allocator<T> >
class stable_vector;
template <class T, std::size_t Capacity>
class static_vector;
+template < class T, std::size_t N
+ , class Allocator= new_allocator<T> >
+class small_vector;
+
template <class T
- ,class Allocator = std::allocator<T> >
+ ,class Allocator = new_allocator<T> >
class deque;
template <class T
- ,class Allocator = std::allocator<T> >
+ ,class Allocator = new_allocator<T> >
class list;
template <class T
- ,class Allocator = std::allocator<T> >
+ ,class Allocator = new_allocator<T> >
class slist;
template<tree_type_enum TreeType, bool OptimizeSize>
@@ -110,67 +121,67 @@ typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
template <class Key
,class Compare = std::less<Key>
- ,class Allocator = std::allocator<Key>
+ ,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults >
class set;
template <class Key
,class Compare = std::less<Key>
- ,class Allocator = std::allocator<Key>
+ ,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults >
class multiset;
template <class Key
,class T
,class Compare = std::less<Key>
- ,class Allocator = std::allocator<std::pair<const Key, T> >
+ ,class Allocator = new_allocator<std::pair<const Key, T> >
,class Options = tree_assoc_defaults >
class map;
template <class Key
,class T
,class Compare = std::less<Key>
- ,class Allocator = std::allocator<std::pair<const Key, T> >
+ ,class Allocator = new_allocator<std::pair<const Key, T> >
,class Options = tree_assoc_defaults >
class multimap;
template <class Key
,class Compare = std::less<Key>
- ,class Allocator = std::allocator<Key> >
+ ,class Allocator = new_allocator<Key> >
class flat_set;
template <class Key
,class Compare = std::less<Key>
- ,class Allocator = std::allocator<Key> >
+ ,class Allocator = new_allocator<Key> >
class flat_multiset;
template <class Key
,class T
,class Compare = std::less<Key>
- ,class Allocator = std::allocator<std::pair<Key, T> > >
+ ,class Allocator = new_allocator<std::pair<Key, T> > >
class flat_map;
template <class Key
,class T
,class Compare = std::less<Key>
- ,class Allocator = std::allocator<std::pair<Key, T> > >
+ ,class Allocator = new_allocator<std::pair<Key, T> > >
class flat_multimap;
template <class CharT
,class Traits = std::char_traits<CharT>
- ,class Allocator = std::allocator<CharT> >
+ ,class Allocator = new_allocator<CharT> >
class basic_string;
typedef basic_string
<char
,std::char_traits<char>
- ,std::allocator<char> >
+ ,new_allocator<char> >
string;
typedef basic_string
<wchar_t
,std::char_traits<wchar_t>
- ,std::allocator<wchar_t> >
+ ,new_allocator<wchar_t> >
wstring;
static const std::size_t ADP_nodes_per_block = 256u;
diff --git a/boost/container/deque.hpp b/boost/container/deque.hpp
index d8a546c86f..eb372a430a 100644
--- a/boost/container/deque.hpp
+++ b/boost/container/deque.hpp
@@ -7,42 +7,51 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#ifndef BOOST_CONTAINER_DEQUE_HPP
#define BOOST_CONTAINER_DEQUE_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-
-#include <boost/container/detail/utilities.hpp>
-#include <boost/container/detail/iterators.hpp>
-#include <boost/container/detail/algorithms.hpp>
-#include <boost/container/detail/mpl.hpp>
+// container
#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
-#include <cstddef>
-#include <iterator>
-#include <boost/assert.hpp>
-#include <memory>
-#include <algorithm>
-#include <boost/core/no_exceptions_support.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/type_traits/has_trivial_copy.hpp>
-#include <boost/type_traits/has_trivial_assign.hpp>
-#include <boost/type_traits/has_nothrow_copy.hpp>
-#include <boost/type_traits/has_nothrow_assign.hpp>
-#include <boost/move/utility_core.hpp>
+// container/detail
+#include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/alloc_helpers.hpp>
+#include <boost/container/detail/copy_move_algo.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/min_max.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// move
+#include <boost/move/adl_move_swap.hpp>
#include <boost/move/iterator.hpp>
-#include <boost/move/algorithm.hpp>
-#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
-#include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// other
+#include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
+// std
+#include <cstddef>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
@@ -59,13 +68,8 @@ template <class T>
struct deque_value_traits
{
typedef T value_type;
- static const bool trivial_dctr = boost::has_trivial_destructor<value_type>::value;
+ static const bool trivial_dctr = container_detail::is_trivially_destructible<value_type>::value;
static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<value_type>::value;
- static const bool trivial_copy = has_trivial_copy<value_type>::value;
- static const bool nothrow_copy = has_nothrow_copy<value_type>::value;
- static const bool trivial_assign = has_trivial_assign<value_type>::value;
- //static const bool nothrow_assign = has_nothrow_assign<value_type>::value;
- static const bool nothrow_assign = false;
};
// Note: this function is simply a kludge to work around several compilers'
@@ -102,7 +106,7 @@ namespace container_detail {
// [map, map + map_size) is a valid, non-empty range.
// [start.node, finish.node] is a valid range contained within
// [map, map + map_size).
-// Allocator pointer in the range [map, map + map_size) points to an allocated node
+// A pointer in the range [map, map + map_size) points to an allocated node
// if and only if the pointer is in the range [start.node, finish.node].
template<class Pointer, bool IsConst>
class deque_iterator
@@ -142,34 +146,34 @@ class deque_iterator
Pointer get_last() const { return m_last; }
index_pointer get_node() const { return m_node; }
- deque_iterator(val_alloc_ptr x, index_pointer y) BOOST_CONTAINER_NOEXCEPT
+ deque_iterator(val_alloc_ptr x, index_pointer y) BOOST_NOEXCEPT_OR_NOTHROW
: m_cur(x), m_first(*y), m_last(*y + s_buffer_size()), m_node(y)
{}
- deque_iterator() BOOST_CONTAINER_NOEXCEPT
+ deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
: m_cur(), m_first(), m_last(), m_node() //Value initialization to achieve "null iterators" (N3644)
{}
- deque_iterator(deque_iterator<Pointer, false> const& x) BOOST_CONTAINER_NOEXCEPT
+ deque_iterator(deque_iterator<Pointer, false> const& x) BOOST_NOEXCEPT_OR_NOTHROW
: m_cur(x.get_cur()), m_first(x.get_first()), m_last(x.get_last()), m_node(x.get_node())
{}
- deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_CONTAINER_NOEXCEPT
+ deque_iterator(Pointer cur, Pointer first, Pointer last, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
: m_cur(cur), m_first(first), m_last(last), m_node(node)
{}
- deque_iterator<Pointer, false> unconst() const BOOST_CONTAINER_NOEXCEPT
+ deque_iterator<Pointer, false> unconst() const BOOST_NOEXCEPT_OR_NOTHROW
{
return deque_iterator<Pointer, false>(this->get_cur(), this->get_first(), this->get_last(), this->get_node());
}
- reference operator*() const BOOST_CONTAINER_NOEXCEPT
+ reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->m_cur; }
- pointer operator->() const BOOST_CONTAINER_NOEXCEPT
+ pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->m_cur; }
- difference_type operator-(const deque_iterator& x) const BOOST_CONTAINER_NOEXCEPT
+ difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
{
if(!this->m_cur && !x.m_cur){
return 0;
@@ -178,7 +182,7 @@ class deque_iterator
(this->m_cur - this->m_first) + (x.m_last - x.m_cur);
}
- deque_iterator& operator++() BOOST_CONTAINER_NOEXCEPT
+ deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
{
++this->m_cur;
if (this->m_cur == this->m_last) {
@@ -188,14 +192,14 @@ class deque_iterator
return *this;
}
- deque_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
+ deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
{
deque_iterator tmp(*this);
++*this;
return tmp;
}
- deque_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
+ deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
{
if (this->m_cur == this->m_first) {
this->priv_set_node(this->m_node - 1);
@@ -205,14 +209,14 @@ class deque_iterator
return *this;
}
- deque_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
+ deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
{
deque_iterator tmp(*this);
--*this;
return tmp;
}
- deque_iterator& operator+=(difference_type n) BOOST_CONTAINER_NOEXCEPT
+ deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
{
difference_type offset = n + (this->m_cur - this->m_first);
if (offset >= 0 && offset < difference_type(this->s_buffer_size()))
@@ -228,44 +232,44 @@ class deque_iterator
return *this;
}
- deque_iterator operator+(difference_type n) const BOOST_CONTAINER_NOEXCEPT
+ deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{ deque_iterator tmp(*this); return tmp += n; }
- deque_iterator& operator-=(difference_type n) BOOST_CONTAINER_NOEXCEPT
+ deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ return *this += -n; }
- deque_iterator operator-(difference_type n) const BOOST_CONTAINER_NOEXCEPT
+ deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{ deque_iterator tmp(*this); return tmp -= n; }
- reference operator[](difference_type n) const BOOST_CONTAINER_NOEXCEPT
+ reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{ return *(*this + n); }
- friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_cur == r.m_cur; }
- friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_cur != r.m_cur; }
- friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
- friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return r < l; }
- friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return !(r < l); }
- friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return !(l < r); }
- void priv_set_node(index_pointer new_node) BOOST_CONTAINER_NOEXCEPT
+ void priv_set_node(index_pointer new_node) BOOST_NOEXCEPT_OR_NOTHROW
{
this->m_node = new_node;
this->m_first = *new_node;
this->m_last = this->m_first + this->s_buffer_size();
}
- friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_CONTAINER_NOEXCEPT
+ friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
{ return x += n; }
};
@@ -304,19 +308,19 @@ class deque_base
typedef deque_value_traits<val_alloc_val> traits_t;
typedef ptr_alloc_t map_allocator_type;
- static size_type s_buffer_size() BOOST_CONTAINER_NOEXCEPT
+ static size_type s_buffer_size() BOOST_NOEXCEPT_OR_NOTHROW
{ return deque_buf_size<val_alloc_val>::value; }
val_alloc_ptr priv_allocate_node()
{ return this->alloc().allocate(s_buffer_size()); }
- void priv_deallocate_node(val_alloc_ptr p) BOOST_CONTAINER_NOEXCEPT
+ void priv_deallocate_node(val_alloc_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
{ this->alloc().deallocate(p, s_buffer_size()); }
ptr_alloc_ptr priv_allocate_map(size_type n)
{ return this->ptr_alloc().allocate(n); }
- void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_CONTAINER_NOEXCEPT
+ void priv_deallocate_map(ptr_alloc_ptr p, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ this->ptr_alloc().deallocate(p, n); }
typedef container_detail::deque_iterator<val_alloc_ptr, false> iterator;
@@ -352,12 +356,12 @@ class deque_base
protected:
- void swap_members(deque_base &x) BOOST_CONTAINER_NOEXCEPT
+ void swap_members(deque_base &x) BOOST_NOEXCEPT_OR_NOTHROW
{
- std::swap(this->members_.m_start, x.members_.m_start);
- std::swap(this->members_.m_finish, x.members_.m_finish);
- std::swap(this->members_.m_map, x.members_.m_map);
- std::swap(this->members_.m_map_size, x.members_.m_map_size);
+ ::boost::adl_move_swap(this->members_.m_start, x.members_.m_start);
+ ::boost::adl_move_swap(this->members_.m_finish, x.members_.m_finish);
+ ::boost::adl_move_swap(this->members_.m_map, x.members_.m_map);
+ ::boost::adl_move_swap(this->members_.m_map_size, x.members_.m_map_size);
}
void priv_initialize_map(size_type num_elements)
@@ -392,9 +396,9 @@ class deque_base
void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
{
- ptr_alloc_ptr cur;
+ ptr_alloc_ptr cur = nstart;
BOOST_TRY {
- for (cur = nstart; cur < nfinish; ++cur)
+ for (; cur < nfinish; ++cur)
*cur = this->priv_allocate_node();
}
BOOST_CATCH(...){
@@ -404,13 +408,13 @@ class deque_base
BOOST_CATCH_END
}
- void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_CONTAINER_NOEXCEPT
+ void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish) BOOST_NOEXCEPT_OR_NOTHROW
{
for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
this->priv_deallocate_node(*n);
}
- void priv_clear_map() BOOST_CONTAINER_NOEXCEPT
+ void priv_clear_map() BOOST_NOEXCEPT_OR_NOTHROW
{
if (this->members_.m_map) {
this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
@@ -455,16 +459,16 @@ class deque_base
iterator m_finish;
} members_;
- ptr_alloc_t &ptr_alloc() BOOST_CONTAINER_NOEXCEPT
+ ptr_alloc_t &ptr_alloc() BOOST_NOEXCEPT_OR_NOTHROW
{ return members_; }
- const ptr_alloc_t &ptr_alloc() const BOOST_CONTAINER_NOEXCEPT
+ const ptr_alloc_t &ptr_alloc() const BOOST_NOEXCEPT_OR_NOTHROW
{ return members_; }
- allocator_type &alloc() BOOST_CONTAINER_NOEXCEPT
+ allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW
{ return members_; }
- const allocator_type &alloc() const BOOST_CONTAINER_NOEXCEPT
+ const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
{ return members_; }
};
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -475,7 +479,7 @@ class deque_base
//!
//! \tparam T The type of object that is stored in the deque
//! \tparam Allocator The allocator used for all internal memory management
-template <class T, class Allocator = std::allocator<T> >
+template <class T, class Allocator = new_allocator<T> >
#else
template <class T, class Allocator>
#endif
@@ -505,8 +509,8 @@ class deque : protected deque_base<Allocator>
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(typename Base::iterator) iterator;
typedef BOOST_CONTAINER_IMPDEF(typename Base::const_iterator) const_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -540,11 +544,11 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit deque(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
+ explicit deque(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
: Base(a)
{}
- //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+ //! <b>Effects</b>: Constructs a deque
//! and inserts n value initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor
@@ -559,7 +563,7 @@ class deque : protected deque_base<Allocator>
//deque_base will deallocate in case of exception...
}
- //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+ //! <b>Effects</b>: Constructs a deque
//! and inserts n default initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor
@@ -577,6 +581,38 @@ class deque : protected deque_base<Allocator>
}
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+ //! and inserts n value initialized values.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor
+ //! throws or T's value initialization throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ explicit deque(size_type n, const allocator_type &a)
+ : Base(n, a)
+ {
+ 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...
+ }
+
+ //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
+ //! and inserts n default initialized values.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor
+ //! throws or T's default initialization or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ deque(size_type n, default_init_t, const allocator_type &a)
+ : Base(n, a)
+ {
+ 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...
+ }
+
+ //! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
//! and inserts n copies of value.
//!
//! <b>Throws</b>: If allocator_type's default constructor
@@ -605,8 +641,7 @@ class deque : protected deque_base<Allocator>
)
: Base(a)
{
- typedef typename std::iterator_traits<InIt>::iterator_category ItCat;
- this->priv_range_initialize(first, last, ItCat());
+ this->priv_range_initialize(first, last);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -620,7 +655,7 @@ class deque : protected deque_base<Allocator>
deque(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
: Base(a)
{
- this->priv_range_initialize(il.begin(), il.end(), std::input_iterator_tag());
+ this->priv_range_initialize(il.begin(), il.end());
}
#endif
@@ -639,13 +674,13 @@ class deque : protected deque_base<Allocator>
}
}
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
deque(BOOST_RV_REF(deque) x)
- : Base(boost::move(static_cast<Base&>(x)))
+ : Base(BOOST_MOVE_BASE(Base, x))
{ this->swap_members(x); }
//! <b>Effects</b>: Copy constructs a vector using the specified allocator.
@@ -667,23 +702,24 @@ class deque : protected deque_base<Allocator>
}
//! <b>Effects</b>: Move constructor using the specified allocator.
- //! Moves mx's resources to *this if a == allocator_type().
+ //! Moves x's resources to *this if a == allocator_type().
//! Otherwise copies values from x to *this.
//!
//! <b>Throws</b>: If allocation or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
- deque(BOOST_RV_REF(deque) mx, const allocator_type &a)
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
+ deque(BOOST_RV_REF(deque) x, const allocator_type &a)
: Base(a)
{
- if(mx.alloc() == a){
- this->swap_members(mx);
+ if(x.alloc() == a){
+ this->swap_members(x);
}
else{
- if(mx.size()){
- this->priv_initialize_map(mx.size());
+ if(x.size()){
+ this->priv_initialize_map(x.size());
boost::container::uninitialized_copy_alloc
- (this->alloc(), mx.begin(), mx.end(), this->members_.m_start);
+ ( this->alloc(), boost::make_move_iterator(x.begin())
+ , boost::make_move_iterator(x.end()), this->members_.m_start);
}
}
}
@@ -694,7 +730,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements.
- ~deque() BOOST_CONTAINER_NOEXCEPT
+ ~deque() BOOST_NOEXCEPT_OR_NOTHROW
{
this->priv_destroy_range(this->members_.m_start, this->members_.m_finish);
}
@@ -734,7 +770,8 @@ class deque : protected deque_base<Allocator>
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
deque& operator= (BOOST_RV_REF(deque) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+ || allocator_traits_type::is_always_equal::value)
{
BOOST_ASSERT(this != &x);
allocator_type &this_alloc = this->alloc();
@@ -826,10 +863,10 @@ class deque : protected deque_base<Allocator>
>::type * = 0
)
{
- const size_type len = std::distance(first, last);
+ const size_type len = boost::container::iterator_distance(first, last);
if (len > size()) {
FwdIt mid = first;
- std::advance(mid, this->size());
+ boost::container::iterator_advance(mid, this->size());
boost::container::copy(first, mid, begin());
this->insert(this->cend(), mid, last);
}
@@ -855,7 +892,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return Base::alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -865,7 +902,7 @@ class deque : protected deque_base<Allocator>
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return Base::alloc(); }
//////////////////////////////////////////////
@@ -881,7 +918,7 @@ class deque : protected deque_base<Allocator>
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return Base::alloc(); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the deque.
@@ -889,7 +926,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_start; }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
@@ -897,7 +934,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_start; }
//! <b>Effects</b>: Returns an iterator to the end of the deque.
@@ -905,7 +942,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_finish; }
//! <b>Effects</b>: Returns a const_iterator to the end of the deque.
@@ -913,7 +950,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_finish; }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -922,7 +959,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(this->members_.m_finish); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -931,7 +968,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->members_.m_finish); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -940,7 +977,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(this->members_.m_start); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -949,7 +986,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->members_.m_start); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the deque.
@@ -957,7 +994,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_start; }
//! <b>Effects</b>: Returns a const_iterator to the end of the deque.
@@ -965,7 +1002,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_finish; }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -974,7 +1011,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->members_.m_finish); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -983,7 +1020,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->members_.m_start); }
//////////////////////////////////////////////
@@ -997,7 +1034,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_finish == this->members_.m_start; }
//! <b>Effects</b>: Returns the number of the elements contained in the deque.
@@ -1005,7 +1042,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_finish - this->members_.m_start; }
//! <b>Effects</b>: Returns the largest possible size of the deque.
@@ -1013,7 +1050,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return allocator_traits_type::max_size(this->alloc()); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -1100,7 +1137,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference front() BOOST_CONTAINER_NOEXCEPT
+ reference front() BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->members_.m_start; }
//! <b>Requires</b>: !empty()
@@ -1111,7 +1148,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference front() const BOOST_CONTAINER_NOEXCEPT
+ const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->members_.m_start; }
//! <b>Requires</b>: !empty()
@@ -1122,7 +1159,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference back() BOOST_CONTAINER_NOEXCEPT
+ reference back() BOOST_NOEXCEPT_OR_NOTHROW
{ return *(end()-1); }
//! <b>Requires</b>: !empty()
@@ -1133,7 +1170,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference back() const BOOST_CONTAINER_NOEXCEPT
+ const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *(cend()-1); }
//! <b>Requires</b>: size() > n.
@@ -1144,7 +1181,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
+ reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_start[difference_type(n)]; }
//! <b>Requires</b>: size() > n.
@@ -1155,9 +1192,70 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
+ const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->members_.m_start[difference_type(n)]; }
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns an iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->size() >= n);
+ return iterator(this->begin()+n);
+ }
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns a const_iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->size() >= n);
+ return const_iterator(this->cbegin()+n);
+ }
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns an iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->priv_index_of(p); }
+
+ //! <b>Requires</b>: begin() <= p <= end().
+ //!
+ //! <b>Effects</b>: Returns the index of the element pointed by p
+ //! and size() if p == end().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->priv_index_of(p); }
+
//! <b>Requires</b>: size() > n.
//!
//! <b>Effects</b>: Returns a reference to the nth element
@@ -1186,7 +1284,7 @@ class deque : protected deque_base<Allocator>
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the beginning of the deque.
@@ -1195,7 +1293,7 @@ class deque : protected deque_base<Allocator>
//!
//! <b>Complexity</b>: Amortized constant time
template <class... Args>
- void emplace_front(Args&&... args)
+ void emplace_front(BOOST_FWD_REF(Args)... args)
{
if(this->priv_push_front_simple_available()){
allocator_traits_type::construct
@@ -1205,7 +1303,7 @@ class deque : protected deque_base<Allocator>
this->priv_push_front_simple_commit();
}
else{
- typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
+ typedef container_detail::insert_nonmovable_emplace_proxy<Allocator, iterator, Args...> type;
this->priv_insert_front_aux_impl(1, type(boost::forward<Args>(args)...));
}
}
@@ -1217,7 +1315,7 @@ class deque : protected deque_base<Allocator>
//!
//! <b>Complexity</b>: Amortized constant time
template <class... Args>
- void emplace_back(Args&&... args)
+ void emplace_back(BOOST_FWD_REF(Args)... args)
{
if(this->priv_push_back_simple_available()){
allocator_traits_type::construct
@@ -1227,7 +1325,7 @@ class deque : protected deque_base<Allocator>
this->priv_push_back_simple_commit();
}
else{
- typedef container_detail::insert_non_movable_emplace_proxy<Allocator, iterator, Args...> type;
+ typedef container_detail::insert_nonmovable_emplace_proxy<Allocator, iterator, Args...> type;
this->priv_insert_back_aux_impl(1, type(boost::forward<Args>(args)...));
}
}
@@ -1242,7 +1340,7 @@ class deque : protected deque_base<Allocator>
//! <b>Complexity</b>: If p is end(), amortized constant time
//! Linear time otherwise.
template <class... Args>
- iterator emplace(const_iterator p, Args&&... args)
+ iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
{
if(p == this->cbegin()){
this->emplace_front(boost::forward<Args>(args)...);
@@ -1258,70 +1356,61 @@ class deque : protected deque_base<Allocator>
}
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- //advanced_insert_int.hpp includes all necessary preprocessor machinery...
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, > ) \
- void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- if(priv_push_front_simple_available()){ \
- allocator_traits_type::construct \
- ( this->alloc() \
- , this->priv_push_front_simple_pos() \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- priv_push_front_simple_commit(); \
- } \
- else{ \
- 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, _))); \
- } \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- if(priv_push_back_simple_available()){ \
- allocator_traits_type::construct \
- ( this->alloc() \
- , this->priv_push_back_simple_pos() \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- priv_push_back_simple_commit(); \
- } \
- else{ \
- 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, _))); \
- } \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- if(p == this->cbegin()){ \
- this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- return this->begin(); \
- } \
- else if(p == cend()){ \
- this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- return (this->end()-1); \
- } \
- else{ \
- 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, _))); \
- } \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ #define BOOST_CONTAINER_DEQUE_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
+ void emplace_front(BOOST_MOVE_UREF##N)\
+ {\
+ if(priv_push_front_simple_available()){\
+ allocator_traits_type::construct\
+ ( this->alloc(), this->priv_push_front_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ priv_push_front_simple_commit();\
+ }\
+ else{\
+ typedef container_detail::insert_nonmovable_emplace_proxy##N\
+ <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+ priv_insert_front_aux_impl(1, type(BOOST_MOVE_FWD##N));\
+ }\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
+ void emplace_back(BOOST_MOVE_UREF##N)\
+ {\
+ if(priv_push_back_simple_available()){\
+ allocator_traits_type::construct\
+ ( this->alloc(), this->priv_push_back_simple_pos() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ priv_push_back_simple_commit();\
+ }\
+ else{\
+ typedef container_detail::insert_nonmovable_emplace_proxy##N\
+ <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+ priv_insert_back_aux_impl(1, type(BOOST_MOVE_FWD##N));\
+ }\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
+ iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ if(p == this->cbegin()){\
+ this->emplace_front(BOOST_MOVE_FWD##N);\
+ return this->begin();\
+ }\
+ else if(p == cend()){\
+ this->emplace_back(BOOST_MOVE_FWD##N);\
+ return (--this->end());\
+ }\
+ else{\
+ typedef container_detail::insert_emplace_proxy_arg##N\
+ <Allocator, iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+ return this->priv_insert_aux_impl(p, 1, type(BOOST_MOVE_FWD##N));\
+ }\
+ }
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_DEQUE_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_DEQUE_EMPLACE_CODE
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the front of the deque.
@@ -1333,7 +1422,7 @@ class deque : protected deque_base<Allocator>
void push_front(const T &x);
//! <b>Effects</b>: Constructs a new element in the front of the deque
- //! and moves the resources of mx to this new element.
+ //! and moves the resources of x to this new element.
//!
//! <b>Throws</b>: If memory allocation throws.
//!
@@ -1353,7 +1442,7 @@ class deque : protected deque_base<Allocator>
void push_back(const T &x);
//! <b>Effects</b>: Constructs a new element in the end of the deque
- //! and moves the resources of mx to this new element.
+ //! and moves the resources of x to this new element.
//!
//! <b>Throws</b>: If memory allocation throws.
//!
@@ -1379,7 +1468,7 @@ class deque : protected deque_base<Allocator>
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
- //! <b>Effects</b>: Insert a new element before p with mx's resources.
+ //! <b>Effects</b>: Insert a new element before p with x's resources.
//!
//! <b>Returns</b>: an iterator to the inserted element.
//!
@@ -1416,7 +1505,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InIt throws or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Linear to std::distance [first, last).
+ //! <b>Complexity</b>: Linear to distance [first, last).
template <class InIt>
iterator insert(const_iterator pos, InIt first, InIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1447,7 +1536,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced std::initializer_list throws or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Linear to std::distance [il.begin(), il.end()).
+ //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
iterator insert(const_iterator pos, std::initializer_list<value_type> il)
{ return insert(pos, il.begin(), il.end()); }
#endif
@@ -1464,7 +1553,7 @@ class deque : protected deque_base<Allocator>
)
{
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first);
- return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
+ return priv_insert_aux_impl(p, boost::container::iterator_distance(first, last), proxy);
}
#endif
@@ -1473,7 +1562,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant time.
- void pop_front() BOOST_CONTAINER_NOEXCEPT
+ void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
{
if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
allocator_traits_type::destroy
@@ -1491,7 +1580,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant time.
- void pop_back() BOOST_CONTAINER_NOEXCEPT
+ void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
{
if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
--this->members_.m_finish.m_cur;
@@ -1512,17 +1601,17 @@ class deque : protected deque_base<Allocator>
//! last element (if pos is near the end) or the first element
//! if(pos is near the beginning).
//! Constant if pos is the first or the last element.
- iterator erase(const_iterator pos) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW
{
iterator next = pos.unconst();
++next;
size_type index = pos - this->members_.m_start;
if (index < (this->size()/2)) {
- boost::move_backward(this->begin(), pos.unconst(), next);
+ boost::container::move_backward(this->begin(), pos.unconst(), next);
pop_front();
}
else {
- boost::move(next, this->end(), pos.unconst());
+ boost::container::move(next, this->end(), pos.unconst());
pop_back();
}
return this->members_.m_start + index;
@@ -1536,7 +1625,7 @@ class deque : protected deque_base<Allocator>
//! last plus the elements between pos and the
//! last element (if pos is near the end) or the first element
//! if(pos is near the beginning).
- iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{
if (first == this->members_.m_start && last == this->members_.m_finish) {
this->clear();
@@ -1546,7 +1635,7 @@ class deque : protected deque_base<Allocator>
const size_type n = static_cast<size_type>(last - first);
const size_type elems_before = static_cast<size_type>(first - this->members_.m_start);
if (elems_before < (this->size() - n) - elems_before) {
- boost::move_backward(begin(), first.unconst(), last.unconst());
+ boost::container::move_backward(begin(), first.unconst(), last.unconst());
iterator new_start = this->members_.m_start + n;
if(!Base::traits_t::trivial_dctr_after_move)
this->priv_destroy_range(this->members_.m_start, new_start);
@@ -1554,7 +1643,7 @@ class deque : protected deque_base<Allocator>
this->members_.m_start = new_start;
}
else {
- boost::move(last.unconst(), end(), first.unconst());
+ boost::container::move(last.unconst(), end(), first.unconst());
iterator new_finish = this->members_.m_finish - n;
if(!Base::traits_t::trivial_dctr_after_move)
this->priv_destroy_range(new_finish, this->members_.m_finish);
@@ -1571,6 +1660,8 @@ class deque : protected deque_base<Allocator>
//!
//! <b>Complexity</b>: Constant.
void swap(deque &x)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
+ || allocator_traits_type::is_always_equal::value)
{
this->swap_members(x);
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
@@ -1583,7 +1674,7 @@ class deque : protected deque_base<Allocator>
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements in the deque.
- void clear() BOOST_CONTAINER_NOEXCEPT
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW
{
for (index_pointer node = this->members_.m_start.m_node + 1;
node < this->members_.m_finish.m_node;
@@ -1607,7 +1698,7 @@ class deque : protected deque_base<Allocator>
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator==(const deque& x, const deque& y)
- { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
@@ -1619,7 +1710,7 @@ class deque : protected deque_base<Allocator>
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator<(const deque& x, const deque& y)
- { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+ { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! <b>Effects</b>: Returns true if x is greater than y
//!
@@ -1648,6 +1739,13 @@ class deque : protected deque_base<Allocator>
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
+ size_type priv_index_of(const_iterator p) const
+ {
+ BOOST_ASSERT(this->cbegin() <= p);
+ BOOST_ASSERT(p <= this->cend());
+ return static_cast<size_type>(p - this->cbegin());
+ }
+
void priv_erase_last_n(size_type n)
{
if(n == this->size()) {
@@ -1743,21 +1841,19 @@ class deque : protected deque_base<Allocator>
void priv_destroy_range(iterator p, iterator p2)
{
- for(;p != p2; ++p){
- allocator_traits_type::destroy
- ( this->alloc()
- , container_detail::to_raw_pointer(container_detail::iterator_to_pointer(p))
- );
+ if(!Base::traits_t::trivial_dctr){
+ for(;p != p2; ++p){
+ allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p));
+ }
}
}
void priv_destroy_range(pointer p, pointer p2)
{
- for(;p != p2; ++p){
- allocator_traits_type::destroy
- ( this->alloc()
- , container_detail::to_raw_pointer(container_detail::iterator_to_pointer(p))
- );
+ if(!Base::traits_t::trivial_dctr){
+ for(;p != p2; ++p){
+ allocator_traits_type::destroy(this->alloc(), container_detail::iterator_to_raw_pointer(p));
+ }
}
}
@@ -1787,7 +1883,7 @@ class deque : protected deque_base<Allocator>
::boost::container::uninitialized_move_alloc
(this->alloc(), this->members_.m_start, start_n, new_start);
this->members_.m_start = new_start;
- boost::move(start_n, pos, old_start);
+ boost::container::move(start_n, pos, old_start);
proxy.copy_n_and_update(this->alloc(), pos - n, n);
}
else {
@@ -1817,7 +1913,7 @@ class deque : protected deque_base<Allocator>
::boost::container::uninitialized_move_alloc
(this->alloc(), finish_n, old_finish, old_finish);
this->members_.m_finish = new_finish;
- boost::move_backward(pos, finish_n, old_finish);
+ boost::container::move_backward(pos, finish_n, old_finish);
proxy.copy_n_and_update(this->alloc(), pos, n);
}
else {
@@ -1877,9 +1973,9 @@ class deque : protected deque_base<Allocator>
// but none of the deque's elements have yet been constructed.
void priv_fill_initialize(const value_type& value)
{
- index_pointer cur;
+ index_pointer cur = this->members_.m_start.m_node;
BOOST_TRY {
- for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){
+ for ( ; cur < this->members_.m_finish.m_node; ++cur){
boost::container::uninitialized_fill_alloc
(this->alloc(), *cur, *cur + this->s_buffer_size(), value);
}
@@ -1894,7 +1990,8 @@ class deque : protected deque_base<Allocator>
}
template <class InIt>
- void priv_range_initialize(InIt first, InIt last, std::input_iterator_tag)
+ typename iterator_enable_if_tag<InIt, std::input_iterator_tag>::type
+ priv_range_initialize(InIt first, InIt last)
{
this->priv_initialize_map(0);
BOOST_TRY {
@@ -1909,19 +2006,18 @@ class deque : protected deque_base<Allocator>
}
template <class FwdIt>
- void priv_range_initialize(FwdIt first, FwdIt last, std::forward_iterator_tag)
+ typename iterator_disable_if_tag<FwdIt, std::input_iterator_tag>::type
+ priv_range_initialize(FwdIt first, FwdIt last)
{
size_type n = 0;
- n = std::distance(first, last);
+ n = boost::container::iterator_distance(first, last);
this->priv_initialize_map(n);
- index_pointer cur_node;
+ index_pointer cur_node = this->members_.m_start.m_node;
BOOST_TRY {
- for (cur_node = this->members_.m_start.m_node;
- cur_node < this->members_.m_finish.m_node;
- ++cur_node) {
+ for (; cur_node < this->members_.m_finish.m_node; ++cur_node) {
FwdIt mid = first;
- std::advance(mid, this->s_buffer_size());
+ boost::container::iterator_advance(mid, this->s_buffer_size());
::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
first = mid;
}
@@ -1935,7 +2031,7 @@ class deque : protected deque_base<Allocator>
}
// Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
- void priv_pop_back_aux() BOOST_CONTAINER_NOEXCEPT
+ void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW
{
this->priv_deallocate_node(this->members_.m_finish.m_first);
this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
@@ -1950,7 +2046,7 @@ class deque : protected deque_base<Allocator>
// if the deque has at least one element (a precondition for this member
// function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
// must have at least two nodes.
- void priv_pop_front_aux() BOOST_CONTAINER_NOEXCEPT
+ void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW
{
allocator_traits_type::destroy
( this->alloc()
@@ -1997,9 +2093,9 @@ class deque : protected deque_base<Allocator>
if (new_nodes + 1 > s){
this->priv_reallocate_map(new_nodes, false);
}
- size_type i;
+ size_type i = 1;
BOOST_TRY {
- for (i = 1; i <= new_nodes; ++i)
+ for (; i <= new_nodes; ++i)
*(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
}
BOOST_CATCH(...) {
@@ -2022,9 +2118,9 @@ class deque : protected deque_base<Allocator>
new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
if (new_nstart < this->members_.m_start.m_node)
- boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+ boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
else
- boost::move_backward
+ boost::container::move_backward
(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
}
else {
@@ -2034,7 +2130,7 @@ class deque : protected deque_base<Allocator>
index_pointer new_map = this->priv_allocate_map(new_map_size);
new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
- boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+ boost::container::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
this->members_.m_map = new_map;
@@ -2057,8 +2153,11 @@ namespace boost {
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::deque<T, Allocator> >
- : public ::boost::has_trivial_destructor_after_move<Allocator>
-{};
+{
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
}
diff --git a/boost/container/detail/adaptive_node_pool.hpp b/boost/container/detail/adaptive_node_pool.hpp
index 4e7375412b..4a1f07c4a8 100644
--- a/boost/container/detail/adaptive_node_pool.hpp
+++ b/boost/container/detail/adaptive_node_pool.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -19,13 +23,14 @@
#include <boost/container/detail/workaround.hpp>
#include <boost/intrusive/set.hpp>
-#include <boost/aligned_storage.hpp>
#include <boost/container/detail/alloc_lib_auto_link.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/container/detail/pool_common_alloc.hpp>
#include <boost/container/detail/mutex.hpp>
#include <boost/container/detail/adaptive_node_pool_impl.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
#include <cstddef>
#include <cmath>
#include <cassert>
diff --git a/boost/container/detail/adaptive_node_pool_impl.hpp b/boost/container/detail/adaptive_node_pool_impl.hpp
index dc1a7f102e..24c81dda3b 100644
--- a/boost/container/detail/adaptive_node_pool_impl.hpp
+++ b/boost/container/detail/adaptive_node_pool_impl.hpp
@@ -11,24 +11,34 @@
#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+// container
#include <boost/container/container_fwd.hpp>
-#include <boost/container/detail/utilities.hpp>
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/pool_common.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/math_functions.hpp>
+#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// intrusive
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
-#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/detail/math_functions.hpp>
-#include <boost/container/detail/mpl.hpp>
-#include <boost/container/detail/pool_common.hpp>
-#include <boost/container/throw_exception.hpp>
+// other
#include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <cstddef>
@@ -482,7 +492,7 @@ class private_adaptive_node_pool_impl
free_nodes_iterator itf(nodes.begin()), itbf(itbb);
size_type splice_node_count = size_type(-1);
while(itf != ite){
- void *pElem = container_detail::to_raw_pointer(container_detail::iterator_to_pointer(itf));
+ void *pElem = container_detail::to_raw_pointer(container_detail::iterator_to_raw_pointer(itf));
block_info_t &block_info = *this->priv_block_from_node(pElem);
BOOST_ASSERT(block_info.free_nodes.size() < m_real_num_node);
++splice_node_count;
diff --git a/boost/container/detail/addressof.hpp b/boost/container/detail/addressof.hpp
new file mode 100644
index 0000000000..cc582c439d
--- /dev/null
+++ b/boost/container/detail/addressof.hpp
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
+#define BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <cstddef>
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template <typename T>
+inline T* addressof(T& obj)
+{
+ return static_cast<T*>(
+ static_cast<void*>(
+ const_cast<char*>(
+ &reinterpret_cast<const char&>(obj)
+ )));
+}
+
+} //namespace container_detail {
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
diff --git a/boost/container/detail/advanced_insert_int.hpp b/boost/container/detail/advanced_insert_int.hpp
index a35279dcf7..56df588706 100644
--- a/boost/container/detail/advanced_insert_int.hpp
+++ b/boost/container/detail/advanced_insert_int.hpp
@@ -11,44 +11,55 @@
#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+// container
#include <boost/container/allocator_traits.hpp>
+// container/detail
+#include <boost/container/detail/copy_move_algo.hpp>
#include <boost/container/detail/destroyers.hpp>
-#include <boost/aligned_storage.hpp>
-#include <boost/move/utility_core.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
-#include <iterator> //std::iterator_traits
+#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+// move
+#include <boost/move/utility_core.hpp>
+// other
#include <boost/assert.hpp>
#include <boost/core/no_exceptions_support.hpp>
namespace boost { namespace container { namespace container_detail {
-template<class A, class FwdIt, class Iterator>
+template<class Allocator, 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;
+ typedef typename allocator_traits<Allocator>::size_type size_type;
+ typedef typename allocator_traits<Allocator>::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)
+ void uninitialized_copy_n_and_update(Allocator &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)
+ void copy_n_and_update(Allocator &, Iterator p, size_type n)
{
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
}
@@ -57,22 +68,22 @@ struct move_insert_range_proxy
};
-template<class A, class FwdIt, class Iterator>
+template<class Allocator, 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;
+ typedef typename allocator_traits<Allocator>::size_type size_type;
+ typedef typename allocator_traits<Allocator>::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)
+ void uninitialized_copy_n_and_update(Allocator &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)
+ void copy_n_and_update(Allocator &, Iterator p, size_type n)
{
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
}
@@ -81,20 +92,20 @@ struct insert_range_proxy
};
-template<class A, class Iterator>
+template<class Allocator, 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;
+ typedef typename allocator_traits<Allocator>::size_type size_type;
+ typedef typename allocator_traits<Allocator>::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
+ void uninitialized_copy_n_and_update(Allocator &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
+ void copy_n_and_update(Allocator &, Iterator p, size_type n) const
{
for (; 0 < n; --n, ++p){
*p = v_;
@@ -104,38 +115,38 @@ struct insert_n_copies_proxy
const value_type &v_;
};
-template<class A, class Iterator>
+template<class Allocator, 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;
+ typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
+ typedef typename allocator_traits<Allocator>::size_type size_type;
+ typedef typename allocator_traits<Allocator>::value_type value_type;
- void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
+ void uninitialized_copy_n_and_update(Allocator &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
+ void copy_n_and_update(Allocator &, Iterator, size_type) const
{ BOOST_ASSERT(false); }
};
-template<class A, class Iterator>
+template<class Allocator, 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;
+ typedef ::boost::container::allocator_traits<Allocator> alloc_traits;
+ typedef typename allocator_traits<Allocator>::size_type size_type;
+ typedef typename allocator_traits<Allocator>::value_type value_type;
- void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
+ void uninitialized_copy_n_and_update(Allocator &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
+ void copy_n_and_update(Allocator &, Iterator, size_type) const
{ BOOST_ASSERT(false); }
};
-template<class A, class Iterator>
+template<class Allocator, class Iterator>
struct insert_copy_proxy
{
- typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
@@ -143,13 +154,13 @@ struct insert_copy_proxy
: v_(v)
{}
- void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
+ void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a, iterator_to_raw_pointer(p), v_);
}
- void copy_n_and_update(A &, Iterator p, size_type n) const
+ void copy_n_and_update(Allocator &, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p =v_;
@@ -159,10 +170,10 @@ struct insert_copy_proxy
};
-template<class A, class Iterator>
+template<class Allocator, class Iterator>
struct insert_move_proxy
{
- typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef boost::container::allocator_traits<Allocator> alloc_traits;
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
@@ -170,13 +181,13 @@ struct insert_move_proxy
: v_(v)
{}
- void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const
+ void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::move(v_) );
}
- void copy_n_and_update(A &, Iterator p, size_type n) const
+ void copy_n_and_update(Allocator &, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p = ::boost::move(v_);
@@ -185,50 +196,48 @@ struct insert_move_proxy
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)
+template<class It, class Allocator>
+insert_move_proxy<Allocator, It> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v)
{
- return insert_move_proxy<A, It>(v);
+ return insert_move_proxy<Allocator, 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)
+template<class It, class Allocator>
+insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
{
- return insert_copy_proxy<A, It>(v);
+ return insert_copy_proxy<Allocator, It>(v);
}
}}} //namespace boost { namespace container { namespace container_detail {
-#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/variadic_templates_tools.hpp>
#include <boost/move/utility_core.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
+template<class Allocator, class Iterator, class ...Args>
+struct insert_nonmovable_emplace_proxy
{
- typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef boost::container::allocator_traits<Allocator> 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)
+ explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
: args_(args...)
{}
- void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n)
+ void uninitialized_copy_n_and_update(Allocator &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)
+ void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a, iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
@@ -238,30 +247,30 @@ struct insert_non_movable_emplace_proxy
tuple<Args&...> args_;
};
-template<class A, class Iterator, class ...Args>
+template<class Allocator, class Iterator, class ...Args>
struct insert_emplace_proxy
- : public insert_non_movable_emplace_proxy<A, Iterator, Args...>
+ : public insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...>
{
- typedef insert_non_movable_emplace_proxy<A, Iterator, Args...> base_t;
- typedef boost::container::allocator_traits<A> alloc_traits;
+ typedef insert_nonmovable_emplace_proxy<Allocator, Iterator, Args...> base_t;
+ typedef boost::container::allocator_traits<Allocator> 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)
+ explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
: base_t(::boost::forward<Args>(args)...)
{}
- void copy_n_and_update(A &a, Iterator p, size_type n)
+ void copy_n_and_update(Allocator &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)
+ void priv_copy_some_and_update(Allocator &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;
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));
alloc_traits::construct(a, vp,
::boost::forward<Args>(get<IdxPack>(this->args_))...);
@@ -278,191 +287,182 @@ struct insert_emplace_proxy
};
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
-template<class A, class Iterator>
-struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_traits<A>::value_type>
- : public insert_move_proxy<A, Iterator>
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
+ : public insert_move_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy(typename boost::container::allocator_traits<A>::value_type &&v)
- : insert_move_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
+ : insert_move_proxy<Allocator, Iterator>(v)
{}
};
//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
-//compiler error C2752 (“more than one partial specialization matches”).
+//compiler error C2752 ("more than one partial specialization matches").
//Any problem is solvable with an extra layer of indirection? ;-)
-template<class A, class Iterator>
-struct insert_emplace_proxy<A, Iterator
- , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy<Allocator, Iterator
+ , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
>
- : public insert_copy_proxy<A, Iterator>
+ : public insert_copy_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
- : insert_copy_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+ : insert_copy_proxy<Allocator, Iterator>(v)
{}
};
-template<class A, class Iterator>
-struct insert_emplace_proxy<A, Iterator, typename boost::container::allocator_traits<A>::value_type &>
- : public insert_copy_proxy<A, Iterator>
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
+ : public insert_copy_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
- : insert_copy_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+ : insert_copy_proxy<Allocator, Iterator>(v)
{}
};
-template<class A, class Iterator>
-struct insert_emplace_proxy<A, Iterator
- , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type &
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy<Allocator, Iterator
+ , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
>
- : public insert_copy_proxy<A, Iterator>
+ : public insert_copy_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy(const typename boost::container::allocator_traits<A>::value_type &v)
- : insert_copy_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+ : insert_copy_proxy<Allocator, Iterator>(v)
{}
};
}}} //namespace boost { namespace container { namespace container_detail {
-#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-#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, iterator_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()
+#define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
+template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+struct insert_nonmovable_emplace_proxy##N\
+{\
+ typedef boost::container::allocator_traits<Allocator> alloc_traits;\
+ typedef typename alloc_traits::size_type size_type;\
+ typedef typename alloc_traits::value_type value_type;\
+ \
+ explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\
+ BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\
+ \
+ void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
+ {\
+ BOOST_ASSERT(n == 1); (void)n;\
+ alloc_traits::construct(a, iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
+ }\
+ \
+ void copy_n_and_update(Allocator &, Iterator, size_type)\
+ { BOOST_ASSERT(false); }\
+ \
+ protected:\
+ BOOST_MOVE_MREF##N\
+};\
+\
+template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+struct insert_emplace_proxy_arg##N\
+ : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\
+{\
+ typedef insert_nonmovable_emplace_proxy##N\
+ < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\
+ typedef typename base_t::value_type value_type;\
+ typedef typename base_t::size_type size_type;\
+ typedef boost::container::allocator_traits<Allocator> alloc_traits;\
+ \
+ explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\
+ : base_t(BOOST_MOVE_FWD##N){}\
+ \
+ void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
+ {\
+ BOOST_ASSERT(n == 1); (void)n;\
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
+ BOOST_ASSERT((((size_type)(&v)) % alignment_of<value_type>::value) == 0);\
+ value_type *vp = static_cast<value_type *>(static_cast<void *>(&v));\
+ alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
+ BOOST_TRY{\
+ *p = ::boost::move(*vp);\
+ }\
+ BOOST_CATCH(...){\
+ alloc_traits::destroy(a, vp);\
+ BOOST_RETHROW\
+ }\
+ BOOST_CATCH_END\
+ alloc_traits::destroy(a, vp);\
+ }\
+};\
+//
+BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE)
+#undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
-template<class A, class Iterator>
-struct insert_emplace_proxy_arg1<A, Iterator, ::boost::rv<typename boost::container::allocator_traits<A>::value_type> >
- : public insert_move_proxy<A, Iterator>
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> >
+ : public insert_move_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<A>::value_type &v)
- : insert_move_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
+ : insert_move_proxy<Allocator, Iterator>(v)
{}
};
-template<class A, class Iterator>
-struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type>
- : public insert_copy_proxy<A, Iterator>
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
+ : public insert_copy_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
- : insert_copy_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+ : insert_copy_proxy<Allocator, Iterator>(v)
{}
};
#else //e.g. MSVC10 & MSVC11
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
-template<class A, class Iterator>
-struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type>
- : public insert_move_proxy<A, Iterator>
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type>
+ : public insert_move_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<A>::value_type &&v)
- : insert_move_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
+ : insert_move_proxy<Allocator, Iterator>(v)
{}
};
//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
-//compiler error C2752 (“more than one partial specialization matches”).
+//compiler error C2752 ("more than one partial specialization matches").
//Any problem is solvable with an extra layer of indirection? ;-)
-template<class A, class Iterator>
-struct insert_emplace_proxy_arg1<A, Iterator
- , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator
+ , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type
>
- : public insert_copy_proxy<A, Iterator>
+ : public insert_copy_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
- : insert_copy_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+ : insert_copy_proxy<Allocator, Iterator>(v)
{}
};
-template<class A, class Iterator>
-struct insert_emplace_proxy_arg1<A, Iterator, typename boost::container::allocator_traits<A>::value_type &>
- : public insert_copy_proxy<A, Iterator>
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator, typename boost::container::allocator_traits<Allocator>::value_type &>
+ : public insert_copy_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
- : insert_copy_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+ : insert_copy_proxy<Allocator, Iterator>(v)
{}
};
-template<class A, class Iterator>
-struct insert_emplace_proxy_arg1<A, Iterator
- , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<A>::value_type>::type &
+template<class Allocator, class Iterator>
+struct insert_emplace_proxy_arg1<Allocator, Iterator
+ , typename boost::container::container_detail::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type &
>
- : public insert_copy_proxy<A, Iterator>
+ : public insert_copy_proxy<Allocator, Iterator>
{
- explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<A>::value_type &v)
- : insert_copy_proxy<A, Iterator>(v)
+ explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
+ : insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -470,7 +470,7 @@ struct insert_emplace_proxy_arg1<A, Iterator
}}} //namespace boost { namespace container { namespace container_detail {
-#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/container/detail/config_end.hpp>
diff --git a/boost/container/detail/algorithm.hpp b/boost/container/detail/algorithm.hpp
new file mode 100644
index 0000000000..67e7876345
--- /dev/null
+++ b/boost/container/detail/algorithm.hpp
@@ -0,0 +1,35 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
+#define BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/intrusive/detail/algorithm.hpp>
+
+namespace boost {
+namespace container {
+
+using boost::intrusive::algo_equal;
+using boost::intrusive::algo_lexicographical_compare;
+
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
diff --git a/boost/container/detail/algorithms.hpp b/boost/container/detail/algorithms.hpp
deleted file mode 100644
index af15f65737..0000000000
--- a/boost/container/detail/algorithms.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (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)
-//
-// See http://www.boost.org/libs/container for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
-#define BOOST_CONTAINER_DETAIL_ALGORITHMS_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/iterators.hpp>
-
-namespace boost {
-namespace container {
-
-template<class A, class T, class InpIt>
-inline void construct_in_place(A &a, T* dest, InpIt source)
-{ boost::container::allocator_traits<A>::construct(a, dest, *source); }
-
-template<class A, class T, class U, class D>
-inline void construct_in_place(A &a, T *dest, value_init_construct_iterator<U, D>)
-{
- boost::container::allocator_traits<A>::construct(a, dest);
-}
-
-template <class T, class Difference>
-class default_init_construct_iterator;
-
-template<class A, class T, class U, class D>
-inline void construct_in_place(A &a, T *dest, default_init_construct_iterator<U, D>)
-{
- boost::container::allocator_traits<A>::construct(a, dest, default_init);
-}
-
-template <class T, class EmplaceFunctor, class Difference>
-class emplace_iterator;
-
-template<class A, class T, class U, class EF, class D>
-inline void construct_in_place(A &a, T *dest, emplace_iterator<U, EF, D> ei)
-{
- ei.construct_in_place(a, dest);
-}
-
-} //namespace container {
-} //namespace boost {
-
-#include <boost/container/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
-
diff --git a/boost/container/detail/alloc_helpers.hpp b/boost/container/detail/alloc_helpers.hpp
new file mode 100644
index 0000000000..656e0c2a5e
--- /dev/null
+++ b/boost/container/detail/alloc_helpers.hpp
@@ -0,0 +1,60 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
+#define BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+// move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template<class AllocatorType>
+inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
+ BOOST_NOEXCEPT_OR_NOTHROW
+{}
+
+template<class AllocatorType>
+inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
+{ boost::adl_move_swap(l, r); }
+
+template<class AllocatorType>
+inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type)
+ BOOST_NOEXCEPT_OR_NOTHROW
+{}
+
+template<class AllocatorType>
+inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type)
+{ l = r; }
+
+template<class AllocatorType>
+inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
+ BOOST_NOEXCEPT_OR_NOTHROW
+{}
+
+template<class AllocatorType>
+inline void move_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
+{ l = ::boost::move(r); }
+
+} //namespace container_detail {
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
diff --git a/boost/container/detail/alloc_lib_auto_link.hpp b/boost/container/detail/alloc_lib_auto_link.hpp
index e0a01b6086..aea99a65c3 100644
--- a/boost/container/detail/alloc_lib_auto_link.hpp
+++ b/boost/container/detail/alloc_lib_auto_link.hpp
@@ -10,7 +10,11 @@
#ifndef BOOST_CONTAINER_DETAIL_BOOST_CONT_EXT_AUTO_LINK_HPP
#define BOOST_CONTAINER_DETAIL_BOOST_CONT_EXT_AUTO_LINK_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/allocation_type.hpp b/boost/container/detail/allocation_type.hpp
index 65d543ad50..1e8aa67310 100644
--- a/boost/container/detail/allocation_type.hpp
+++ b/boost/container/detail/allocation_type.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -36,7 +40,7 @@ enum allocation_type_v
try_shrink_in_place_v = 0x40
};
-typedef int allocation_type;
+typedef unsigned int allocation_type;
#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;
diff --git a/boost/container/detail/allocator_version_traits.hpp b/boost/container/detail/allocator_version_traits.hpp
index 18bb2ac613..62492da091 100644
--- a/boost/container/detail/allocator_version_traits.hpp
+++ b/boost/container/detail/allocator_version_traits.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -25,7 +29,6 @@
#include <boost/container/detail/allocation_type.hpp> //allocation_type
#include <boost/container/detail/mpl.hpp> //integral_constant
#include <boost/intrusive/pointer_traits.hpp> //pointer_traits
-#include <utility> //pair
#include <boost/core/no_exceptions_support.hpp> //BOOST_TRY
namespace boost {
@@ -56,14 +59,9 @@ struct allocator_version_traits
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
{ a.deallocate_individual(holder); }
- static std::pair<pointer, bool>
- allocation_command(Allocator &a, allocation_type command,
- size_type limit_size, size_type preferred_size,
- size_type &received_size, const pointer &reuse)
- {
- return a.allocation_command
- (command, limit_size, preferred_size, received_size, reuse);
- }
+ static pointer allocation_command(Allocator &a, allocation_type command,
+ size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
+ { return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
};
template<class Allocator>
@@ -132,21 +130,16 @@ struct allocator_version_traits<Allocator, 1>
rollback.release();
}
- static std::pair<pointer, bool>
- allocation_command(Allocator &a, allocation_type command,
- size_type, size_type preferred_size,
- size_type &received_size, const pointer &)
+ static pointer allocation_command(Allocator &a, allocation_type command,
+ size_type, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
- std::pair<pointer, bool> ret(pointer(), false);
- if(!(command & allocate_new)){
- if(!(command & nothrow_allocation)){
- throw_logic_error("version 1 allocator without allocate_new flag");
- }
+ pointer ret = pointer();
+ if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){
+ throw_logic_error("version 1 allocator without allocate_new flag");
}
else{
- received_size = preferred_size;
BOOST_TRY{
- ret.first = a.allocate(received_size);
+ ret = a.allocate(prefer_in_recvd_out_size);
}
BOOST_CATCH(...){
if(!(command & nothrow_allocation)){
@@ -154,6 +147,7 @@ struct allocator_version_traits<Allocator, 1>
}
}
BOOST_CATCH_END
+ reuse = pointer();
}
return ret;
}
diff --git a/boost/container/detail/auto_link.hpp b/boost/container/detail/auto_link.hpp
index 2e4733363d..da078e8342 100644
--- a/boost/container/detail/auto_link.hpp
+++ b/boost/container/detail/auto_link.hpp
@@ -10,7 +10,11 @@
#ifndef BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
#define BOOST_CONTAINER_DETAIL_AUTO_LINK_HPP_INCLUDED
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/compare_functors.hpp b/boost/container/detail/compare_functors.hpp
new file mode 100644
index 0000000000..4220d50996
--- /dev/null
+++ b/boost/container/detail/compare_functors.hpp
@@ -0,0 +1,74 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
+#define BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+namespace boost {
+namespace container {
+
+template<class Allocator>
+class equal_to_value
+{
+ typedef typename Allocator::value_type value_type;
+ const value_type &t_;
+
+ public:
+ explicit equal_to_value(const value_type &t)
+ : t_(t)
+ {}
+
+ bool operator()(const value_type &t)const
+ { return t_ == t; }
+};
+
+template<class Node, class Pred>
+struct value_to_node_compare
+ : Pred
+{
+ typedef Pred predicate_type;
+ typedef Node node_type;
+
+ value_to_node_compare()
+ : Pred()
+ {}
+
+ explicit value_to_node_compare(Pred pred)
+ : Pred(pred)
+ {}
+
+ bool operator()(const Node &a, const Node &b) const
+ { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
+
+ bool operator()(const Node &a) const
+ { return static_cast<const Pred&>(*this)(a.m_data); }
+
+ bool operator()(const Node &a, const Node &b)
+ { return static_cast<Pred&>(*this)(a.m_data, b.m_data); }
+
+ bool operator()(const Node &a)
+ { return static_cast<Pred&>(*this)(a.m_data); }
+
+ predicate_type & predicate() { return static_cast<predicate_type&>(*this); }
+ const predicate_type & predicate() const { return static_cast<predicate_type&>(*this); }
+};
+
+} //namespace container {
+} //namespace boost {
+
+#endif //BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
diff --git a/boost/container/detail/config_begin.hpp b/boost/container/detail/config_begin.hpp
index ca9dd59682..3f509e320b 100644
--- a/boost/container/detail/config_begin.hpp
+++ b/boost/container/detail/config_begin.hpp
@@ -17,32 +17,34 @@
#ifdef BOOST_MSVC
#pragma warning (push)
- #pragma warning (disable : 4702) // unreachable code
- #pragma warning (disable : 4706) // assignment within conditional expression
#pragma warning (disable : 4127) // conditional expression is constant
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
- #pragma warning (disable : 4284) // odd return type for operator->
+ #pragma warning (disable : 4197) // top-level volatile in cast is ignored
#pragma warning (disable : 4244) // possible loss of data
#pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
#pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
+ #pragma warning (disable : 4284) // odd return type for operator->
+ #pragma warning (disable : 4324) // structure was padded due to __declspec(align(
+ #pragma warning (disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
#pragma warning (disable : 4355) // "this" : used in base member initializer list
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
+ #pragma warning (disable : 4510) // default constructor could not be generated
#pragma warning (disable : 4511) // copy constructor could not be generated
#pragma warning (disable : 4512) // assignment operator could not be generated
#pragma warning (disable : 4514) // unreferenced inline removed
#pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
#pragma warning (disable : 4522) // "class" : multiple assignment operators specified
+ #pragma warning (disable : 4541) // 'typeid' used on polymorphic type '' with /GR-; unpredictable behavior may result
+ #pragma warning (disable : 4584) // X is already a base-class of Y
+ #pragma warning (disable : 4610) // struct can never be instantiated - user defined constructor required
+ #pragma warning (disable : 4671) // the copy constructor is inaccessible
+ #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
+ #pragma warning (disable : 4702) // unreachable code
+ #pragma warning (disable : 4706) // assignment within conditional expression
#pragma warning (disable : 4710) // function not inlined
#pragma warning (disable : 4711) // function selected for automatic inline expansion
#pragma warning (disable : 4786) // identifier truncated in debug info
#pragma warning (disable : 4996) // "function": was declared deprecated
- #pragma warning (disable : 4197) // top-level volatile in cast is ignored
- #pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
- // with /GR-; unpredictable behavior may result
- #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
- #pragma warning (disable : 4671) // the copy constructor is inaccessible
- #pragma warning (disable : 4584) // X is already a base-class of Y
- #pragma warning (disable : 4510) // default constructor could not be generated
#endif //BOOST_MSVC
diff --git a/boost/container/detail/construct_in_place.hpp b/boost/container/detail/construct_in_place.hpp
new file mode 100644
index 0000000000..6cb339519c
--- /dev/null
+++ b/boost/container/detail/construct_in_place.hpp
@@ -0,0 +1,62 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
+#define BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/detail/iterators.hpp>
+
+namespace boost {
+namespace container {
+
+template<class Allocator, class T, class InpIt>
+inline void construct_in_place(Allocator &a, T* dest, InpIt source)
+{ boost::container::allocator_traits<Allocator>::construct(a, dest, *source); }
+
+template<class Allocator, class T, class U, class D>
+inline void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U, D>)
+{
+ boost::container::allocator_traits<Allocator>::construct(a, dest);
+}
+
+template <class T, class Difference>
+class default_init_construct_iterator;
+
+template<class Allocator, class T, class U, class D>
+inline void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U, D>)
+{
+ boost::container::allocator_traits<Allocator>::construct(a, dest, default_init);
+}
+
+template <class T, class EmplaceFunctor, class Difference>
+class emplace_iterator;
+
+template<class Allocator, class T, class U, class EF, class D>
+inline void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF, D> ei)
+{
+ ei.construct_in_place(a, dest);
+}
+
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
+
diff --git a/boost/container/detail/utilities.hpp b/boost/container/detail/copy_move_algo.hpp
index 25f035df50..79cbde80a9 100644
--- a/boost/container/detail/utilities.hpp
+++ b/boost/container/detail/copy_move_algo.hpp
@@ -7,225 +7,37 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
-#include <boost/container/detail/config_begin.hpp>
-#include <boost/container/detail/workaround.hpp>
-
-#include <cstdio>
-#include <cstring> //for ::memmove / ::memcpy
-#include <boost/type_traits/is_pointer.hpp>
-#include <boost/type_traits/is_enum.hpp>
-#include <boost/type_traits/is_class.hpp>
-#include <boost/type_traits/is_integral.hpp>
-#include <boost/type_traits/is_floating_point.hpp>
-#include <boost/type_traits/is_copy_constructible.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/type_traits/has_trivial_copy.hpp>
-#include <boost/type_traits/has_trivial_assign.hpp>
-#include <boost/type_traits/is_pod.hpp>
-#include <boost/move/core.hpp>
-#include <boost/move/utility_core.hpp>
-#include <boost/move/iterator.hpp>
-#include <boost/assert.hpp>
-#include <boost/container/throw_exception.hpp>
+// container
+#include <boost/container/allocator_traits.hpp>
+// container/detail
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/allocator_traits.hpp>
+// move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/utility_core.hpp>
+// other
#include <boost/core/no_exceptions_support.hpp>
-#include <boost/container/detail/memory_util.hpp>
-#include <boost/intrusive/pointer_traits.hpp>
-#include <boost/aligned_storage.hpp>
-#include <iterator>
-#include <utility> //std::distance
+// std
+#include <cstring> //for emmove/memcpy
namespace boost {
namespace container {
-
-//////////////////////////////////////////////////////////////////////////////
-//
-// swap
-//
-//////////////////////////////////////////////////////////////////////////////
-
-namespace container_swap {
-
-template<class T, bool IsClass = boost::is_class<T>::value >
-struct has_member_swap
-{
- static const bool value = boost::container::container_detail::
- has_member_function_callable_with_swap<T, T &>::value;
-};
-
-template<class T>
-struct has_member_swap<T, false>
-{
- static const bool value = false;
-};
-
-} //namespace container_swap {
-
-template<class T> inline
-typename container_detail::enable_if_c
- <container_swap::has_member_swap<T>::value, void>::type
-swap_dispatch(T &left, T &right) //swap using member swap
-{
- left.swap(right); // may throw
-}
-
-template<class T> inline
-typename container_detail::enable_if_c
- <!container_swap::has_member_swap<T>::value/* && boost::has_move_emulation_enabled<T>::value*/, void>::type
- swap_dispatch(T &left, T &right)
-{
- T temp(boost::move(left)); // may throw
- left = boost::move(right); // may throw
- right = boost::move(temp); // may throw
-}
-/*
-template<class T> inline
-typename container_detail::enable_if_c
- <!container_swap::has_member_swap<T>::value && !boost::has_move_emulation_enabled<T>::value, void>::type
- swap_dispatch(T &left, T &right)
-{
- using std::swap;
- swap(left, right); // may throw
-}
-*/
namespace container_detail {
-template <typename T>
-inline T* addressof(T& obj)
-{
- return static_cast<T*>(
- static_cast<void*>(
- const_cast<char*>(
- &reinterpret_cast<const char&>(obj)
- )));
-}
-
-template<class T>
-const T &max_value(const T &a, const T &b)
-{ return a > b ? a : b; }
-
-template<class T>
-const T &min_value(const T &a, const T &b)
-{ return a < b ? a : b; }
-
-enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent };
-
-template<class SizeType, NextCapacityOption Option>
-struct next_capacity_calculator;
-
-template<class SizeType>
-struct next_capacity_calculator<SizeType, NextCapacityDouble>
-{
- 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)
- return capacity + max_value(3*(capacity+1)/5, n);
-
- if (capacity < m3*2)
- return capacity + max_value((capacity+1)/2, n);
- return max_size;
- }
-};
-
-template <class T>
-inline T* to_raw_pointer(T* p)
-{ return p; }
-
-template <class Pointer>
-inline typename boost::intrusive::pointer_traits<Pointer>::element_type*
- to_raw_pointer(const Pointer &p)
-{ return boost::container::container_detail::to_raw_pointer(p.operator->()); }
-
-template <class T>
-inline T* iterator_to_pointer(T* i)
-{ return i; }
-
-template <class Iterator>
-inline typename std::iterator_traits<Iterator>::pointer
- iterator_to_pointer(const Iterator &i)
-{ return i.operator->(); }
-
-template <class Iterator>
-inline
- typename boost::intrusive::pointer_traits
- <typename std::iterator_traits<Iterator>::pointer>::element_type*
- iterator_to_raw_pointer(const Iterator &i)
-{ return (to_raw_pointer)((iterator_to_pointer)(i)); }
-
-
-template<class AllocatorType>
-inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
- BOOST_CONTAINER_NOEXCEPT
-{}
-
-template<class AllocatorType>
-inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
-{ boost::container::swap_dispatch(l, r); }
-
-template<class AllocatorType>
-inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type)
- BOOST_CONTAINER_NOEXCEPT
-{}
-
-template<class AllocatorType>
-inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type)
-{ l = r; }
-
-template<class AllocatorType>
-inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
- BOOST_CONTAINER_NOEXCEPT
-{}
-
-template<class AllocatorType>
-inline void move_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
-{ l = ::boost::move(r); }
-
-//Rounds "orig_size" by excess to round_to bytes
-template<class SizeType>
-inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)
-{
- return ((orig_size-1)/round_to+1)*round_to;
-}
-
-template <std::size_t OrigSize, std::size_t RoundTo>
-struct ct_rounded_size
-{
- enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
-};
-
template<class I>
struct are_elements_contiguous
{
@@ -243,6 +55,15 @@ struct are_elements_contiguous<T*>
};
/////////////////////////
+// move iterators
+/////////////////////////
+
+template<class It>
+struct are_elements_contiguous< ::boost::move_iterator<It> >
+ : are_elements_contiguous<It>
+{};
+
+/////////////////////////
// predeclarations
/////////////////////////
@@ -304,8 +125,8 @@ template <typename I, typename O>
struct are_contiguous_and_same
{
static const bool is_same_io =
- is_same< typename remove_const< typename ::std::iterator_traits<I>::value_type >::type
- , typename ::std::iterator_traits<O>::value_type
+ is_same< typename remove_const< typename ::boost::container::iterator_traits<I>::value_type >::type
+ , typename ::boost::container::iterator_traits<O>::value_type
>::value;
static const bool value = is_same_io &&
are_elements_contiguous<I>::value &&
@@ -316,112 +137,125 @@ template <typename I, typename O>
struct is_memtransfer_copy_assignable
{
static const bool value = are_contiguous_and_same<I, O>::value &&
- boost::has_trivial_assign< typename ::std::iterator_traits<I>::value_type >::value;
+ container_detail::is_trivially_copy_assignable< typename ::boost::container::iterator_traits<I>::value_type >::value;
};
template <typename I, typename O>
struct is_memtransfer_copy_constructible
{
static const bool value = are_contiguous_and_same<I, O>::value &&
- boost::has_trivial_copy< typename ::std::iterator_traits<I>::value_type >::value;
+ container_detail::is_trivially_copy_constructible< typename ::boost::container::iterator_traits<I>::value_type >::value;
};
template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_constructible
- : public enable_if_c<container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
+ : enable_if_c<container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
{};
template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_constructible
- : public enable_if_c<!container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
+ : enable_if_c<!container_detail::is_memtransfer_copy_constructible<I, O>::value, R>
{};
template <typename I, typename O, typename R>
struct enable_if_memtransfer_copy_assignable
- : public enable_if_c<container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
+ : enable_if_c<container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
{};
template <typename I, typename O, typename R>
struct disable_if_memtransfer_copy_assignable
- : public enable_if_c<!container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
+ : enable_if_c<!container_detail::is_memtransfer_copy_assignable<I, O>::value, R>
{};
template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
-inline F memmove(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
+inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
- typedef typename std::iterator_traits<I>::value_type value_type;
- typename std::iterator_traits<I>::difference_type n = std::distance(f, l);
- ::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- std::advance(r, n);
+ typedef typename boost::container::iterator_traits<I>::value_type value_type;
+ typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(r, n);
return r;
}
template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
-F memmove_n(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+F memmove_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
- typedef typename std::iterator_traits<I>::value_type value_type;
- ::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- std::advance(r, n);
+ typedef typename boost::container::iterator_traits<I>::value_type value_type;
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(r, n);
return r;
}
template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
-I memmove_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+I memmove_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
- typedef typename std::iterator_traits<I>::value_type value_type;
- ::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- std::advance(f, n);
+ typedef typename boost::container::iterator_traits<I>::value_type value_type;
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(f, n);
return f;
}
template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
-I memmove_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r) BOOST_CONTAINER_NOEXCEPT
+I memmove_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
{
- typedef typename std::iterator_traits<I>::value_type value_type;
- ::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
- std::advance(f, n);
- std::advance(r, n);
+ typedef typename boost::container::iterator_traits<I>::value_type value_type;
+ std::memmove((iterator_to_raw_pointer)(r), (iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ boost::container::iterator_advance(f, n);
+ boost::container::iterator_advance(r, n);
return f;
}
template <typename O>
struct is_memzero_initializable
{
- typedef typename ::std::iterator_traits<O>::value_type value_type;
+ typedef typename ::boost::container::iterator_traits<O>::value_type value_type;
static const bool value = are_elements_contiguous<O>::value &&
- ( ::boost::is_integral<value_type>::value || ::boost::is_enum<value_type>::value
+ ( container_detail::is_integral<value_type>::value || container_detail::is_enum<value_type>::value
#if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
- || ::boost::is_pointer<value_type>::value
+ || container_detail::is_pointer<value_type>::value
#endif
#if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO)
- || ::boost::is_floating_point<value_type>::value
+ || container_detail::is_floating_point<value_type>::value
#endif
#if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL)
- || ::boost::is_pod<value_type>::value
+ || container_detail::is_pod<value_type>::value
#endif
);
};
template <typename O, typename R>
struct enable_if_memzero_initializable
- : public enable_if_c<container_detail::is_memzero_initializable<O>::value, R>
+ : enable_if_c<container_detail::is_memzero_initializable<O>::value, R>
{};
template <typename O, typename R>
struct disable_if_memzero_initializable
- : public enable_if_c<!container_detail::is_memzero_initializable<O>::value, R>
+ : enable_if_c<!container_detail::is_memzero_initializable<O>::value, R>
{};
-} //namespace container_detail {
+template <typename I, typename R>
+struct enable_if_trivially_destructible
+ : enable_if_c < false/*container_detail::is_trivially_destructible
+ <typename boost::container::iterator_traits<I>::value_type>::value*/
+ , R>
+{};
+template <typename I, typename R>
+struct disable_if_trivially_destructible
+ : enable_if_c <true/*!container_detail::is_trivially_destructible
+ <typename boost::container::iterator_traits<I>::value_type>::value*/
+ , R>
+{};
+
+} //namespace container_detail {
//////////////////////////////////////////////////////////////////////////////
//
@@ -438,22 +272,22 @@ struct disable_if_memzero_initializable
//!
//! <b>Returns</b>: r
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
- uninitialized_move_alloc(A &a, I f, I l, F r)
+ uninitialized_move_alloc(Allocator &a, I f, I l, F r)
{
F back = r;
BOOST_TRY{
while (f != l) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -462,11 +296,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
- uninitialized_move_alloc(A &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
+ uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove(f, l, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -483,22 +317,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: r
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
- uninitialized_move_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+ uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -507,11 +341,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
- uninitialized_move_alloc_n(A &, I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+ uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove_n(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -528,22 +362,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: f (after incremented)
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
- uninitialized_move_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+ uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -552,11 +386,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
- uninitialized_move_alloc_n_source(A &, I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+ uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove_n_source(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -573,22 +407,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: r
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
- uninitialized_copy_alloc(A &a, I f, I l, F r)
+ uninitialized_copy_alloc(Allocator &a, I f, I l, F r)
{
F back = r;
BOOST_TRY{
while (f != l) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -597,11 +431,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
- uninitialized_copy_alloc(A &, I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
+ uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove(f, l, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -618,22 +452,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: r
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, F>::type
- uninitialized_copy_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+ uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -642,11 +476,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, F>::type
- uninitialized_copy_alloc_n(A &, I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+ uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove_n(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -663,22 +497,22 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: f (after incremented)
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F, I>::type
- uninitialized_copy_alloc_n_source(A &a, I f, typename std::iterator_traits<I>::difference_type n, F r)
+ uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -687,11 +521,11 @@ inline typename container_detail::disable_if_memtransfer_copy_constructible<I, F
}
template
- <typename A,
+ <typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F, I>::type
- uninitialized_copy_alloc_n_source(A &, I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+ uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove_n_source(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -708,21 +542,21 @@ inline typename container_detail::enable_if_memtransfer_copy_constructible<I, F,
//!
//! <b>Returns</b>: r
template
- <typename A,
+ <typename Allocator,
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memzero_initializable<F, F>::type
- uninitialized_value_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
+ uninitialized_value_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r));
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r));
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -731,14 +565,14 @@ inline typename container_detail::disable_if_memzero_initializable<F, F>::type
}
template
- <typename A,
+ <typename Allocator,
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memzero_initializable<F, F>::type
- uninitialized_value_init_alloc_n(A &, typename allocator_traits<A>::difference_type n, F r)
+ uninitialized_value_init_alloc_n(Allocator &, typename allocator_traits<Allocator>::difference_type n, F r)
{
- typedef typename std::iterator_traits<F>::value_type value_type;
- ::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
- std::advance(r, n);
+ typedef typename boost::container::iterator_traits<F>::value_type value_type;
+ std::memset((void*)container_detail::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
+ boost::container::iterator_advance(r, n);
return r;
}
@@ -756,20 +590,20 @@ inline typename container_detail::enable_if_memzero_initializable<F, F>::type
//!
//! <b>Returns</b>: r
template
- <typename A,
+ <typename Allocator,
typename F> // F models ForwardIterator
-inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
+inline F uninitialized_default_init_alloc_n(Allocator &a, typename allocator_traits<Allocator>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), default_init);
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), default_init);
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -791,21 +625,21 @@ inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits<A>::
//!
//! <b>Returns</b>: r
template
- <typename A,
+ <typename Allocator,
typename F, // F models ForwardIterator
typename T>
-inline void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
+inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t)
{
F back = f;
BOOST_TRY{
while (f != l) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(f), t);
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(f), t);
++f;
}
}
BOOST_CATCH(...){
for (; back != l; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -827,21 +661,21 @@ inline void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
//!
//! <b>Returns</b>: r
template
- <typename A,
+ <typename Allocator,
typename T,
typename F> // F models ForwardIterator
-inline F uninitialized_fill_alloc_n(A &a, const T &v, typename allocator_traits<A>::difference_type n, F r)
+inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename allocator_traits<Allocator>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
- allocator_traits<A>::construct(a, container_detail::iterator_to_raw_pointer(r), v);
+ allocator_traits<Allocator>::construct(a, container_detail::iterator_to_raw_pointer(r), v);
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(back));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(back));
}
BOOST_RETHROW;
}
@@ -872,7 +706,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
- copy(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
+ copy(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove(f, l, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -885,7 +719,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
- copy_n(I f, typename std::iterator_traits<I>::difference_type n, F r)
+ copy_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
while (n--) {
*r = *f;
@@ -898,7 +732,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
- copy_n(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+ copy_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove_n(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -911,7 +745,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
- copy_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r)
+ copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
while (n--) {
*r = *f;
@@ -924,7 +758,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
- copy_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+ copy_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove_n_source(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -937,7 +771,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
- copy_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r)
+ copy_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r)
{
while (n--) {
*r = *f;
@@ -950,7 +784,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
- copy_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r) BOOST_CONTAINER_NOEXCEPT
+ copy_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove_n_source_dest(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -976,7 +810,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
- move(I f, I l, F r) BOOST_CONTAINER_NOEXCEPT
+ move(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove(f, l, r); }
//////////////////////////////////////////////////////////////////////////////
@@ -989,7 +823,7 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
- move_n(I f, typename std::iterator_traits<I>::difference_type n, F r)
+ move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
while (n--) {
*r = ::boost::move(*f);
@@ -1002,12 +836,45 @@ template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
- move_n(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
+ move_n(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::memmove_n(f, n, r); }
+
//////////////////////////////////////////////////////////////////////////////
//
-// move_n_source
+// move_backward
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+<typename I, // I models BidirectionalIterator
+typename F> // F models ForwardIterator
+inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, F>::type
+ move_backward(I f, I l, F r)
+{
+ while (f != l) {
+ --l; --r;
+ *r = ::boost::move(*l);
+ }
+ return r;
+}
+
+template
+<typename I, // I models InputIterator
+typename F> // F models ForwardIterator
+inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, F>::type
+ move_backward(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{
+ typedef typename boost::container::iterator_traits<I>::value_type value_type;
+ const typename boost::container::iterator_traits<I>::difference_type n = boost::container::iterator_distance(f, l);
+ r -= n;
+ std::memmove((container_detail::iterator_to_raw_pointer)(r), (container_detail::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
+ return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// move_n_source_dest
//
//////////////////////////////////////////////////////////////////////////////
@@ -1015,7 +882,7 @@ template
<typename I // I models InputIterator
,typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
- move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r)
+ move_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r)
{
while (n--) {
*r = ::boost::move(*f);
@@ -1028,12 +895,12 @@ template
<typename I // I models InputIterator
,typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
- move_n_source(I f, typename std::iterator_traits<I>::difference_type n, F r) BOOST_CONTAINER_NOEXCEPT
-{ return container_detail::memmove_n_source(f, n, r); }
+ move_n_source_dest(I f, typename boost::container::iterator_traits<I>::difference_type n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
+{ return container_detail::memmove_n_source_dest(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
//
-// move_n_source_dest
+// move_n_source
//
//////////////////////////////////////////////////////////////////////////////
@@ -1041,7 +908,7 @@ template
<typename I // I models InputIterator
,typename F> // F models ForwardIterator
inline typename container_detail::disable_if_memtransfer_copy_assignable<I, F, I>::type
- move_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r)
+ move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r)
{
while (n--) {
*r = ::boost::move(*f);
@@ -1054,33 +921,34 @@ template
<typename I // I models InputIterator
,typename F> // F models ForwardIterator
inline typename container_detail::enable_if_memtransfer_copy_assignable<I, F, I>::type
- move_n_source_dest(I f, typename std::iterator_traits<I>::difference_type n, F &r) BOOST_CONTAINER_NOEXCEPT
-{ return container_detail::memmove_n_source_dest(f, n, r); }
+ move_n_source(I f, typename boost::container::iterator_traits<I>::difference_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
+{ return container_detail::memmove_n_source(f, n, r); }
//////////////////////////////////////////////////////////////////////////////
//
-// destroy_n
+// destroy_alloc_n
//
//////////////////////////////////////////////////////////////////////////////
template
- <typename A
- ,typename I> // I models InputIterator
-inline void destroy_alloc_n(A &a, I f, typename std::iterator_traits<I>::difference_type n
- ,typename boost::container::container_detail::enable_if_c
- < !boost::has_trivial_destructor<typename std::iterator_traits<I>::value_type>::value >::type* = 0)
+ <typename Allocator
+ ,typename I // I models InputIterator
+ ,typename U> // U models unsigned integral constant
+inline typename container_detail::disable_if_trivially_destructible<I, void>::type
+ destroy_alloc_n(Allocator &a, I f, U n)
{
while(n--){
- allocator_traits<A>::destroy(a, container_detail::iterator_to_raw_pointer(f++));
+ allocator_traits<Allocator>::destroy(a, container_detail::iterator_to_raw_pointer(f));
+ ++f;
}
}
template
- <typename A
- ,typename I> // I models InputIterator
-inline void destroy_alloc_n(A &, I, typename std::iterator_traits<I>::difference_type
- ,typename boost::container::container_detail::enable_if_c
- < boost::has_trivial_destructor<typename std::iterator_traits<I>::value_type>::value >::type* = 0)
+ <typename Allocator
+ ,typename I // I models InputIterator
+ ,typename U> // U models unsigned integral constant
+inline typename container_detail::enable_if_trivially_destructible<I, void>::type
+ destroy_alloc_n(Allocator &, I, U)
{}
//////////////////////////////////////////////////////////////////////////////
@@ -1091,17 +959,17 @@ inline void destroy_alloc_n(A &, I, typename std::iterator_traits<I>::difference
template
<std::size_t MaxTmpBytes
- ,typename A
+ ,typename Allocator
,typename F // F models ForwardIterator
,typename G // G models ForwardIterator
>
inline typename container_detail::disable_if_memtransfer_copy_assignable<F, G, void>::type
- deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
- , G large_range_f, typename allocator_traits<A>::size_type n_j)
+ deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
+ , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
{
- typename allocator_traits<A>::size_type n = 0;
+ typename allocator_traits<Allocator>::size_type n = 0;
for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){
- boost::container::swap_dispatch(*short_range_f, *large_range_f);
+ boost::adl_move_swap(*short_range_f, *large_range_f);
}
boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
@@ -1111,18 +979,18 @@ static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_
template
<std::size_t MaxTmpBytes
- ,typename A
+ ,typename Allocator
,typename F // F models ForwardIterator
,typename G // G models ForwardIterator
>
inline typename container_detail::enable_if_c
< container_detail::is_memtransfer_copy_assignable<F, G>::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false
, void>::type
- deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
- , G large_range_f, typename allocator_traits<A>::size_type n_j)
+ deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
+ , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
{
- typedef typename allocator_traits<A>::value_type value_type;
- typedef typename boost::aligned_storage
+ typedef typename allocator_traits<Allocator>::value_type value_type;
+ typedef typename container_detail::aligned_storage
<MaxTmpBytes, container_detail::alignment_of<value_type>::value>::type storage_type;
storage_type storage;
@@ -1130,29 +998,29 @@ inline typename container_detail::enable_if_c
void *const large_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(large_range_f));
void *const short_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(short_range_f));
void *const stora_ptr = static_cast<void*>(container_detail::iterator_to_raw_pointer(storage));
- ::memcpy(stora_ptr, large_ptr, n_i_bytes);
- ::memcpy(large_ptr, short_ptr, n_i_bytes);
- ::memcpy(short_ptr, stora_ptr, n_i_bytes);
- std::advance(large_range_f, n_i);
- std::advance(short_range_f, n_i);
+ std::memcpy(stora_ptr, large_ptr, n_i_bytes);
+ std::memcpy(large_ptr, short_ptr, n_i_bytes);
+ std::memcpy(short_ptr, stora_ptr, n_i_bytes);
+ boost::container::iterator_advance(large_range_f, n_i);
+ boost::container::iterator_advance(short_range_f, n_i);
boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
}
template
<std::size_t MaxTmpBytes
- ,typename A
+ ,typename Allocator
,typename F // F models ForwardIterator
,typename G // G models ForwardIterator
>
inline typename container_detail::enable_if_c
< container_detail::is_memtransfer_copy_assignable<F, G>::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage)
, void>::type
- deep_swap_alloc_n( A &a, F short_range_f, typename allocator_traits<A>::size_type n_i
- , G large_range_f, typename allocator_traits<A>::size_type n_j)
+ deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits<Allocator>::size_type n_i
+ , G large_range_f, typename allocator_traits<Allocator>::size_type n_j)
{
- typedef typename allocator_traits<A>::value_type value_type;
- typedef typename boost::aligned_storage
+ typedef typename allocator_traits<Allocator>::value_type value_type;
+ typedef typename container_detail::aligned_storage
<DeepSwapAllocNMaxStorage, container_detail::alignment_of<value_type>::value>::type storage_type;
storage_type storage;
const std::size_t sizeof_storage = sizeof(storage);
@@ -1173,39 +1041,39 @@ inline typename container_detail::enable_if_c
case 4:
break;
case 0: do{
- ::memcpy(stora_ptr, large_ptr, sizeof_storage);
- ::memcpy(large_ptr, short_ptr, sizeof_storage);
- ::memcpy(short_ptr, stora_ptr, sizeof_storage);
+ std::memcpy(stora_ptr, large_ptr, sizeof_storage);
+ std::memcpy(large_ptr, short_ptr, sizeof_storage);
+ std::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage;
short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 3:
- ::memcpy(stora_ptr, large_ptr, sizeof_storage);
- ::memcpy(large_ptr, short_ptr, sizeof_storage);
- ::memcpy(short_ptr, stora_ptr, sizeof_storage);
+ std::memcpy(stora_ptr, large_ptr, sizeof_storage);
+ std::memcpy(large_ptr, short_ptr, sizeof_storage);
+ std::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage;
short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 2:
- ::memcpy(stora_ptr, large_ptr, sizeof_storage);
- ::memcpy(large_ptr, short_ptr, sizeof_storage);
- ::memcpy(short_ptr, stora_ptr, sizeof_storage);
+ std::memcpy(stora_ptr, large_ptr, sizeof_storage);
+ std::memcpy(large_ptr, short_ptr, sizeof_storage);
+ std::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage;
short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 1:
- ::memcpy(stora_ptr, large_ptr, sizeof_storage);
- ::memcpy(large_ptr, short_ptr, sizeof_storage);
- ::memcpy(short_ptr, stora_ptr, sizeof_storage);
+ std::memcpy(stora_ptr, large_ptr, sizeof_storage);
+ std::memcpy(large_ptr, short_ptr, sizeof_storage);
+ std::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage;
short_ptr += sizeof_storage;
} while(--n);
}
- ::memcpy(stora_ptr, large_ptr, szt_rem);
- ::memcpy(large_ptr, short_ptr, szt_rem);
- ::memcpy(short_ptr, stora_ptr, szt_rem);
- std::advance(large_range_f, n_i);
- std::advance(short_range_f, n_i);
+ std::memcpy(stora_ptr, large_ptr, szt_rem);
+ std::memcpy(large_ptr, short_ptr, szt_rem);
+ std::memcpy(short_ptr, stora_ptr, szt_rem);
+ boost::container::iterator_advance(large_range_f, n_i);
+ boost::container::iterator_advance(short_range_f, n_i);
boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw
boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i);
}
@@ -1218,12 +1086,12 @@ inline typename container_detail::enable_if_c
//////////////////////////////////////////////////////////////////////////////
template
- <typename A
+ <typename Allocator
,typename I // F models InputIterator
,typename O // G models OutputIterator
>
-void copy_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>::size_type n_i
- , O out_start, typename allocator_traits<A>::size_type n_o )
+void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
+ , O out_start, typename allocator_traits<Allocator>::size_type n_o )
{
if (n_o < n_i){
inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw
@@ -1242,12 +1110,12 @@ void copy_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>:
//////////////////////////////////////////////////////////////////////////////
template
- <typename A
+ <typename Allocator
,typename I // F models InputIterator
,typename O // G models OutputIterator
>
-void move_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>::size_type n_i
- , O out_start, typename allocator_traits<A>::size_type n_o )
+void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits<Allocator>::size_type n_i
+ , O out_start, typename allocator_traits<Allocator>::size_type n_o )
{
if (n_o < n_i){
inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw
@@ -1262,6 +1130,4 @@ void move_assign_range_alloc_n( A &a, I inp_start, typename allocator_traits<A>:
} //namespace container {
} //namespace boost {
-#include <boost/container/detail/config_end.hpp>
-
#endif //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
diff --git a/boost/container/detail/destroyers.hpp b/boost/container/detail/destroyers.hpp
index ea9b617437..52b44c0363 100644
--- a/boost/container/detail/destroyers.hpp
+++ b/boost/container/detail/destroyers.hpp
@@ -13,16 +13,20 @@
#ifndef BOOST_CONTAINER_DESTROYERS_HPP
#define BOOST_CONTAINER_DESTROYERS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#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>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/version_type.hpp>
namespace boost {
namespace container {
@@ -30,22 +34,20 @@ namespace container_detail {
//!A deleter for scoped_ptr that deallocates the memory
//!allocated for an object using a STL allocator.
-template <class A>
+template <class Allocator>
struct scoped_deallocator
{
- typedef allocator_traits<A> allocator_traits_type;
+ typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::pointer pointer;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
- version<A>::value> alloc_version;
- typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
- typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
+ version<Allocator>::value> alloc_version;
private:
- void priv_deallocate(allocator_v1)
+ void priv_deallocate(version_1)
{ m_alloc.deallocate(m_ptr, 1); }
- void priv_deallocate(allocator_v2)
+ void priv_deallocate(version_2)
{ m_alloc.deallocate_one(m_ptr); }
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
@@ -53,9 +55,9 @@ struct scoped_deallocator
public:
pointer m_ptr;
- A& m_alloc;
+ Allocator& m_alloc;
- scoped_deallocator(pointer p, A& a)
+ scoped_deallocator(pointer p, Allocator& a)
: m_ptr(p), m_alloc(a)
{}
@@ -143,8 +145,6 @@ struct scoped_destroy_deallocator
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<Allocator>::value> alloc_version;
- typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
- typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
scoped_destroy_deallocator(pointer p, Allocator& a)
: m_ptr(p), m_alloc(a) {}
@@ -162,10 +162,10 @@ struct scoped_destroy_deallocator
private:
- void priv_deallocate(const pointer &p, allocator_v1)
+ void priv_deallocate(const pointer &p, version_1)
{ AllocTraits::deallocate(m_alloc, p, 1); }
- void priv_deallocate(const pointer &p, allocator_v2)
+ void priv_deallocate(const pointer &p, version_2)
{ m_alloc.deallocate_one(p); }
pointer m_ptr;
@@ -239,13 +239,13 @@ struct null_scoped_destructor_n
{}
};
-template<class A>
+template<class Allocator>
class scoped_destructor
{
- typedef boost::container::allocator_traits<A> AllocTraits;
+ typedef boost::container::allocator_traits<Allocator> AllocTraits;
public:
- typedef typename A::value_type value_type;
- scoped_destructor(A &a, value_type *pv)
+ typedef typename Allocator::value_type value_type;
+ scoped_destructor(Allocator &a, value_type *pv)
: pv_(pv), a_(a)
{}
@@ -266,17 +266,17 @@ class scoped_destructor
private:
value_type *pv_;
- A &a_;
+ Allocator &a_;
};
-template<class A>
+template<class Allocator>
class value_destructor
{
- typedef boost::container::allocator_traits<A> AllocTraits;
+ typedef boost::container::allocator_traits<Allocator> AllocTraits;
public:
- typedef typename A::value_type value_type;
- value_destructor(A &a, value_type &rv)
+ typedef typename Allocator::value_type value_type;
+ value_destructor(Allocator &a, value_type &rv)
: rv_(rv), a_(a)
{}
@@ -287,7 +287,7 @@ class value_destructor
private:
value_type &rv_;
- A &a_;
+ Allocator &a_;
};
template <class Allocator>
@@ -299,21 +299,19 @@ class allocator_destroyer
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<Allocator>::value> alloc_version;
- typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
- typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
private:
Allocator & a_;
private:
- void priv_deallocate(const pointer &p, allocator_v1)
+ void priv_deallocate(const pointer &p, version_1)
{ AllocTraits::deallocate(a_,p, 1); }
- void priv_deallocate(const pointer &p, allocator_v2)
+ void priv_deallocate(const pointer &p, version_2)
{ a_.deallocate_one(p); }
public:
- allocator_destroyer(Allocator &a)
+ explicit allocator_destroyer(Allocator &a)
: a_(a)
{}
@@ -324,41 +322,41 @@ class allocator_destroyer
}
};
-template <class A>
+template <class Allocator>
class allocator_destroyer_and_chain_builder
{
- typedef allocator_traits<A> allocator_traits_type;
+ typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
- typedef typename A::multiallocation_chain multiallocation_chain;
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
- A & a_;
+ Allocator & a_;
multiallocation_chain &c_;
public:
- allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
+ allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
: a_(a), c_(c)
{}
- void operator()(const typename A::pointer &p)
+ void operator()(const typename Allocator::pointer &p)
{
- allocator_traits<A>::destroy(a_, container_detail::to_raw_pointer(p));
+ allocator_traits<Allocator>::destroy(a_, container_detail::to_raw_pointer(p));
c_.push_back(p);
}
};
-template <class A>
+template <class Allocator>
class allocator_multialloc_chain_node_deallocator
{
- typedef allocator_traits<A> allocator_traits_type;
+ typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
- typedef typename A::multiallocation_chain multiallocation_chain;
- typedef allocator_destroyer_and_chain_builder<A> chain_builder;
+ typedef typename Allocator::multiallocation_chain multiallocation_chain;
+ typedef allocator_destroyer_and_chain_builder<Allocator> chain_builder;
- A & a_;
+ Allocator & a_;
multiallocation_chain c_;
public:
- allocator_multialloc_chain_node_deallocator(A &a)
+ allocator_multialloc_chain_node_deallocator(Allocator &a)
: a_(a), c_()
{}
diff --git a/boost/container/detail/flat_tree.hpp b/boost/container/detail/flat_tree.hpp
index a6f7568b43..a94043c6bd 100644
--- a/boost/container/detail/flat_tree.hpp
+++ b/boost/container/detail/flat_tree.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_FLAT_TREE_HPP
#define BOOST_CONTAINER_FLAT_TREE_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -20,29 +24,29 @@
#include <boost/container/container_fwd.hpp>
-#include <algorithm>
-#include <functional>
-#include <utility>
-
-#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/move/utility_core.hpp>
-#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/detail/value_init.hpp>
#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/iterator.hpp>
#include <boost/container/allocator_traits.hpp>
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
#include <boost/intrusive/pointer_traits.hpp>
#endif
-#include <boost/aligned_storage.hpp>
+#include <boost/container/detail/type_traits.hpp>
#include <boost/move/make_unique.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
-namespace boost {
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+namespace boost {
namespace container {
-
namespace container_detail {
template<class Compare, class Value, class KeyOfValue>
@@ -78,30 +82,29 @@ template<class Pointer>
struct get_flat_tree_iterators
{
#ifdef BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
- typedef Pointer iterator;
+ typedef Pointer iterator;
typedef typename boost::intrusive::
- pointer_traits<Pointer>::element_type iterator_element_type;
+ pointer_traits<Pointer>::element_type iterator_element_type;
typedef typename boost::intrusive::
pointer_traits<Pointer>:: template
- rebind_pointer<const iterator_element_type>::type const_iterator;
+ rebind_pointer<const iterator_element_type>::type const_iterator;
#else //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
typedef typename boost::container::container_detail::
- vec_iterator<Pointer, false> iterator;
+ vec_iterator<Pointer, false> iterator;
typedef typename boost::container::container_detail::
- vec_iterator<Pointer, true > const_iterator;
+ vec_iterator<Pointer, true > const_iterator;
#endif //BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER
- typedef boost::container::container_detail::
- reverse_iterator<iterator> reverse_iterator;
- typedef boost::container::container_detail::
- reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef boost::container::reverse_iterator<iterator> reverse_iterator;
+ typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
};
template <class Key, class Value, class KeyOfValue,
- class Compare, class A>
+ class Compare, class Allocator>
class flat_tree
{
- typedef boost::container::vector<Value, A> vector_t;
- typedef A allocator_t;
+ typedef boost::container::vector<Value, Allocator> vector_t;
+ typedef Allocator allocator_t;
+ typedef allocator_traits<Allocator> allocator_traits_type;
public:
typedef flat_tree_value_compare<Compare, Value, KeyOfValue> value_compare;
@@ -126,11 +129,11 @@ class flat_tree
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect))
{}
- Data(const Data &d, const A &a)
+ Data(const Data &d, const Allocator &a)
: value_compare(static_cast<const value_compare&>(d)), m_vect(d.m_vect, a)
{}
- Data(BOOST_RV_REF(Data) d, const A &a)
+ Data(BOOST_RV_REF(Data) d, const Allocator &a)
: value_compare(boost::move(static_cast<value_compare&>(d))), m_vect(boost::move(d.m_vect), a)
{}
@@ -163,7 +166,7 @@ class flat_tree
void swap(Data &d)
{
value_compare& mycomp = *this, & othercomp = d;
- boost::container::swap_dispatch(mycomp, othercomp);
+ boost::adl_move_swap(mycomp, othercomp);
this->m_vect.swap(d.m_vect);
}
@@ -265,8 +268,10 @@ class flat_tree
flat_tree& operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
{ m_data = x.m_data; return *this; }
- flat_tree& operator=(BOOST_RV_REF(flat_tree) mx)
- { m_data = boost::move(mx.m_data); return *this; }
+ flat_tree& operator=(BOOST_RV_REF(flat_tree) x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
+ { m_data = boost::move(x.m_data); return *this; }
public:
// accessors:
@@ -331,6 +336,8 @@ class flat_tree
{ return this->m_data.m_vect.max_size(); }
void swap(flat_tree& other)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
{ this->m_data.swap(other.m_data); }
public:
@@ -428,7 +435,7 @@ class flat_tree
#endif
)
{
- const size_type len = static_cast<size_type>(std::distance(first, last));
+ const size_type len = static_cast<size_type>(boost::container::iterator_distance(first, last));
this->reserve(this->size()+len);
this->priv_insert_equal_loop(first, last);
}
@@ -455,7 +462,7 @@ class flat_tree
#endif
)
{
- const size_type len = static_cast<size_type>(std::distance(first, last));
+ const size_type len = static_cast<size_type>(boost::container::iterator_distance(first, last));
this->reserve(this->size()+len);
this->priv_insert_equal_loop_ordered(first, last);
}
@@ -499,12 +506,12 @@ class flat_tree
)
{ this->priv_insert_ordered_range(true, first, last); }
- #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class... Args>
- std::pair<iterator, bool> emplace_unique(Args&&... args)
+ std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
{
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -513,9 +520,9 @@ class flat_tree
}
template <class... Args>
- iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+ iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -524,9 +531,9 @@ class flat_tree
}
template <class... Args>
- iterator emplace_equal(Args&&... args)
+ iterator emplace_equal(BOOST_FWD_REF(Args)... args)
{
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -535,9 +542,9 @@ class flat_tree
}
template <class... Args>
- iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+ iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v;
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator();
stored_allocator_traits::construct(a, &val, ::boost::forward<Args>(args)... );
@@ -545,64 +552,57 @@ class flat_tree
return this->insert_equal(hint, ::boost::move(val));
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- std::pair<iterator, bool> \
- emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
- value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
- stored_allocator_type &a = this->get_stored_allocator(); \
- stored_allocator_traits::construct(a, &val \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- value_destructor<stored_allocator_type> d(a, val); \
- return this->insert_unique(::boost::move(val)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint_unique(const_iterator hint \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
- value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
- stored_allocator_type &a = this->get_stored_allocator(); \
- stored_allocator_traits::construct(a, &val \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- value_destructor<stored_allocator_type> d(a, val); \
- return this->insert_unique(hint, ::boost::move(val)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
- value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
- stored_allocator_type &a = this->get_stored_allocator(); \
- stored_allocator_traits::construct(a, &val \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- value_destructor<stored_allocator_type> d(a, val); \
- return this->insert_equal(::boost::move(val)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint_equal(const_iterator hint \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- aligned_storage<sizeof(value_type), alignment_of<value_type>::value> v; \
- value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); \
- stored_allocator_type &a = this->get_stored_allocator(); \
- stored_allocator_traits::construct(a, &val \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- value_destructor<stored_allocator_type> d(a, val); \
- return this->insert_equal(hint, ::boost::move(val)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ #define BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\
+ {\
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
+ value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
+ stored_allocator_type &a = this->get_stored_allocator();\
+ stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ value_destructor<stored_allocator_type> d(a, val);\
+ return this->insert_unique(::boost::move(val));\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
+ value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
+ stored_allocator_type &a = this->get_stored_allocator();\
+ stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ value_destructor<stored_allocator_type> d(a, val);\
+ return this->insert_unique(hint, ::boost::move(val));\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_equal(BOOST_MOVE_UREF##N)\
+ {\
+ typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;\
+ value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
+ stored_allocator_type &a = this->get_stored_allocator();\
+ stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ value_destructor<stored_allocator_type> d(a, val);\
+ return this->insert_equal(::boost::move(val));\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ typename aligned_storage <sizeof(value_type), alignment_of<value_type>::value>::type v;\
+ value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));\
+ stored_allocator_type &a = this->get_stored_allocator();\
+ stored_allocator_traits::construct(a, &val BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ value_destructor<stored_allocator_type> d(a, val);\
+ return this->insert_equal(hint, ::boost::move(val));\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_FLAT_TREE_EMPLACE_CODE
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
iterator erase(const_iterator position)
{ return this->m_data.m_vect.erase(position); }
@@ -632,6 +632,18 @@ class flat_tree
void shrink_to_fit()
{ this->m_data.m_vect.shrink_to_fit(); }
+ iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->m_data.m_vect.nth(n); }
+
+ const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->m_data.m_vect.nth(n); }
+
+ size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->m_data.m_vect.index_of(p); }
+
+ size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->m_data.m_vect.index_of(p); }
+
// set operations:
iterator find(const key_type& k)
{
@@ -694,13 +706,12 @@ class flat_tree
friend bool operator==(const flat_tree& x, const flat_tree& y)
{
- return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
+ return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin());
}
friend bool operator<(const flat_tree& x, const flat_tree& y)
{
- return std::lexicographical_compare(x.begin(), x.end(),
- y.begin(), y.end());
+ return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
friend bool operator!=(const flat_tree& x, const flat_tree& y)
@@ -936,7 +947,7 @@ class flat_tree
template <class BidirIt>
void priv_insert_ordered_range(const bool unique_values, BidirIt first, BidirIt last)
{
- size_type len = static_cast<size_type>(std::distance(first, last));
+ size_type len = static_cast<size_type>(boost::container::iterator_distance(first, last));
//Prereserve all memory so that iterators are not invalidated
this->reserve(this->size()+len);
//Auxiliary data for insertion positions.
@@ -955,10 +966,10 @@ class flat_tree
size_type unique_burst = 0u;
size_type checked = 0;
for(; checked != burst; ++checked){
- //Get the insertion position for each key, use std::iterator_traits<BidirIt>::value_type
+ //Get the insertion position for each key, use iterator_traits<BidirIt>::value_type
//because it can be different from container::value_type
- //(e.g. conversion between std::pair<A, B> -> boost::container::pair<A, B>
- const typename std::iterator_traits<BidirIt>::value_type & val = *first;
+ //(e.g. conversion between std::pair<T1, T2> -> boost::container::pair<T1, T2>
+ const typename boost::container::iterator_traits<BidirIt>::value_type & val = *first;
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
//Check if already present
if (pos != ce){
@@ -984,7 +995,11 @@ class flat_tree
while(len--){
BidirIt next(first);
++next;
- if(next == last || val_cmp(*first, *next)){
+ //Use iterator_traits<BidirIt>::value_type
+ //because it can be different from container::value_type
+ //(e.g. conversion between std::pair<T1, T2> -> boost::container::pair<T1, T2>
+ const typename boost::container::iterator_traits<BidirIt>::value_type & val = *first;
+ if (next == last || val_cmp(val, *next)){
const bool room = this->m_data.m_vect.stable_emplace_back(*first);
(void)room;
BOOST_ASSERT(room);
@@ -994,7 +1009,7 @@ class flat_tree
BOOST_ASSERT(first == last);
}
else{
- BOOST_ASSERT(size_type(std::distance(first, last)) == len);
+ BOOST_ASSERT(size_type(boost::container::iterator_distance(first, last)) == len);
if(len)
this->m_data.m_vect.insert(this->m_data.m_vect.cend(), len, first, last);
}
@@ -1004,16 +1019,18 @@ class flat_tree
} //namespace container_detail {
} //namespace container {
-/*
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class K, class V, class KOV,
-class C, class A>
-struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<K, V, KOV, C, A> >
+template <class Key, class T, class KeyOfValue,
+class Compare, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::container_detail::flat_tree<Key, T, KeyOfValue, Compare, Allocator> >
{
- static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
};
-*/
+
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
diff --git a/boost/container/detail/function_detector.hpp b/boost/container/detail/function_detector.hpp
index 242eb41352..00caced5ba 100644
--- a/boost/container/detail/function_detector.hpp
+++ b/boost/container/detail/function_detector.hpp
@@ -22,7 +22,11 @@
#ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
#define BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/hash_table.hpp b/boost/container/detail/hash_table.hpp
index da7bb536e4..4bc5c901de 100644
--- a/boost/container/detail/hash_table.hpp
+++ b/boost/container/detail/hash_table.hpp
@@ -1,6 +1,6 @@
/*
template <class Value, unsigned int Options = 0, class Hash = hash<Value>, class Pred = equal_to<Value>,
- class Alloc = allocator<Value> >
+ class Allocator = allocator<Value> >
class hash_set
{
public:
@@ -9,7 +9,7 @@ public:
typedef key_type value_type;
typedef Hash hasher;
typedef Pred key_equal;
- typedef Alloc allocator_type;
+ typedef Allocator allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename allocator_traits<allocator_type>::pointer pointer;
@@ -71,9 +71,9 @@ public:
const_iterator cend() const noexcept;
template <class... Args>
- pair<iterator, bool> emplace(Args&&... args);
+ pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... Args>
- iterator emplace_hint(const_iterator position, Args&&... args);
+ iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args);
pair<iterator, bool> insert(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj);
iterator insert(const_iterator hint, const value_type& obj);
@@ -124,7 +124,7 @@ public:
};
template <class Key, class T, unsigned int Options = 0, class Hash = hash<Key>, class Pred = equal_to<Key>,
- class Alloc = allocator<pair<const Key, T> > >
+ class Allocator = allocator<pair<const Key, T> > >
class hash_map
{
public:
@@ -133,7 +133,7 @@ public:
typedef T mapped_type;
typedef Hash hasher;
typedef Pred key_equal;
- typedef Alloc allocator_type;
+ typedef Allocator allocator_type;
typedef pair<const key_type, mapped_type> value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
@@ -196,9 +196,9 @@ public:
const_iterator cend() const noexcept;
template <class... Args>
- pair<iterator, bool> emplace(Args&&... args);
+ pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... Args>
- iterator emplace_hint(const_iterator position, Args&&... args);
+ iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args);
pair<iterator, bool> insert(const value_type& obj);
template <class P>
pair<iterator, bool> insert(P&& obj);
@@ -259,7 +259,7 @@ public:
*/
template <class Key, class Value, class KeyOfValue, unsigned int Options = 0, class Hash = hash<Key>, class Pred = equal_to<Key>,
- class Alloc = allocator<Value> >
+ class Allocator = allocator<Value> >
class hash_table
{
public:
@@ -268,7 +268,7 @@ public:
typedef key_type value_type;
typedef Hash hasher;
typedef Pred key_equal;
- typedef Alloc allocator_type;
+ typedef Allocator allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename allocator_traits<allocator_type>::pointer pointer;
@@ -330,9 +330,9 @@ public:
const_iterator cend() const noexcept;
template <class... Args>
- pair<iterator, bool> emplace(Args&&... args);
+ pair<iterator, bool> emplace(BOOST_FWD_REF(Args)... args);
template <class... Args>
- iterator emplace_hint(const_iterator position, Args&&... args);
+ iterator emplace_hint(const_iterator position, BOOST_FWD_REF(Args)... args);
pair<iterator, bool> insert(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj);
iterator insert(const_iterator hint, const value_type& obj);
diff --git a/boost/container/detail/iterator.hpp b/boost/container/detail/iterator.hpp
new file mode 100644
index 0000000000..ceb224f3ad
--- /dev/null
+++ b/boost/container/detail/iterator.hpp
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_HPP
+#define BOOST_CONTAINER_DETAIL_ITERATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/intrusive/detail/iterator.hpp>
+
+namespace boost {
+namespace container {
+
+using ::boost::intrusive::iterator_traits;
+using ::boost::intrusive::iterator_distance;
+using ::boost::intrusive::iterator_advance;
+using ::boost::intrusive::iterator;
+using ::boost::intrusive::iterator_enable_if_tag;
+using ::boost::intrusive::iterator_disable_if_tag;
+
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
diff --git a/boost/container/detail/iterator_to_raw_pointer.hpp b/boost/container/detail/iterator_to_raw_pointer.hpp
new file mode 100644
index 0000000000..83736d8bb1
--- /dev/null
+++ b/boost/container/detail/iterator_to_raw_pointer.hpp
@@ -0,0 +1,58 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
+#define BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/intrusive/pointer_traits.hpp>
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template <class T>
+inline T* iterator_to_pointer(T* i)
+{ return i; }
+
+template <class Iterator>
+inline typename boost::container::iterator_traits<Iterator>::pointer
+ iterator_to_pointer(const Iterator &i)
+{ return i.operator->(); }
+
+template <class Iterator>
+struct iterator_to_element_ptr
+{
+ typedef typename boost::container::iterator_traits<Iterator>::pointer pointer;
+ typedef typename boost::intrusive::pointer_traits<pointer>::element_type element_type;
+ typedef element_type* type;
+};
+
+template <class Iterator>
+inline typename iterator_to_element_ptr<Iterator>::type
+ iterator_to_raw_pointer(const Iterator &i)
+{
+ return ::boost::intrusive::detail::to_raw_pointer
+ ( ::boost::container::container_detail::iterator_to_pointer(i) );
+}
+
+} //namespace container_detail {
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
diff --git a/boost/container/detail/iterators.hpp b/boost/container/detail/iterators.hpp
index 0dabd3c73e..1f80d3e122 100644
--- a/boost/container/detail/iterators.hpp
+++ b/boost/container/detail/iterators.hpp
@@ -14,7 +14,11 @@
#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -26,20 +30,19 @@
#include <boost/move/utility_core.hpp>
#include <boost/intrusive/detail/reverse_iterator.hpp>
-#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-#include <boost/container/detail/variadic_templates_tools.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
#else
-#include <boost/container/detail/preprocessor.hpp>
+#include <boost/container/detail/variadic_templates_tools.hpp>
#endif
-
-#include <iterator>
+#include <boost/container/detail/iterator.hpp>
namespace boost {
namespace container {
template <class T, class Difference = std::ptrdiff_t>
class constant_iterator
- : public std::iterator
+ : public ::boost::container::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef constant_iterator<T, Difference> this_type;
@@ -150,7 +153,7 @@ class constant_iterator
template <class T, class Difference>
class value_init_construct_iterator
- : public std::iterator
+ : public ::boost::container::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef value_init_construct_iterator<T, Difference> this_type;
@@ -261,7 +264,7 @@ class value_init_construct_iterator
template <class T, class Difference>
class default_init_construct_iterator
- : public std::iterator
+ : public ::boost::container::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef default_init_construct_iterator<T, Difference> this_type;
@@ -373,7 +376,7 @@ class default_init_construct_iterator
template <class T, class Difference = std::ptrdiff_t>
class repeat_iterator
- : public std::iterator
+ : public ::boost::container::iterator
<std::random_access_iterator_tag, T, Difference>
{
typedef repeat_iterator<T, Difference> this_type;
@@ -483,7 +486,7 @@ class repeat_iterator
template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/>
class emplace_iterator
- : public std::iterator
+ : public ::boost::container::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef emplace_iterator this_type;
@@ -564,8 +567,8 @@ class emplace_iterator
//const T& operator[](difference_type) const;
//const T* operator->() const;
- template<class A>
- void construct_in_place(A &a, T* ptr)
+ template<class Allocator>
+ void construct_in_place(Allocator &a, T* ptr)
{ (*m_pe)(a, ptr); }
private:
@@ -597,54 +600,49 @@ class emplace_iterator
{ return difference_type(m_num - other.m_num); }
};
-#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class ...Args>
struct emplace_functor
{
typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
- emplace_functor(Args&&... args)
+ emplace_functor(BOOST_FWD_REF(Args)... args)
: args_(args...)
{}
- template<class A, class T>
- void operator()(A &a, T *ptr)
+ template<class Allocator, class T>
+ void operator()(Allocator &a, T *ptr)
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
- template<class A, class T, int ...IdxPack>
- void inplace_impl(A &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
+ template<class Allocator, class T, int ...IdxPack>
+ void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
{
- allocator_traits<A>::construct
+ allocator_traits<Allocator>::construct
(a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
}
container_detail::tuple<Args&...> args_;
};
-#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
-#define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template <) \
- BOOST_PP_ENUM_PARAMS(n, class P) \
- BOOST_PP_EXPR_IF(n, >) \
- struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
- { \
- BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
- ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
- BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
- \
- template<class A, class T> \
- void operator()(A &a, T *ptr) \
- { \
- allocator_traits<A>::construct \
- (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \
- } \
- BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
- }; \
- //!
-#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
-#include BOOST_PP_LOCAL_ITERATE()
+#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
+BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+struct emplace_functor##N\
+{\
+ explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
+ BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
+ \
+ template<class Allocator, class T>\
+ void operator()(Allocator &a, T *ptr)\
+ { allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
+ \
+ BOOST_MOVE_MREF##N\
+};\
+//
+BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
+#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
#endif
@@ -709,8 +707,8 @@ struct iiterator_types
{
typedef typename IIterator::value_type it_value_type;
typedef typename iiterator_node_value_type<it_value_type>::type value_type;
- typedef typename std::iterator_traits<IIterator>::pointer it_pointer;
- typedef typename std::iterator_traits<IIterator>::difference_type difference_type;
+ typedef typename boost::container::iterator_traits<IIterator>::pointer it_pointer;
+ typedef typename boost::container::iterator_traits<IIterator>::difference_type difference_type;
typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
template rebind_pointer<value_type>::type pointer;
typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
@@ -723,9 +721,9 @@ struct iiterator_types
};
template<class IIterator, bool IsConst>
-struct std_iterator
+struct iterator_types
{
- typedef typename std::iterator
+ typedef typename ::boost::container::iterator
< typename iiterator_types<IIterator>::iterator_category
, typename iiterator_types<IIterator>::value_type
, typename iiterator_types<IIterator>::difference_type
@@ -734,9 +732,9 @@ struct std_iterator
};
template<class IIterator>
-struct std_iterator<IIterator, false>
+struct iterator_types<IIterator, false>
{
- typedef typename std::iterator
+ typedef typename ::boost::container::iterator
< typename iiterator_types<IIterator>::iterator_category
, typename iiterator_types<IIterator>::value_type
, typename iiterator_types<IIterator>::difference_type
@@ -745,9 +743,9 @@ struct std_iterator<IIterator, false>
};
template<class IIterator, bool IsConst>
-class iterator
+class iterator_from_iiterator
{
- typedef typename std_iterator<IIterator, IsConst>::type types_t;
+ typedef typename iterator_types<IIterator, IsConst>::type types_t;
public:
typedef typename types_t::pointer pointer;
@@ -756,63 +754,64 @@ class iterator
typedef typename types_t::iterator_category iterator_category;
typedef typename types_t::value_type value_type;
- iterator()
+ iterator_from_iiterator()
{}
- explicit iterator(IIterator iit) BOOST_CONTAINER_NOEXCEPT
+ explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
: m_iit(iit)
{}
- iterator(iterator<IIterator, false> const& other) BOOST_CONTAINER_NOEXCEPT
+ iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
: m_iit(other.get())
{}
- iterator& operator++() BOOST_CONTAINER_NOEXCEPT
+ iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
{ ++this->m_iit; return *this; }
- iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
+ iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
{
- iterator result (*this);
+ iterator_from_iiterator result (*this);
++this->m_iit;
return result;
}
- iterator& operator--() BOOST_CONTAINER_NOEXCEPT
+ iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
{
- //If the iterator is not a bidirectional iterator, operator-- should not exist
- BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator>::value));
+ //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist
+ BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value));
--this->m_iit; return *this;
}
- iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
+ iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
{
- iterator result (*this);
+ iterator_from_iiterator result (*this);
--this->m_iit;
return result;
}
- friend bool operator== (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_iit == r.m_iit; }
- friend bool operator!= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return !(l == r); }
- reference operator*() const BOOST_CONTAINER_NOEXCEPT
+ reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
{ return (*this->m_iit).get_data(); }
- pointer operator->() const BOOST_CONTAINER_NOEXCEPT
+ pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
- const IIterator &get() const BOOST_CONTAINER_NOEXCEPT
+ const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->m_iit; }
private:
IIterator m_iit;
};
-using ::boost::intrusive::detail::reverse_iterator;
-
} //namespace container_detail {
+
+using ::boost::intrusive::reverse_iterator;
+
} //namespace container {
} //namespace boost {
diff --git a/boost/container/detail/math_functions.hpp b/boost/container/detail/math_functions.hpp
index 6853b9c59f..e499f633ec 100644
--- a/boost/container/detail/math_functions.hpp
+++ b/boost/container/detail/math_functions.hpp
@@ -16,7 +16,11 @@
#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/memory_util.hpp b/boost/container/detail/memory_util.hpp
deleted file mode 100644
index 7f055cb55b..0000000000
--- a/boost/container/detail/memory_util.hpp
+++ /dev/null
@@ -1,90 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (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)
-//
-// See http://www.boost.org/libs/container for documentation.
-//
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
-#define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
-
-#if defined(_MSC_VER)
-# pragma once
-#endif
-
-#include <boost/container/detail/config_begin.hpp>
-#include <boost/container/detail/workaround.hpp>
-
-#include <boost/container/detail/preprocessor.hpp>
-#include <boost/intrusive/detail/mpl.hpp>
-#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
-
-
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
-#define BOOST_PP_ITERATION_PARAMS_1 (3, (2, 2, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
-#include BOOST_PP_ITERATE()
-
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
-#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
-#include BOOST_PP_ITERATE()
-
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME max_size
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
-#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
-#include BOOST_PP_ITERATE()
-
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME select_on_container_copy_construction
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
-#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
-#include BOOST_PP_ITERATE()
-
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
-#ifdef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_SINGLE_ITERATION
-# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
-#else
-# define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
-#endif
-#include BOOST_PP_ITERATE()
-
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME swap
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
-#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
-#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
-#include BOOST_PP_ITERATE()
-
-namespace boost {
-namespace container {
-namespace container_detail {
-
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_pointer)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(void_pointer)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_void_pointer)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
-BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(wrapped_value_compare)
-
-} //namespace container_detail {
-} //namespace container {
-} //namespace boost {
-
-#include <boost/container/detail/config_end.hpp>
-
-#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP)
diff --git a/boost/container/detail/min_max.hpp b/boost/container/detail/min_max.hpp
new file mode 100644
index 0000000000..7486db7d05
--- /dev/null
+++ b/boost/container/detail/min_max.hpp
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (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)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
+#define BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template<class T>
+const T &max_value(const T &a, const T &b)
+{ return a > b ? a : b; }
+
+template<class T>
+const T &min_value(const T &a, const T &b)
+{ return a < b ? a : b; }
+
+} //namespace container_detail {
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
diff --git a/boost/container/detail/minimal_char_traits_header.hpp b/boost/container/detail/minimal_char_traits_header.hpp
new file mode 100644
index 0000000000..a92a31a2b4
--- /dev/null
+++ b/boost/container/detail/minimal_char_traits_header.hpp
@@ -0,0 +1,32 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
+#define BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
+#
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+#
+#//Try to avoid including <string>, as it's quite big
+#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
+ #include <iosfwd> //Dinkum libraries for MSVC define std::char_traits there
+#elif defined(BOOST_GNU_STDLIB)
+ #include <bits/char_traits.h>
+#else
+ #include <string> //Fallback
+#endif
+
+#endif //BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
diff --git a/boost/container/detail/mpl.hpp b/boost/container/detail/mpl.hpp
index ceac52a371..74b618f8c6 100644
--- a/boost/container/detail/mpl.hpp
+++ b/boost/container/detail/mpl.hpp
@@ -13,7 +13,11 @@
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -40,6 +44,13 @@ struct bool_ : integral_constant<bool, C_>
operator bool() const { return bool_::value; }
};
+template< unsigned V_ >
+struct unsigned_ : integral_constant<unsigned, V_>
+{
+ static const unsigned value = V_;
+ operator unsigned() const { return unsigned_::value; }
+};
+
typedef bool_<true> true_;
typedef bool_<false> false_;
@@ -169,6 +180,12 @@ struct ls_zeros<1>
static const std::size_t value = 0;
};
+template <std::size_t OrigSize, std::size_t RoundTo>
+struct ct_rounded_size
+{
+ static const std::size_t value = ((OrigSize-1)/RoundTo+1)*RoundTo;
+};
+
template <typename T> struct unvoid { typedef T type; };
template <> struct unvoid<void> { struct type { }; };
template <> struct unvoid<const void> { struct type { }; };
diff --git a/boost/container/detail/multiallocation_chain.hpp b/boost/container/detail/multiallocation_chain.hpp
index 96f6202671..32f87c8ae9 100644
--- a/boost/container/detail/multiallocation_chain.hpp
+++ b/boost/container/detail/multiallocation_chain.hpp
@@ -11,20 +11,26 @@
#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-
+// container
#include <boost/container/container_fwd.hpp>
-#include <boost/container/detail/utilities.hpp>
-#include <boost/container/detail/type_traits.hpp>
+// container/detail
+#include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/transform_iterator.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// intrusive
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/pointer_traits.hpp>
-#include <boost/type_traits/make_unsigned.hpp>
+// move
#include <boost/move/utility_core.hpp>
namespace boost {
@@ -47,7 +53,7 @@ class basic_multiallocation_chain
typedef bi::slist< node
, bi::linear<true>
, bi::cache_last<true>
- , bi::size_type<typename boost::make_unsigned<difference_type>::type>
+ , bi::size_type<typename boost::container::container_detail::make_unsigned<difference_type>::type>
> slist_impl_t;
slist_impl_t slist_impl_;
diff --git a/boost/container/detail/mutex.hpp b/boost/container/detail/mutex.hpp
index c53afa1f42..f8efa7fe6b 100644
--- a/boost/container/detail/mutex.hpp
+++ b/boost/container/detail/mutex.hpp
@@ -19,7 +19,11 @@
#ifndef BOOST_CONTAINER_MUTEX_HPP
#define BOOST_CONTAINER_MUTEX_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -162,7 +166,7 @@
#define BOOST_CONTAINER_TRY_LOCK(sl) !BOOST_CONTAINER_CAS_LOCK(sl)
#define BOOST_CONTAINER_RELEASE_LOCK(sl) BOOST_CONTAINER_CLEAR_LOCK(sl)
#define BOOST_CONTAINER_ACQUIRE_LOCK(sl) (BOOST_CONTAINER_CAS_LOCK(sl)? boost_interprocess_spin_acquire_lock(sl) : 0)
- #define BOOST_CONTAINER_INITIAL_LOCK(sl) (*sl = 0)
+ #define BOOST_MOVE_INITIAL_LOCK(sl) (*sl = 0)
#define BOOST_CONTAINER_DESTROY_LOCK(sl) (0)
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
//
@@ -199,7 +203,7 @@ namespace container_detail {
void operator=(const spin_mutex &);
public:
- spin_mutex() { BOOST_CONTAINER_INITIAL_LOCK(&sl); }
+ spin_mutex() { BOOST_MOVE_INITIAL_LOCK(&sl); }
void lock() { BOOST_CONTAINER_ACQUIRE_LOCK(&sl); }
void unlock() { BOOST_CONTAINER_RELEASE_LOCK(&sl); }
diff --git a/boost/container/detail/next_capacity.hpp b/boost/container/detail/next_capacity.hpp
new file mode 100644
index 0000000000..3bc98a3c91
--- /dev/null
+++ b/boost/container/detail/next_capacity.hpp
@@ -0,0 +1,75 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
+#define BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+// container
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/min_max.hpp>
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent };
+
+template<class SizeType, NextCapacityOption Option>
+struct next_capacity_calculator;
+
+template<class SizeType>
+struct next_capacity_calculator<SizeType, NextCapacityDouble>
+{
+ 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)
+ return capacity + max_value(3*(capacity+1)/5, n);
+
+ if (capacity < m3*2)
+ return capacity + max_value((capacity+1)/2, n);
+ return max_size;
+ }
+};
+
+} //namespace container_detail {
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
diff --git a/boost/container/detail/node_alloc_holder.hpp b/boost/container/detail/node_alloc_holder.hpp
index 250c559765..98c8e62baa 100644
--- a/boost/container/detail/node_alloc_holder.hpp
+++ b/boost/container/detail/node_alloc_holder.hpp
@@ -11,82 +11,63 @@
#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-#include <utility>
-#include <functional>
-
-#include <boost/move/utility_core.hpp>
-#include <boost/intrusive/options.hpp>
-
-#include <boost/container/detail/version_type.hpp>
-#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/detail/utilities.hpp>
+// container
#include <boost/container/allocator_traits.hpp>
+// container/detail
+#include <boost/container/detail/addressof.hpp>
+#include <boost/container/detail/alloc_helpers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
-#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/construct_in_place.hpp>
#include <boost/container/detail/destroyers.hpp>
-#include <boost/container/detail/memory_util.hpp>
+#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/placement_new.hpp>
-#include <boost/core/no_exceptions_support.hpp>
-
-#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-#include <boost/container/detail/preprocessor.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/version_type.hpp>
+// intrusive
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/options.hpp>
+// move
+#include <boost/move/utility_core.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
#endif
-
-#include <boost/container/detail/algorithms.hpp>
-
+// other
+#include <boost/core/no_exceptions_support.hpp>
namespace boost {
namespace container {
namespace container_detail {
-template<class ValueCompare, class Node>
-struct node_compare
- : private ValueCompare
-{
- typedef ValueCompare wrapped_value_compare;
- typedef typename wrapped_value_compare::key_type key_type;
- typedef typename wrapped_value_compare::value_type value_type;
- typedef typename wrapped_value_compare::key_of_value key_of_value;
-
- explicit node_compare(const wrapped_value_compare &pred)
- : wrapped_value_compare(pred)
- {}
-
- node_compare()
- : wrapped_value_compare()
- {}
-
- wrapped_value_compare &value_comp()
- { return static_cast<wrapped_value_compare &>(*this); }
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
- wrapped_value_compare &value_comp() const
- { return static_cast<const wrapped_value_compare &>(*this); }
-
- bool operator()(const Node &a, const Node &b) const
- { return wrapped_value_compare::operator()(a.get_data(), b.get_data()); }
-};
-
-template<class A, class ICont>
+template<class Allocator, class ICont>
struct node_alloc_holder
{
//If the intrusive container is an associative container, obtain the predicate, which will
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
value_compare, container_detail::nat) intrusive_value_compare;
- //In that case obtain the value predicate from the node predicate via wrapped_value_compare
+ //In that case obtain the value predicate from the node predicate via predicate_type
//if intrusive_value_compare is node_compare<>, nat otherwise
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
- wrapped_value_compare, container_detail::nat) value_compare;
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare,
+ predicate_type, container_detail::nat) value_compare;
- typedef allocator_traits<A> allocator_traits_type;
+ typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef ICont intrusive_container;
typedef typename ICont::value_type Node;
@@ -94,13 +75,11 @@ struct node_alloc_holder
portable_rebind_alloc<Node>::type NodeAlloc;
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
- typedef A ValAlloc;
+ typedef Allocator ValAlloc;
typedef typename node_allocator_traits_type::pointer NodePtr;
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
typedef typename node_allocator_traits_type::size_type size_type;
typedef typename node_allocator_traits_type::difference_type difference_type;
- typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
- typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<NodeAlloc>::value> alloc_version;
@@ -133,11 +112,11 @@ struct node_alloc_holder
{ this->icont().swap(x.icont()); }
//Constructors for associative containers
- explicit node_alloc_holder(const ValAlloc &a, const value_compare &c)
+ explicit node_alloc_holder(const value_compare &c, const ValAlloc &a)
: members_(a, c)
{}
- explicit node_alloc_holder(const node_alloc_holder &x, const value_compare &c)
+ explicit node_alloc_holder(const value_compare &c, const node_alloc_holder &x)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
{}
@@ -176,7 +155,7 @@ struct node_alloc_holder
void deallocate_one(const NodePtr &p)
{ AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
- #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class ...Args>
NodePtr create_node(Args &&...args)
@@ -193,28 +172,90 @@ struct node_alloc_holder
return (p);
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- NodePtr p = this->allocate_one(); \
- Deallocator node_deallocator(p, this->node_alloc()); \
- allocator_traits<NodeAlloc>::construct \
- (this->node_alloc(), container_detail::addressof(p->m_data) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- node_deallocator.release(); \
- typedef typename Node::hook_type hook_type; \
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; \
- return (p); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ NodePtr create_node()
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data));
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS1>
+ NodePtr create_node(BOOST_MOVE_UREF1)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD1);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS2>
+ NodePtr create_node(BOOST_MOVE_UREF2)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD2);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS3>
+ NodePtr create_node(BOOST_MOVE_UREF3)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD3);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS4>
+ NodePtr create_node(BOOST_MOVE_UREF4)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD4);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS5>
+ NodePtr create_node(BOOST_MOVE_UREF5)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD5);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class It>
NodePtr create_node_from_it(const It &it)
@@ -261,7 +302,7 @@ struct node_alloc_holder
Deallocator node_deallocator(NodePtr(), nalloc);
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
while(n--){
- p = container_detail::to_raw_pointer(iterator_to_pointer(itbeg));
+ p = container_detail::iterator_to_raw_pointer(itbeg);
node_deallocator.set(p);
++itbeg;
//This can throw
@@ -288,10 +329,10 @@ struct node_alloc_holder
}
}
- void clear(allocator_v1)
+ void clear(version_1)
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
- void clear(allocator_v2)
+ void clear(version_2)
{
typename NodeAlloc::multiallocation_chain chain;
allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
@@ -301,10 +342,10 @@ struct node_alloc_holder
this->node_alloc().deallocate_individual(chain);
}
- icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1)
+ icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1)
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
- icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2)
+ icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2)
{
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
NodeAlloc & nalloc = this->node_alloc();
@@ -316,11 +357,11 @@ struct node_alloc_holder
}
template<class Key, class Comparator>
- size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
+ size_type erase_key(const Key& k, const Comparator &comp, version_1)
{ return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
template<class Key, class Comparator>
- size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
+ size_type erase_key(const Key& k, const Comparator &comp, version_2)
{
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
@@ -329,7 +370,7 @@ struct node_alloc_holder
protected:
struct cloner
{
- cloner(node_alloc_holder &holder)
+ explicit cloner(node_alloc_holder &holder)
: m_holder(holder)
{}
@@ -339,6 +380,18 @@ struct node_alloc_holder
node_alloc_holder &m_holder;
};
+ struct move_cloner
+ {
+ move_cloner(node_alloc_holder &holder)
+ : m_holder(holder)
+ {}
+
+ NodePtr operator()(Node &other)
+ { return m_holder.create_node(::boost::move(other.get_data())); }
+
+ node_alloc_holder &m_holder;
+ };
+
struct members_holder
: public NodeAlloc
{
diff --git a/boost/container/detail/node_pool.hpp b/boost/container/detail/node_pool.hpp
index 60d826675a..00e35dfa8d 100644
--- a/boost/container/detail/node_pool.hpp
+++ b/boost/container/detail/node_pool.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
#define BOOST_CONTAINER_DETAIL_NODE_POOL_HPP
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -22,11 +26,8 @@
#include <boost/container/detail/pool_common_alloc.hpp>
#include <boost/container/detail/node_pool_impl.hpp>
#include <boost/container/detail/mutex.hpp>
-#include <boost/intrusive/slist.hpp>
#include <boost/move/utility_core.hpp>
#include <cstddef>
-#include <functional> //std::unary_function
-#include <algorithm> //std::swap
#include <cassert>
namespace boost {
diff --git a/boost/container/detail/node_pool_impl.hpp b/boost/container/detail/node_pool_impl.hpp
index 2450e5103e..4febf19e90 100644
--- a/boost/container/detail/node_pool_impl.hpp
+++ b/boost/container/detail/node_pool_impl.hpp
@@ -7,26 +7,31 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#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>
-#include <boost/intrusive/slist.hpp>
-#include <boost/container/detail/type_traits.hpp>
+
#include <boost/container/detail/math_functions.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pool_common.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+#include <boost/intrusive/pointer_traits.hpp>
+#include <boost/intrusive/set.hpp>
+#include <boost/intrusive/slist.hpp>
+
#include <boost/core/no_exceptions_support.hpp>
#include <boost/assert.hpp>
#include <cstddef>
@@ -57,6 +62,10 @@ class private_node_pool_impl
< node_t, bi::base_hook<slist_hook_t>
, bi::linear<true>
, bi::constant_time_size<false> >::type blockslist_t;
+
+ static size_type get_rounded_size(size_type orig_size, size_type round_to)
+ { return ((orig_size-1)/round_to+1)*round_to; }
+
public:
//!Segment manager typedef
@@ -145,7 +154,7 @@ class private_node_pool_impl
nodelist_iterator backup_list_last = backup_list.before_begin();
//Execute the algorithm and get an iterator to the last value
- size_type blocksize = get_rounded_size
+ size_type blocksize = (get_rounded_size)
(m_real_node_size*m_nodes_per_block, (size_type) alignment_of<node_t>::value);
while(it != itend){
@@ -205,7 +214,7 @@ class private_node_pool_impl
{
//check for memory leaks
BOOST_ASSERT(m_allocated==0);
- size_type blocksize = get_rounded_size
+ size_type blocksize = (get_rounded_size)
(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
//We iterate though the NodeBlock list to free the memory
@@ -298,7 +307,7 @@ class private_node_pool_impl
{
BOOST_ASSERT(num_blocks > 0);
size_type blocksize =
- get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
+ (get_rounded_size)(m_real_node_size*m_nodes_per_block, (size_type)alignment_of<node_t>::value);
BOOST_TRY{
for(size_type i = 0; i != num_blocks; ++i){
diff --git a/boost/container/detail/pair.hpp b/boost/container/detail/pair.hpp
index b7ad84c80e..6d31d3b796 100644
--- a/boost/container/detail/pair.hpp
+++ b/boost/container/detail/pair.hpp
@@ -13,7 +13,11 @@
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -24,17 +28,11 @@
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/type_traits.hpp>
+#include <boost/move/adl_move_swap.hpp> //swap
-#include <utility> //std::pair
-#include <algorithm> //std::swap
-
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
#include <boost/move/utility_core.hpp>
-
-#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-#include <boost/container/detail/preprocessor.hpp>
-#endif
-
namespace boost {
namespace container {
namespace container_detail {
@@ -166,37 +164,7 @@ struct pair
//template <class... Args1, class... Args2>
// pair(piecewise_construct_t, tuple<Args1...> first_args,
// tuple<Args2...> second_args);
-/*
- //Variadic versions
- template<class U>
- pair(BOOST_CONTAINER_PP_PARAM(U, u), typename container_detail::disable_if
- < container_detail::is_pair< typename container_detail::remove_ref_const<U>::type >, pair_nat>::type* = 0)
- : first(::boost::forward<U>(u))
- , second()
- {}
-
- #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
- template<class U, class V, class ...Args>
- pair(U &&u, V &&v)
- : first(::boost::forward<U>(u))
- , second(::boost::forward<V>(v), ::boost::forward<Args>(args)...)
- {}
-
- #else
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<class U, BOOST_PP_ENUM_PARAMS(n, class P)> \
- pair(BOOST_CONTAINER_PP_PARAM(U, u) \
- ,BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- : first(::boost::forward<U>(u)) \
- , second(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
- #endif
-*/
//pair copy assignment
pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
{
@@ -272,9 +240,8 @@ struct pair
//swap
void swap(pair& p)
{
- using std::swap;
- swap(this->first, p.first);
- swap(this->second, p.second);
+ ::boost::adl_move_swap(this->first, p.first);
+ ::boost::adl_move_swap(this->second, p.second);
}
};
@@ -309,10 +276,7 @@ inline pair<T1, T2> make_pair(T1 x, T2 y)
template <class T1, class T2>
inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
-{
- swap(x.first, y.first);
- swap(x.second, y.second);
-}
+{ x.swap(y); }
} //namespace container_detail {
} //namespace container {
diff --git a/boost/container/detail/placement_new.hpp b/boost/container/detail/placement_new.hpp
index 2489d8a45e..c50981f685 100644
--- a/boost/container/detail/placement_new.hpp
+++ b/boost/container/detail/placement_new.hpp
@@ -1,6 +1,8 @@
+#ifndef BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
+#define BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
///////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2014-2015. 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,10 +10,11 @@
//
///////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
-#define BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
-#if defined(_MSC_VER)
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/pool_common.hpp b/boost/container/detail/pool_common.hpp
index 11fb6c2e50..61d0612ed1 100644
--- a/boost/container/detail/pool_common.hpp
+++ b/boost/container/detail/pool_common.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
#define BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/pool_common_alloc.hpp b/boost/container/detail/pool_common_alloc.hpp
index dfae7efd13..72e9c8d278 100644
--- a/boost/container/detail/pool_common_alloc.hpp
+++ b/boost/container/detail/pool_common_alloc.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
#define BOOST_CONTAINER_DETAIL_POOL_COMMON_ALLOC_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/preprocessor.hpp b/boost/container/detail/preprocessor.hpp
deleted file mode 100644
index 838eff2ca1..0000000000
--- a/boost/container/detail/preprocessor.hpp
+++ /dev/null
@@ -1,228 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-//
-// (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_DETAIL_PREPROCESSOR_HPP
-#define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
-
-#if defined(_MSC_VER)
-# pragma once
-#endif
-
-#include <boost/container/detail/config_begin.hpp>
-#include <boost/container/detail/workaround.hpp>
-#include <boost/move/utility_core.hpp>
-
-#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-//#error "This file is not needed when perfect forwarding is available"
-#endif //BOOST_CONTAINER_PERFECT_FORWARDING
-
-#include <boost/preprocessor/iteration/local.hpp>
-#include <boost/preprocessor/punctuation/paren_if.hpp>
-#include <boost/preprocessor/punctuation/comma_if.hpp>
-#include <boost/preprocessor/control/expr_if.hpp>
-#include <boost/preprocessor/cat.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
-#include <boost/preprocessor/repetition/enum_trailing.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
-#include <boost/preprocessor/arithmetic/sub.hpp>
-#include <boost/preprocessor/arithmetic/add.hpp>
-#include <boost/preprocessor/iteration/iterate.hpp>
-
-#define BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS 10
-
-//Note:
-//We define template parameters as const references to
-//be able to bind temporaries. After that we will un-const them.
-//This cast is ugly but it is necessary until "perfect forwarding"
-//is achieved in C++0x. Meanwhile, if we want to be able to
-//bind rvalues with non-const references, we have to be ugly
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- #define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
- BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
- //!
-#else
- #define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
- const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
- //!
-#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-
-#define BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q(z, n, Data) \
-const BOOST_PP_CAT(Q, n) & BOOST_PP_CAT(q, n) \
-//!
-
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- #define BOOST_CONTAINER_PP_PARAM(U, u) \
- U && u \
- //!
-#else
- #define BOOST_CONTAINER_PP_PARAM(U, u) \
- const U & u \
- //!
-#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-
- #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) )) \
- //!
-
-#else //BOOST_NO_CXX11_RVALUE_REFERENCES
-
- #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
- BOOST_PP_CAT(m_p, n) (const_cast<BOOST_PP_CAT(P, n) &>(BOOST_PP_CAT(p, n))) \
- //!
-#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-
- #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-
- namespace boost {
- namespace container {
- namespace container_detail {
- template<class T>
- struct ref_holder;
-
- template<class T>
- struct ref_holder<T &>
- {
- explicit ref_holder(T &t)
- : t_(t)
- {}
- T &t_;
- T & get() { return t_; }
- };
-
- template<class T>
- struct ref_holder<const T>
- {
- explicit ref_holder(const T &t)
- : t_(t)
- {}
- const T &t_;
- const T & get() { return t_; }
- };
-
- template<class T>
- struct ref_holder<const T &&>
- {
- explicit ref_holder(const T &t)
- : t_(t)
- {}
- const T &t_;
- const T & get() { return t_; }
- };
-
- template<class T>
- struct ref_holder
- {
- explicit ref_holder(T &&t)
- : t_(t)
- {}
- T &t_;
- T && get() { return ::boost::move(t_); }
- };
-
- template<class T>
- struct ref_holder<T &&>
- {
- explicit ref_holder(T &&t)
- : t_(t)
- {}
- T &t_;
- T && get() { return ::boost::move(t_); }
- };
-
- } //namespace container_detail {
- } //namespace container {
- } //namespace boost {
-
- #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
- ::boost::container::container_detail::ref_holder<BOOST_PP_CAT(P, n)> BOOST_PP_CAT(m_p, n); \
- //!
-
- #else //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
-
- #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
- BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n); \
- //!
-
- #endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-
-#else //BOOST_NO_CXX11_RVALUE_REFERENCES
-
- #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data) \
- BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n); \
- //!
-#endif //#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-
-#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-
- #define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) BOOST_PP_CAT(this->m_p, n).get() \
- //!
-
-#else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-
- #define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
- ::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
- //!
-
-#endif //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
-
-#define BOOST_CONTAINER_PP_PARAM_INC(z, n, data) \
- BOOST_PP_CAT(++this->m_p, n) \
-//!
-
-#define BOOST_CONTAINER_PP_IDENTITY(z, n, data) data
-
-
-#define BOOST_CONTAINER_PP_PARAM_FORWARD(z, n, data) \
-::boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
-//!
-
-#define BOOST_CONTAINER_PP_DECLVAL(z, n, data) \
-::boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
-//!
-
-#define BOOST_CONTAINER_PP_MEMBER_IT_FORWARD(z, n, data) \
-BOOST_PP_CAT(*this->m_p, n) \
-//!
-
-#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \
- BOOST_PP_CAT(class P, n) = void \
-//!
-
-#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT(z, n, default_type) \
- BOOST_PP_CAT(class P, n) = default_type \
-//!
-
-#define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \
- static BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n); \
-//!
-
-#define BOOST_CONTAINER_PP_PARAM_PASS(z, n, data) \
- BOOST_PP_CAT(p, n) \
-//!
-
-#define BOOST_CONTAINER_PP_FWD_TYPE(z, n, data) \
- typename ::boost::move_detail::forward_type< BOOST_PP_CAT(P, n) >::type \
-//!
-
-#include <boost/container/detail/config_end.hpp>
-
-//#else
-
-//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-//#error "This file is not needed when perfect forwarding is available"
-//#endif //BOOST_CONTAINER_PERFECT_FORWARDING
-
-#endif //#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
diff --git a/boost/container/detail/singleton.hpp b/boost/container/detail/singleton.hpp
index a2372c3a96..6fd6a54f30 100644
--- a/boost/container/detail/singleton.hpp
+++ b/boost/container/detail/singleton.hpp
@@ -22,7 +22,11 @@
#ifndef BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
#define BOOST_CONTAINER_DETAIL_SINGLETON_DETAIL_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/std_fwd.hpp b/boost/container/detail/std_fwd.hpp
index a2edeccff1..a2931c134b 100644
--- a/boost/container/detail/std_fwd.hpp
+++ b/boost/container/detail/std_fwd.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
#define BOOST_CONTAINER_DETAIL_STD_FWD_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -25,6 +29,12 @@
#pragma GCC diagnostic ignored "-Wc++11-extensions"
#define BOOST_CONTAINER_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
#define BOOST_CONTAINER_STD_NS_END _LIBCPP_END_NAMESPACE_STD
+#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION) //GCC >= 4.6
+ #define BOOST_CONTAINER_STD_NS_BEG namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION
+ #define BOOST_CONTAINER_STD_NS_END _GLIBCXX_END_NAMESPACE_VERSION } // namespace
+#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE) //GCC >= 4.2
+ #define BOOST_CONTAINER_STD_NS_BEG _GLIBCXX_BEGIN_NAMESPACE(std)
+ #define BOOST_CONTAINER_STD_NS_END _GLIBCXX_END_NAMESPACE
#else
#define BOOST_CONTAINER_STD_NS_BEG namespace std{
#define BOOST_CONTAINER_STD_NS_END }
@@ -49,6 +59,11 @@ struct forward_iterator_tag;
struct bidirectional_iterator_tag;
struct random_access_iterator_tag;
+template<class Container>
+class insert_iterator;
+
+struct allocator_arg_t;
+
BOOST_CONTAINER_STD_NS_END
#ifdef BOOST_CONTAINER_CLANG_INLINE_STD_NS
diff --git a/boost/container/detail/to_raw_pointer.hpp b/boost/container/detail/to_raw_pointer.hpp
new file mode 100644
index 0000000000..0b4445a942
--- /dev/null
+++ b/boost/container/detail/to_raw_pointer.hpp
@@ -0,0 +1,33 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP
+#define BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/intrusive/detail/to_raw_pointer.hpp>
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+using ::boost::intrusive::detail::to_raw_pointer;
+
+} //namespace container_detail {
+} //namespace container {
+} //namespace boost {
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_TO_RAW_POINTER_HPP
diff --git a/boost/container/detail/transform_iterator.hpp b/boost/container/detail/transform_iterator.hpp
index c4e746c389..ba64c7de79 100644
--- a/boost/container/detail/transform_iterator.hpp
+++ b/boost/container/detail/transform_iterator.hpp
@@ -14,15 +14,18 @@
#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-
#include <boost/container/detail/type_traits.hpp>
-#include <iterator>
+#include <boost/container/detail/iterator.hpp>
namespace boost {
namespace container {
@@ -58,7 +61,7 @@ struct operator_arrow_proxy<T&>
template <class Iterator, class UnaryFunction>
class transform_iterator
: public UnaryFunction
- , public std::iterator
+ , public boost::container::iterator
< typename Iterator::iterator_category
, typename container_detail::remove_reference<typename UnaryFunction::result_type>::type
, typename Iterator::difference_type
@@ -156,10 +159,10 @@ class transform_iterator
{ return UnaryFunction::operator()(*m_it); }
void advance(typename Iterator::difference_type n)
- { std::advance(m_it, n); }
+ { boost::container::iterator_advance(m_it, n); }
typename Iterator::difference_type distance_to(const transform_iterator &other)const
- { return std::distance(other.m_it, m_it); }
+ { return boost::container::iterator_distance(other.m_it, m_it); }
};
template <class Iterator, class UnaryFunc>
diff --git a/boost/container/detail/tree.hpp b/boost/container/detail/tree.hpp
index e59bca0887..0f90b5a4e2 100644
--- a/boost/container/detail/tree.hpp
+++ b/boost/container/detail/tree.hpp
@@ -11,62 +11,66 @@
#ifndef BOOST_CONTAINER_TREE_HPP
#define BOOST_CONTAINER_TREE_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+// container
+#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
+#include <boost/container/options.hpp>
-#include <boost/container/detail/utilities.hpp>
+// container/detail
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/compare_functors.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
-#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
-#include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/pair.hpp>
#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/allocator_traits.hpp>
-#include <boost/container/options.hpp>
-
-//
+// intrusive
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/rbtree.hpp>
#include <boost/intrusive/avltree.hpp>
#include <boost/intrusive/splaytree.hpp>
#include <boost/intrusive/sgtree.hpp>
-//
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+// move
#include <boost/move/utility_core.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/core/no_exceptions_support.hpp>
-//
-#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-#include <boost/container/detail/preprocessor.hpp>
+// move/detail
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
#endif
-
-#include <utility> //std::pair
-#include <iterator>
-#include <algorithm>
+// other
+#include <boost/core/no_exceptions_support.hpp>
namespace boost {
namespace container {
namespace container_detail {
-template<class Key, class Value, class KeyCompare, class KeyOfValue>
+template<class Key, class T, class Compare, class KeyOfValue>
struct tree_value_compare
- : public KeyCompare
+ : public Compare
{
- typedef Value value_type;
- typedef KeyCompare key_compare;
+ typedef T value_type;
+ typedef Compare key_compare;
typedef KeyOfValue key_of_value;
typedef Key key_type;
explicit tree_value_compare(const key_compare &kcomp)
- : KeyCompare(kcomp)
+ : Compare(kcomp)
{}
tree_value_compare()
- : KeyCompare()
+ : Compare()
{}
const key_compare &key_comp() const
@@ -75,25 +79,29 @@ struct tree_value_compare
key_compare &key_comp()
{ return static_cast<key_compare &>(*this); }
- template<class T>
+ template<class U>
struct is_key
{
- static const bool value = is_same<const T, const key_type>::value;
+ static const bool value = is_same<const U, const key_type>::value;
};
- template<class T>
- typename enable_if_c<is_key<T>::value, const key_type &>::type
- key_forward(const T &key) const
+ template<class U>
+ typename enable_if_c<is_key<U>::value, const key_type &>::type
+ key_forward(const U &key) const
{ return key; }
- template<class T>
- typename enable_if_c<!is_key<T>::value, const key_type &>::type
- key_forward(const T &key) const
+ template<class U>
+ typename enable_if_c<!is_key<U>::value, const key_type &>::type
+ key_forward(const U &key) const
{ return KeyOfValue()(key); }
template<class KeyType, class KeyType2>
bool operator()(const KeyType &key1, const KeyType2 &key2) const
{ return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
+
+ template<class KeyType, class KeyType2>
+ bool operator()(const KeyType &key1, const KeyType2 &key2)
+ { return key_compare::operator()(this->key_forward(key1), this->key_forward(key2)); }
};
template<class VoidPointer, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
@@ -183,17 +191,17 @@ struct tree_node
internal_type m_data;
- template<class A, class B>
- void do_assign(const std::pair<const A, B> &p)
+ template<class T1, class T2>
+ void do_assign(const std::pair<const T1, T2> &p)
{
- const_cast<A&>(m_data.first) = p.first;
+ const_cast<T1&>(m_data.first) = p.first;
m_data.second = p.second;
}
- template<class A, class B>
- void do_assign(const pair<const A, B> &p)
+ template<class T1, class T2>
+ void do_assign(const pair<const T1, T2> &p)
{
- const_cast<A&>(m_data.first) = p.first;
+ const_cast<T1&>(m_data.first) = p.first;
m_data.second = p.second;
}
@@ -201,17 +209,17 @@ struct tree_node
void do_assign(const V &v)
{ m_data = v; }
- template<class A, class B>
- void do_move_assign(std::pair<const A, B> &p)
+ template<class T1, class T2>
+ void do_move_assign(std::pair<const T1, T2> &p)
{
- const_cast<A&>(m_data.first) = ::boost::move(p.first);
+ const_cast<T1&>(m_data.first) = ::boost::move(p.first);
m_data.second = ::boost::move(p.second);
}
- template<class A, class B>
- void do_move_assign(pair<const A, B> &p)
+ template<class T1, class T2>
+ void do_move_assign(pair<const T1, T2> &p)
{
- const_cast<A&>(m_data.first) = ::boost::move(p.first);
+ const_cast<T1&>(m_data.first) = ::boost::move(p.first);
m_data.second = ::boost::move(p.second);
}
@@ -314,20 +322,21 @@ struct intrusive_tree_dispatch
>::type type;
};
-template<class A, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
+template<class Allocator, class ValueCompare, boost::container::tree_type_enum tree_type_value, bool OptimizeSize>
struct intrusive_tree_type
{
private:
typedef typename boost::container::
- allocator_traits<A>::value_type value_type;
+ allocator_traits<Allocator>::value_type value_type;
typedef typename boost::container::
- allocator_traits<A>::void_pointer void_pointer;
+ allocator_traits<Allocator>::void_pointer void_pointer;
typedef typename boost::container::
- allocator_traits<A>::size_type size_type;
+ allocator_traits<Allocator>::size_type size_type;
typedef typename container_detail::tree_node
< value_type, void_pointer
, tree_type_value, OptimizeSize> node_type;
- typedef node_compare<ValueCompare, node_type> node_compare_type;
+ typedef value_to_node_compare
+ <node_type, ValueCompare> node_compare_type;
//Deducing the hook type from node_type (e.g. node_type::hook_type) would
//provoke an early instantiation of node_type that could ruin recursive
//tree definitions, so retype the complete type to avoid any problem.
@@ -391,10 +400,10 @@ class RecyclingCloner
{}
static void do_assign(node_ptr_type &p, const node_type &other, bool_<true>)
- { p->do_assign(other.m_data); }
+ { p->do_move_assign(const_cast<node_type &>(other).m_data); }
static void do_assign(node_ptr_type &p, const node_type &other, bool_<false>)
- { p->do_move_assign(const_cast<node_type &>(other).m_data); }
+ { p->do_assign(other.m_data); }
node_ptr_type operator()(const node_type &other) const
{
@@ -425,7 +434,7 @@ class RecyclingCloner
};
template<class KeyValueCompare, class Node>
-//where KeyValueCompare is tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
+//where KeyValueCompare is tree_value_compare<Key, T, Compare, KeyOfValue>
struct key_node_compare
: private KeyValueCompare
{
@@ -454,35 +463,35 @@ struct key_node_compare
{ return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2)); }
};
-template <class Key, class Value, class KeyOfValue,
- class KeyCompare, class A,
+template <class Key, class T, class KeyOfValue,
+ class Compare, class Allocator,
class Options = tree_assoc_defaults>
class tree
: protected container_detail::node_alloc_holder
- < A
+ < Allocator
, typename container_detail::intrusive_tree_type
- < A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue> //ValComp
+ < Allocator, tree_value_compare<Key, T, Compare, KeyOfValue> //ValComp
, Options::tree_type, Options::optimize_size>::type
>
{
typedef tree_value_compare
- <Key, Value, KeyCompare, KeyOfValue> ValComp;
+ <Key, T, Compare, KeyOfValue> ValComp;
typedef typename container_detail::intrusive_tree_type
- < A, ValComp, Options::tree_type
+ < Allocator, ValComp, Options::tree_type
, Options::optimize_size>::type Icont;
typedef container_detail::node_alloc_holder
- <A, Icont> AllocHolder;
+ <Allocator, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
- typedef tree < Key, Value, KeyOfValue
- , KeyCompare, A, Options> ThisType;
+ typedef tree < Key, T, KeyOfValue
+ , Compare, Allocator, Options> ThisType;
typedef typename AllocHolder::NodeAlloc NodeAlloc;
+ typedef boost::container::
+ allocator_traits<NodeAlloc> allocator_traits_type;
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef typename Icont::iterator iiterator;
typedef typename Icont::const_iterator iconst_iterator;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
- typedef typename AllocHolder::allocator_v1 allocator_v1;
- typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef intrusive_tree_proxy<Options::tree_type> intrusive_tree_proxy_t;
@@ -491,22 +500,22 @@ class tree
public:
typedef Key key_type;
- typedef Value value_type;
- typedef A allocator_type;
- typedef KeyCompare key_compare;
+ typedef T value_type;
+ typedef Allocator allocator_type;
+ typedef Compare key_compare;
typedef ValComp value_compare;
typedef typename boost::container::
- allocator_traits<A>::pointer pointer;
+ allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::
- allocator_traits<A>::const_pointer const_pointer;
+ allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::
- allocator_traits<A>::reference reference;
+ allocator_traits<Allocator>::reference reference;
typedef typename boost::container::
- allocator_traits<A>::const_reference const_reference;
+ allocator_traits<Allocator>::const_reference const_reference;
typedef typename boost::container::
- allocator_traits<A>::size_type size_type;
+ allocator_traits<Allocator>::size_type size_type;
typedef typename boost::container::
- allocator_traits<A>::difference_type difference_type;
+ allocator_traits<Allocator>::difference_type difference_type;
typedef difference_type tree_difference_type;
typedef pointer tree_pointer;
typedef const_pointer tree_const_pointer;
@@ -519,17 +528,17 @@ class tree
typedef key_node_compare<value_compare, Node> KeyNodeCompare;
public:
- typedef container_detail::iterator<iiterator, false> iterator;
- typedef container_detail::iterator<iiterator, true > const_iterator;
- typedef container_detail::reverse_iterator<iterator> reverse_iterator;
- typedef container_detail::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef container_detail::iterator_from_iiterator<iiterator, false> iterator;
+ typedef container_detail::iterator_from_iiterator<iiterator, true > const_iterator;
+ typedef boost::container::reverse_iterator<iterator> reverse_iterator;
+ typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
tree()
- : AllocHolder(ValComp(key_compare()))
+ : AllocHolder()
{}
explicit tree(const key_compare& comp, const allocator_type& a = allocator_type())
- : AllocHolder(a, ValComp(comp))
+ : AllocHolder(ValComp(comp), a)
{}
explicit tree(const allocator_type& a)
@@ -542,11 +551,11 @@ class tree
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, allocator_v1>::value
+ || container_detail::is_same<alloc_version, version_1>::value
>::type * = 0
#endif
)
- : AllocHolder(a, value_compare(comp))
+ : AllocHolder(value_compare(comp), a)
{
//Use cend() as hint to achieve linear time for
//ordered ranges as required by the standard
@@ -570,11 +579,11 @@ class tree
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< !(container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, allocator_v1>::value)
+ || container_detail::is_same<alloc_version, version_1>::value)
>::type * = 0
#endif
)
- : AllocHolder(a, value_compare(comp))
+ : AllocHolder(value_compare(comp), a)
{
if(unique_insertion){
//Use cend() as hint to achieve linear time for
@@ -588,7 +597,7 @@ class tree
else{
//Optimized allocation and construction
this->allocate_many_and_construct
- ( first, std::distance(first, last)
+ ( first, boost::container::iterator_distance(first, last)
, insert_equal_end_hint_functor<Node, Icont>(this->icont()));
}
}
@@ -599,11 +608,11 @@ class tree
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, allocator_v1>::value
+ || container_detail::is_same<alloc_version, version_1>::value
>::type * = 0
#endif
)
- : AllocHolder(a, value_compare(comp))
+ : AllocHolder(value_compare(comp), a)
{
for ( ; first != last; ++first){
this->push_back_impl(*first);
@@ -616,45 +625,45 @@ class tree
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< !(container_detail::is_input_iterator<InputIterator>::value
- || container_detail::is_same<alloc_version, allocator_v1>::value)
+ || container_detail::is_same<alloc_version, version_1>::value)
>::type * = 0
#endif
)
- : AllocHolder(a, value_compare(comp))
+ : AllocHolder(value_compare(comp), a)
{
//Optimized allocation and construction
this->allocate_many_and_construct
- ( first, std::distance(first, last)
+ ( first, boost::container::iterator_distance(first, last)
, container_detail::push_back_functor<Node, Icont>(this->icont()));
}
tree(const tree& x)
- : AllocHolder(x, x.value_comp())
+ : AllocHolder(x.value_comp(), x)
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
tree(BOOST_RV_REF(tree) x)
- : AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.value_comp())
+ : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x), x.value_comp())
{}
tree(const tree& x, const allocator_type &a)
- : AllocHolder(a, x.value_comp())
+ : AllocHolder(x.value_comp(), a)
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
tree(BOOST_RV_REF(tree) x, const allocator_type &a)
- : AllocHolder(a, x.value_comp())
+ : AllocHolder(x.value_comp(), a)
{
if(this->node_alloc() == x.node_alloc()){
this->icont().swap(x.icont());
}
else{
this->icont().clone_from
- (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+ (x.icont(), typename AllocHolder::move_cloner(*this), Destroyer(this->node_alloc()));
}
}
@@ -693,6 +702,8 @@ class tree
}
tree& operator=(BOOST_RV_REF(tree) x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
{
BOOST_ASSERT(this != &x);
NodeAlloc &this_alloc = this->node_alloc();
@@ -735,10 +746,10 @@ class tree
public:
// accessors:
value_compare value_comp() const
- { return this->icont().value_comp().value_comp(); }
+ { return this->icont().value_comp().predicate(); }
key_compare key_comp() const
- { return this->icont().value_comp().value_comp().key_comp(); }
+ { return this->icont().value_comp().predicate().key_comp(); }
allocator_type get_allocator() const
{ return allocator_type(this->node_alloc()); }
@@ -817,6 +828,8 @@ class tree
{ return AllocHolder::max_size(); }
void swap(ThisType& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
{ AllocHolder::swap(x); }
public:
@@ -851,9 +864,9 @@ class tree
template<class MovableConvertible>
iterator insert_unique_commit
- (BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
+ (BOOST_FWD_REF(MovableConvertible) v, insert_commit_data &data)
{
- NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv));
+ NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(v));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_unique_commit(*tmp, data));
destroy_deallocator.release();
@@ -872,13 +885,13 @@ class tree
}
template<class MovableConvertible>
- std::pair<iterator,bool> insert_unique(BOOST_FWD_REF(MovableConvertible) mv)
+ std::pair<iterator,bool> insert_unique(BOOST_FWD_REF(MovableConvertible) v)
{
insert_commit_data data;
std::pair<iterator,bool> ret =
- this->insert_unique_check(KeyOfValue()(mv), data);
+ this->insert_unique_check(KeyOfValue()(v), data);
if(ret.second){
- ret.first = this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
+ ret.first = this->insert_unique_commit(boost::forward<MovableConvertible>(v), data);
}
return ret;
}
@@ -886,9 +899,9 @@ class tree
private:
template<class MovableConvertible>
- void push_back_impl(BOOST_FWD_REF(MovableConvertible) mv)
+ void push_back_impl(BOOST_FWD_REF(MovableConvertible) v)
{
- NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
+ NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
//push_back has no-throw guarantee so avoid any deallocator/destroyer
this->icont().push_back(*tmp);
}
@@ -925,18 +938,18 @@ class tree
public:
- #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class... Args>
- std::pair<iterator, bool> emplace_unique(Args&&... args)
+ std::pair<iterator, bool> emplace_unique(BOOST_FWD_REF(Args)... args)
{ return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...)); }
template <class... Args>
- iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+ iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
{ return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...)); }
template <class... Args>
- iterator emplace_equal(Args&&... args)
+ iterator emplace_equal(BOOST_FWD_REF(Args)... args)
{
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
@@ -946,7 +959,7 @@ class tree
}
template <class... Args>
- iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+ iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
@@ -955,49 +968,41 @@ class tree
return ret;
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- std::pair<iterator, bool> emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- return this->emplace_unique_impl \
- (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint_unique(const_iterator hint \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- return this->emplace_unique_hint_impl \
- (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
- scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
- iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); \
- destroy_deallocator.release(); \
- return ret; \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint_equal(const_iterator hint \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
- scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
- iterator ret(this->icont().insert_equal(hint.get(), *tmp)); \
- destroy_deallocator.release(); \
- return ret; \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ #define BOOST_CONTAINER_TREE_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ std::pair<iterator, bool> emplace_unique(BOOST_MOVE_UREF##N)\
+ { return this->emplace_unique_impl(AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint_unique(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(BOOST_MOVE_FWD##N)); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_equal(BOOST_MOVE_UREF##N)\
+ {\
+ NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
+ scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
+ iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));\
+ destroy_deallocator.release();\
+ return ret;\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
+ scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
+ iterator ret(this->icont().insert_equal(hint.get(), *tmp));\
+ destroy_deallocator.release();\
+ return ret;\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_TREE_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_TREE_EMPLACE_CODE
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
iterator insert_unique(const_iterator hint, const value_type& v)
{
@@ -1010,14 +1015,14 @@ class tree
}
template<class MovableConvertible>
- iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
+ iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
{
insert_commit_data data;
std::pair<iterator,bool> ret =
- this->insert_unique_check(hint, KeyOfValue()(mv), data);
+ this->insert_unique_check(hint, KeyOfValue()(v), data);
if(!ret.second)
return ret.first;
- return this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
+ return this->insert_unique_commit(boost::forward<MovableConvertible>(v), data);
}
template <class InputIterator>
@@ -1037,9 +1042,9 @@ class tree
}
template<class MovableConvertible>
- iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
+ iterator insert_equal(BOOST_FWD_REF(MovableConvertible) v)
{
- NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
+ NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
destroy_deallocator.release();
@@ -1056,9 +1061,9 @@ class tree
}
template<class MovableConvertible>
- iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
+ iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
{
- NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
+ NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
destroy_deallocator.release();
@@ -1141,10 +1146,10 @@ class tree
{ intrusive_tree_proxy_t::rebalance(this->icont()); }
friend bool operator==(const tree& x, const tree& y)
- { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
friend bool operator<(const tree& x, const tree& y)
- { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+ { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
friend bool operator!=(const tree& x, const tree& y)
{ return !(x == y); }
@@ -1164,17 +1169,25 @@ class tree
} //namespace container_detail {
} //namespace container {
-/*
+
+template <class T>
+struct has_trivial_destructor_after_move;
+
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class K, class V, class KOV,
-class C, class A>
+template <class Key, class T, class KeyOfValue, class Compare, class Allocator, class Options>
struct has_trivial_destructor_after_move
- <boost::container::container_detail::tree<K, V, KOV, C, A> >
+ <
+ ::boost::container::container_detail::tree
+ <Key, T, KeyOfValue, Compare, Allocator, Options>
+ >
{
- static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
-*/
+
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
diff --git a/boost/container/detail/type_traits.hpp b/boost/container/detail/type_traits.hpp
index 9ff361454a..1ae2426863 100644
--- a/boost/container/detail/type_traits.hpp
+++ b/boost/container/detail/type_traits.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
// (C) Copyright John Maddock 2000.
-// (C) Copyright Ion Gaztanaga 2005-2013.
+// (C) Copyright Ion Gaztanaga 2005-2015.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -8,230 +8,60 @@
//
// See http://www.boost.org/libs/container for documentation.
//
-// The alignment_of implementation comes from John Maddock's boost::alignment_of code
+// The alignment and Type traits implementation comes from
+// John Maddock's TypeTraits library.
//
+// Some other tricks come from Howard Hinnant's papers and StackOverflow replies
//////////////////////////////////////////////////////////////////////////////
-
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
-#include <boost/container/detail/config_begin.hpp>
-#include <boost/container/detail/workaround.hpp>
+#include <boost/move/detail/type_traits.hpp>
namespace boost {
namespace container {
namespace container_detail {
-struct nat{};
-
-template <typename U>
-struct LowPriorityConversion
-{
- // Convertible from T with user-defined-conversion rank.
- LowPriorityConversion(const U&) { }
-};
-
-//boost::alignment_of yields to 10K lines of preprocessed code, so we
-//need an alternative
-template <typename T> struct alignment_of;
-
-template <typename T>
-struct alignment_of_hack
-{
- char c;
- T t;
- alignment_of_hack();
-};
-
-template <unsigned A, unsigned S>
-struct alignment_logic
-{
- enum{ value = A < S ? A : S };
-};
-
-template< typename T >
-struct alignment_of
-{
- enum{ value = alignment_logic
- < sizeof(alignment_of_hack<T>) - sizeof(T)
- , sizeof(T)>::value };
-};
-
-//This is not standard, but should work with all compilers
-union max_align
-{
- char char_;
- short short_;
- int int_;
- long long_;
- #ifdef BOOST_HAS_LONG_LONG
- long long long_long_;
- #endif
- float float_;
- double double_;
- long double long_double_;
- void * void_ptr_;
-};
-
-template<class T>
-struct remove_reference
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_reference<T&>
-{
- typedef T type;
-};
-
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-
-template<class T>
-struct remove_reference<T&&>
-{
- typedef T type;
-};
-
-#else
-
-} // namespace container_detail {
-} //namespace container {
-
-template<class T>
-class rv;
-
-namespace container {
-namespace container_detail {
-
-template<class T>
-struct remove_reference< ::boost::rv<T> >
-{
- typedef T type;
-};
-
-#endif
-
-template<class T>
-struct is_reference
-{
- enum { value = false };
-};
-
-template<class T>
-struct is_reference<T&>
-{
- enum { value = true };
-};
-
-template<class T>
-struct is_pointer
-{
- enum { value = false };
-};
-
-template<class T>
-struct is_pointer<T*>
-{
- enum { value = true };
-};
-
-template <typename T>
-struct add_reference
-{
- typedef T& type;
-};
-
-template<class T>
-struct add_reference<T&>
-{
- typedef T& type;
-};
-
-template<>
-struct add_reference<void>
-{
- typedef nat &type;
-};
-
-template<>
-struct add_reference<const void>
-{
- typedef const nat &type;
-};
-
-template <class T>
-struct add_const_reference
-{ typedef const T &type; };
-
-template <class T>
-struct add_const_reference<T&>
-{ typedef T& type; };
-
-template <class T>
-struct add_const
-{ typedef const T type; };
-
-template <typename T, typename U>
-struct is_same
-{
- typedef char yes_type;
- struct no_type
- {
- char padding[8];
- };
-
- template <typename V>
- static yes_type is_same_tester(V*, V*);
- static no_type is_same_tester(...);
-
- static T *t;
- static U *u;
-
- static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
-};
-
-template<class T>
-struct remove_const
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_const< const T>
-{
- typedef T type;
-};
-
-template<class T>
-struct remove_ref_const
-{
- typedef typename remove_const< typename remove_reference<T>::type >::type type;
-};
-
-template <class T>
-struct make_unsigned
-{
- typedef T type;
-};
-
-template <> struct make_unsigned<bool> {};
-template <> struct make_unsigned<signed char> {typedef unsigned char type;};
-template <> struct make_unsigned<signed short> {typedef unsigned short type;};
-template <> struct make_unsigned<signed int> {typedef unsigned int type;};
-template <> struct make_unsigned<signed long> {typedef unsigned long type;};
-#ifdef BOOST_HAS_LONG_LONG
-template <> struct make_unsigned<signed long long> {typedef unsigned long long type;};
-#endif
-
-} // namespace container_detail
+using ::boost::move_detail::is_same;
+using ::boost::move_detail::is_pointer;
+using ::boost::move_detail::add_reference;
+using ::boost::move_detail::add_const;
+using ::boost::move_detail::add_const_reference;
+using ::boost::move_detail::remove_const;
+using ::boost::move_detail::remove_reference;
+using ::boost::move_detail::make_unsigned;
+using ::boost::move_detail::is_floating_point;
+using ::boost::move_detail::is_integral;
+using ::boost::move_detail::is_enum;
+using ::boost::move_detail::is_pod;
+using ::boost::move_detail::is_empty;
+using ::boost::move_detail::is_trivially_destructible;
+using ::boost::move_detail::is_trivially_default_constructible;
+using ::boost::move_detail::is_trivially_copy_constructible;
+using ::boost::move_detail::is_trivially_move_constructible;
+using ::boost::move_detail::is_trivially_copy_assignable;
+using ::boost::move_detail::is_trivially_move_assignable;
+using ::boost::move_detail::is_nothrow_default_constructible;
+using ::boost::move_detail::is_nothrow_copy_constructible;
+using ::boost::move_detail::is_nothrow_move_constructible;
+using ::boost::move_detail::is_nothrow_copy_assignable;
+using ::boost::move_detail::is_nothrow_move_assignable;
+using ::boost::move_detail::is_nothrow_swappable;
+using ::boost::move_detail::alignment_of;
+using ::boost::move_detail::aligned_storage;
+using ::boost::move_detail::nat;
+using ::boost::move_detail::max_align_t;
+
+} //namespace container_detail {
} //namespace container {
} //namespace boost {
-#include <boost/container/detail/config_end.hpp>
-
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
diff --git a/boost/container/detail/value_init.hpp b/boost/container/detail/value_init.hpp
index 68f9678358..eb4c976d92 100644
--- a/boost/container/detail/value_init.hpp
+++ b/boost/container/detail/value_init.hpp
@@ -13,7 +13,11 @@
#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/variadic_templates_tools.hpp b/boost/container/detail/variadic_templates_tools.hpp
index b07fe3050e..ec8b8ceef0 100644
--- a/boost/container/detail/variadic_templates_tools.hpp
+++ b/boost/container/detail/variadic_templates_tools.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/detail/version_type.hpp b/boost/container/detail/version_type.hpp
index 2eabc62483..a20b3eedaa 100644
--- a/boost/container/detail/version_type.hpp
+++ b/boost/container/detail/version_type.hpp
@@ -16,7 +16,11 @@
#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -30,8 +34,6 @@ namespace boost{
namespace container {
namespace container_detail {
-//using namespace boost;
-
template <class T, unsigned V>
struct version_type
: public container_detail::integral_constant<unsigned, V>
@@ -95,6 +97,11 @@ struct is_version
};
} //namespace container_detail {
+
+typedef container_detail::integral_constant<unsigned, 0> version_0;
+typedef container_detail::integral_constant<unsigned, 1> version_1;
+typedef container_detail::integral_constant<unsigned, 2> version_2;
+
} //namespace container {
} //namespace boost{
diff --git a/boost/container/detail/workaround.hpp b/boost/container/detail/workaround.hpp
index 55ebe339ce..026e65d6bb 100644
--- a/boost/container/detail/workaround.hpp
+++ b/boost/container/detail/workaround.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -22,18 +26,6 @@
#define BOOST_CONTAINER_PERFECT_FORWARDING
#endif
-#if defined(BOOST_NO_CXX11_NOEXCEPT)
- #if defined(BOOST_MSVC)
- #define BOOST_CONTAINER_NOEXCEPT throw()
- #else
- #define BOOST_CONTAINER_NOEXCEPT
- #endif
- #define BOOST_CONTAINER_NOEXCEPT_IF(x)
-#else
- #define BOOST_CONTAINER_NOEXCEPT noexcept
- #define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
-#endif
-
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
&& (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700)
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
diff --git a/boost/container/flat_map.hpp b/boost/container/flat_map.hpp
index e7ff31a30b..ef0e1cb252 100644
--- a/boost/container/flat_map.hpp
+++ b/boost/container/flat_map.hpp
@@ -7,29 +7,41 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#ifndef BOOST_CONTAINER_FLAT_MAP_HPP
#define BOOST_CONTAINER_FLAT_MAP_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-
+// container
+#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
-#include <utility>
-#include <functional>
-#include <memory>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
#include <boost/container/detail/flat_tree.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/allocator_traits.hpp>
-#include <boost/container/throw_exception.hpp>
+#include <boost/container/detail/algorithm.hpp> //equal()
+// move
#include <boost/move/utility_core.hpp>
-#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// intrusive
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
+//others
#include <boost/core/no_exceptions_support.hpp>
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -88,7 +100,7 @@ static D force_copy(S s)
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
-template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< Key, T> > >
+template <class Key, class T, class Compare = std::less<Key>, class Allocator = new_allocator< std::pair< Key, T> > >
#else
template <class Key, class T, class Compare, class Allocator>
#endif
@@ -115,6 +127,7 @@ class flat_map
typedef typename impl_tree_t::value_type impl_value_type;
typedef typename impl_tree_t::const_iterator impl_const_iterator;
+ typedef typename impl_tree_t::iterator impl_iterator;
typedef typename impl_tree_t::allocator_type impl_allocator_type;
typedef container_detail::flat_tree_value_compare
< Compare
@@ -128,6 +141,9 @@ 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;
+ public:
+ typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
+ private:
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -170,7 +186,7 @@ class flat_map
flat_map()
: m_flat_tree()
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -181,7 +197,7 @@ class flat_map
explicit flat_map(const Compare& comp, const allocator_type& a = allocator_type())
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -191,7 +207,7 @@ class flat_map
explicit flat_map(const allocator_type& a)
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -205,7 +221,20 @@ class flat_map
const allocator_type& a = allocator_type())
: m_flat_tree(true, first, last, comp, container_detail::force<impl_allocator_type>(a))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_map(InputIterator first, InputIterator last, const allocator_type& a)
+ : m_flat_tree(true, first, last, Compare(), container_detail::force<impl_allocator_type>(a))
+ {
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -224,7 +253,7 @@ class flat_map
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
: m_flat_tree(ordered_range, first, last, comp, a)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -238,7 +267,19 @@ class flat_map
const allocator_type& a = allocator_type())
: m_flat_tree(true, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! allocator, and inserts elements from the range [il.begin() ,il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ flat_map(std::initializer_list<value_type> il, const allocator_type& a)
+ : m_flat_tree(true, il.begin(), il.end(), Compare(), container_detail::force<impl_allocator_type>(a))
+ {
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -256,7 +297,7 @@ class flat_map
const allocator_type& a = allocator_type())
: m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
#endif
@@ -267,7 +308,7 @@ class flat_map
flat_map(const flat_map& x)
: m_flat_tree(x.m_flat_tree)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -280,7 +321,7 @@ class flat_map
flat_map(BOOST_RV_REF(flat_map) x)
: m_flat_tree(boost::move(x.m_flat_tree))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -290,7 +331,7 @@ class flat_map
flat_map(const flat_map& x, const allocator_type &a)
: m_flat_tree(x.m_flat_tree, a)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -301,7 +342,7 @@ class flat_map
flat_map(BOOST_RV_REF(flat_map) x, const allocator_type &a)
: m_flat_tree(boost::move(x.m_flat_tree), a)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -321,7 +362,8 @@ class flat_map
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
flat_map& operator=(BOOST_RV_REF(flat_map) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
{ m_flat_tree = boost::move(x.m_flat_tree); return *this; }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -334,11 +376,11 @@ class flat_map
}
#endif
- //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! <b>Effects</b>: Returns a copy of the allocator that
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -348,7 +390,7 @@ class flat_map
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -358,7 +400,7 @@ class flat_map
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//////////////////////////////////////////////
@@ -372,7 +414,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -380,7 +422,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -388,7 +430,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -396,7 +438,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -405,7 +447,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -414,7 +456,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -423,7 +465,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -432,7 +474,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -440,7 +482,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -448,7 +490,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -457,7 +499,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -466,7 +508,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
//////////////////////////////////////////////
@@ -480,7 +522,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -488,7 +530,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -496,7 +538,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.max_size(); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -505,7 +547,7 @@ class flat_map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+ size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -539,7 +581,7 @@ class flat_map
//! Effects: If there is no key equivalent to x in the flat_map, inserts
//! value_type(x, T()) into the flat_map.
//!
- //! Returns: Allocator reference to the mapped_type corresponding to x in *this.
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
mapped_type &operator[](const key_type& k);
@@ -547,7 +589,7 @@ class flat_map
//! Effects: If there is no key equivalent to x in the flat_map, inserts
//! value_type(move(x), T()) into the flat_map (the key is move-constructed)
//!
- //! Returns: Allocator reference to the mapped_type corresponding to x in *this.
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
mapped_type &operator[](key_type &&k) ;
@@ -556,7 +598,23 @@ class flat_map
BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
#endif
- //! Returns: Allocator reference to the element whose key is equivalent to x.
+ //! @copydoc ::boost::container::flat_set::nth(size_type)
+ iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
+
+ //! @copydoc ::boost::container::flat_set::nth(size_type) const
+ const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
+
+ //! @copydoc ::boost::container::flat_set::index_of(iterator)
+ size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+ { return m_flat_tree.index_of(container_detail::force_copy<impl_iterator>(p)); }
+
+ //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
+ size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
+
+ //! Returns: A reference to the element whose key is equivalent to x.
//!
//! Throws: An exception object of type out_of_range if no such element is present.
//!
@@ -570,7 +628,7 @@ class flat_map
return i->second;
}
- //! Returns: Allocator reference to the element whose key is equivalent to x.
+ //! Returns: A reference to the element whose key is equivalent to x.
//!
//! Throws: An exception object of type out_of_range if no such element is present.
//!
@@ -590,7 +648,7 @@ class flat_map
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object x of type T constructed with
//! std::forward<Args>(args)... if and only if there is no element in the container
@@ -605,7 +663,7 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- std::pair<iterator,bool> emplace(Args&&... args)
+ std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return container_detail::force_copy< std::pair<iterator, bool> >(m_flat_tree.emplace_unique(boost::forward<Args>(args)...)); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -621,32 +679,34 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
+ iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return container_detail::force_copy<iterator>
(m_flat_tree.emplace_hint_unique( container_detail::force_copy<impl_const_iterator>(hint)
, boost::forward<Args>(args)...));
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return container_detail::force_copy< std::pair<iterator, bool> > \
- (m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint(const_iterator hint \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique \
- (container_detail::force_copy<impl_const_iterator>(hint) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ #define BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+ {\
+ return container_detail::force_copy< std::pair<iterator, bool> >\
+ (m_flat_tree.emplace_unique(BOOST_MOVE_FWD##N));\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_unique\
+ (container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_FLAT_MAP_EMPLACE_CODE
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
//! with key equivalent to the key of x.
@@ -660,7 +720,7 @@ class flat_map
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
std::pair<iterator,bool> insert(const value_type& x)
- { return container_detail::force_copy<std::pair<iterator,bool> >(
+ { return container_detail::force_copy<std::pair<iterator,bool> >(
m_flat_tree.insert_unique(container_detail::force<impl_value_type>(x))); }
//! <b>Effects</b>: Inserts a new value_type move constructed from the pair if and
@@ -850,6 +910,8 @@ class flat_map
//!
//! <b>Complexity</b>: Constant.
void swap(flat_map& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
{ m_flat_tree.swap(x.m_flat_tree); }
//! <b>Effects</b>: erase(a.begin(),a.end()).
@@ -857,7 +919,7 @@ class flat_map
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear() BOOST_CONTAINER_NOEXCEPT
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ m_flat_tree.clear(); }
//////////////////////////////////////////////
@@ -893,7 +955,7 @@ class flat_map
iterator find(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.find(x)); }
- //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.s
@@ -913,7 +975,7 @@ class flat_map
iterator lower_bound(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -927,7 +989,7 @@ class flat_map
iterator upper_bound(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -950,7 +1012,7 @@ class flat_map
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator==(const flat_map& x, const flat_map& y)
- { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
@@ -962,7 +1024,7 @@ class flat_map
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator<(const flat_map& x, const flat_map& y)
- { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+ { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! <b>Effects</b>: Returns true if x is greater than y
//!
@@ -1020,10 +1082,13 @@ class flat_map
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class K, class T, class C, class Allocator>
-struct has_trivial_destructor_after_move<boost::container::flat_map<K, T, C, Allocator> >
+template <class Key, class T, class Compare, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::flat_map<Key, T, Compare, Allocator> >
{
- static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -1060,7 +1125,7 @@ namespace container {
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
//! (e.g. <i>allocator< std::pair<Key, T> > </i>).
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
-template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< Key, T> > >
+template <class Key, class T, class Compare = std::less<Key>, class Allocator = new_allocator< std::pair< Key, T> > >
#else
template <class Key, class T, class Compare, class Allocator>
#endif
@@ -1085,6 +1150,7 @@ class flat_multimap
typedef typename impl_tree_t::value_type impl_value_type;
typedef typename impl_tree_t::const_iterator impl_const_iterator;
+ typedef typename impl_tree_t::iterator impl_iterator;
typedef typename impl_tree_t::allocator_type impl_allocator_type;
typedef container_detail::flat_tree_value_compare
< Compare
@@ -1098,6 +1164,9 @@ 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;
+ public:
+ typedef typename impl_tree_t::stored_allocator_type impl_stored_allocator_type;
+ private:
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -1139,7 +1208,7 @@ class flat_multimap
flat_multimap()
: m_flat_tree()
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1151,7 +1220,7 @@ class flat_multimap
const allocator_type& a = allocator_type())
: m_flat_tree(comp, container_detail::force<impl_allocator_type>(a))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1161,7 +1230,7 @@ class flat_multimap
explicit flat_multimap(const allocator_type& a)
: m_flat_tree(container_detail::force<impl_allocator_type>(a))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1176,7 +1245,20 @@ class flat_multimap
const allocator_type& a = allocator_type())
: m_flat_tree(false, first, last, comp, container_detail::force<impl_allocator_type>(a))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Constructs an empty flat_multimap using the specified
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_multimap(InputIterator first, InputIterator last, const allocator_type& a)
+ : m_flat_tree(false, first, last, Compare(), container_detail::force<impl_allocator_type>(a))
+ {
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1195,7 +1277,7 @@ class flat_multimap
const allocator_type& a = allocator_type())
: m_flat_tree(ordered_range, first, last, comp, a)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1208,7 +1290,19 @@ class flat_multimap
flat_multimap(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
: m_flat_tree(false, il.begin(), il.end(), comp, container_detail::force<impl_allocator_type>(a))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Constructs an empty flat_map using the specified
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ flat_multimap(std::initializer_list<value_type> il, const allocator_type& a)
+ : m_flat_tree(false, il.begin(), il.end(), Compare(), container_detail::force<impl_allocator_type>(a))
+ {
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1225,7 +1319,7 @@ class flat_multimap
const allocator_type& a = allocator_type())
: m_flat_tree(ordered_range, il.begin(), il.end(), comp, a)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
#endif
@@ -1236,7 +1330,7 @@ class flat_multimap
flat_multimap(const flat_multimap& x)
: m_flat_tree(x.m_flat_tree)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1248,7 +1342,7 @@ class flat_multimap
flat_multimap(BOOST_RV_REF(flat_multimap) x)
: m_flat_tree(boost::move(x.m_flat_tree))
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1258,7 +1352,7 @@ class flat_multimap
flat_multimap(const flat_multimap& x, const allocator_type &a)
: m_flat_tree(x.m_flat_tree, a)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1269,7 +1363,7 @@ class flat_multimap
flat_multimap(BOOST_RV_REF(flat_multimap) x, const allocator_type &a)
: m_flat_tree(boost::move(x.m_flat_tree), a)
{
- //Allocator type must be std::pair<Key, T>
+ //A type must be std::pair<Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<Key, T>, typename Allocator::value_type>::value));
}
@@ -1283,7 +1377,8 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
{ m_flat_tree = boost::move(x.m_flat_tree); return *this; }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -1298,11 +1393,11 @@ class flat_multimap
}
#endif
- //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! <b>Effects</b>: Returns a copy of the allocator that
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<allocator_type>(m_flat_tree.get_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1312,7 +1407,7 @@ class flat_multimap
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1322,7 +1417,7 @@ class flat_multimap
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force<stored_allocator_type>(m_flat_tree.get_stored_allocator()); }
//////////////////////////////////////////////
@@ -1336,7 +1431,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1344,7 +1439,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.begin()); }
//! <b>Effects</b>: Returns an iterator to the end of the container.
@@ -1352,7 +1447,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1360,7 +1455,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -1369,7 +1464,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1378,7 +1473,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rbegin()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -1387,7 +1482,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1396,7 +1491,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.rend()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
@@ -1404,7 +1499,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cbegin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
@@ -1412,7 +1507,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_iterator>(m_flat_tree.cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1421,7 +1516,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crbegin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1430,7 +1525,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::force_copy<const_reverse_iterator>(m_flat_tree.crend()); }
//////////////////////////////////////////////
@@ -1444,7 +1539,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.empty(); }
//! <b>Effects</b>: Returns the number of the elements contained in the container.
@@ -1452,7 +1547,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.size(); }
//! <b>Effects</b>: Returns the largest possible size of the container.
@@ -1460,7 +1555,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.max_size(); }
//! <b>Effects</b>: Number of elements for which memory has been allocated.
@@ -1469,7 +1564,7 @@ class flat_multimap
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+ size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_flat_tree.capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1493,13 +1588,23 @@ class flat_multimap
void shrink_to_fit()
{ m_flat_tree.shrink_to_fit(); }
- //////////////////////////////////////////////
- //
- // modifiers
- //
- //////////////////////////////////////////////
+ //! @copydoc ::boost::container::flat_set::nth(size_type)
+ iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
+
+ //! @copydoc ::boost::container::flat_set::nth(size_type) const
+ const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return container_detail::force_copy<iterator>(m_flat_tree.nth(n)); }
+
+ //! @copydoc ::boost::container::flat_set::index_of(iterator)
+ size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+ { return m_flat_tree.index_of(container_detail::force_copy<impl_iterator>(p)); }
+
+ //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
+ size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return m_flat_tree.index_of(container_detail::force_copy<impl_const_iterator>(p)); }
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -1510,7 +1615,7 @@ class flat_multimap
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace(Args&&... args)
+ iterator emplace(BOOST_FWD_REF(Args)... args)
{ return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(boost::forward<Args>(args)...)); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -1526,31 +1631,30 @@ class flat_multimap
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace_hint(const_iterator hint, Args&&... args)
+ iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal
(container_detail::force_copy<impl_const_iterator>(hint), boost::forward<Args>(args)...));
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal \
- (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint(const_iterator hint \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal \
- (container_detail::force_copy<impl_const_iterator>(hint) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ #define BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(BOOST_MOVE_UREF##N)\
+ { return container_detail::force_copy<iterator>(m_flat_tree.emplace_equal(BOOST_MOVE_FWD##N)); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ return container_detail::force_copy<iterator>(m_flat_tree.emplace_hint_equal\
+ (container_detail::force_copy<impl_const_iterator>(hint) BOOST_MOVE_I##N BOOST_MOVE_FWD##N));\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_FLAT_MULTIMAP_EMPLACE_CODE
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
//! newly inserted element.
@@ -1740,6 +1844,8 @@ class flat_multimap
//!
//! <b>Complexity</b>: Constant.
void swap(flat_multimap& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
{ m_flat_tree.swap(x.m_flat_tree); }
//! <b>Effects</b>: erase(a.begin(),a.end()).
@@ -1747,7 +1853,7 @@ class flat_multimap
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear() BOOST_CONTAINER_NOEXCEPT
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ m_flat_tree.clear(); }
//////////////////////////////////////////////
@@ -1803,7 +1909,7 @@ class flat_multimap
iterator lower_bound(const key_type& x)
{ return container_detail::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key
+ //! <b>Returns</b>: A const iterator pointing to the first element with key
//! not less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -1817,7 +1923,7 @@ class flat_multimap
iterator upper_bound(const key_type& x)
{return container_detail::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key
+ //! <b>Returns</b>: A const iterator pointing to the first element with key
//! not less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -1840,7 +1946,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator==(const flat_multimap& x, const flat_multimap& y)
- { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
@@ -1852,7 +1958,7 @@ class flat_multimap
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator<(const flat_multimap& x, const flat_multimap& y)
- { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+ { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! <b>Effects</b>: Returns true if x is greater than y
//!
@@ -1887,10 +1993,13 @@ namespace boost {
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class K, class T, class C, class Allocator>
-struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T, C, Allocator> >
+template <class Key, class T, class Compare, class Allocator>
+struct has_trivial_destructor_after_move< boost::container::flat_multimap<Key, T, Compare, Allocator> >
{
- static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
} //namespace boost {
@@ -1899,4 +2008,4 @@ struct has_trivial_destructor_after_move< boost::container::flat_multimap<K, T,
#include <boost/container/detail/config_end.hpp>
-#endif /* BOOST_CONTAINER_FLAT_MAP_HPP */
+#endif // BOOST_CONTAINER_FLAT_MAP_HPP
diff --git a/boost/container/flat_set.hpp b/boost/container/flat_set.hpp
index 1307f3492f..8f592798d2 100644
--- a/boost/container/flat_set.hpp
+++ b/boost/container/flat_set.hpp
@@ -7,31 +7,43 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#ifndef BOOST_CONTAINER_FLAT_SET_HPP
#define BOOST_CONTAINER_FLAT_SET_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+// container
+#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
-#include <utility>
-#include <functional>
-#include <memory>
+#include <boost/container/new_allocator.hpp> //new_allocator
+// container/detail
#include <boost/container/detail/flat_tree.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/allocator_traits.hpp>
+// move
+#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
#include <boost/move/detail/move_helpers.hpp>
-#include <boost/move/traits.hpp>
-
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
+// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
+
namespace boost {
namespace container {
@@ -51,7 +63,7 @@ namespace container {
//! \tparam Compare is the comparison functor used to order keys
//! \tparam Allocator is the allocator to be used to allocate memory for this container
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
-template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
+template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key> >
#else
template <class Key, class Compare, class Allocator>
#endif
@@ -132,6 +144,16 @@ class flat_set
: base_t(true, first, last, comp, a)
{}
+ //! <b>Effects</b>: Constructs an empty container using the specified
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ flat_set(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(true, first, last, Compare(), a)
+ {}
+
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [first ,last). This function
//! is more efficient than the normal range creation for ordered ranges.
@@ -158,9 +180,16 @@ class flat_set
flat_set(std::initializer_list<value_type> il, const Compare& comp = Compare(),
const allocator_type& a = allocator_type())
: base_t(true, il.begin(), il.end(), comp, a)
- {
+ {}
- }
+ //! <b>Effects</b>: Constructs an empty container using the specified
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! comp and otherwise N logN, where N is il.begin() - il.end().
+ flat_set(std::initializer_list<value_type> il, const allocator_type& a)
+ : base_t(true, il.begin(), il.end(), Compare(), a)
+ {}
//! <b>Effects</b>: Constructs an empty container using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
@@ -175,9 +204,7 @@ class flat_set
flat_set(ordered_unique_range_t, std::initializer_list<value_type> il,
const Compare& comp = Compare(), const allocator_type& a = allocator_type())
: base_t(ordered_range, il.begin(), il.end(), comp, a)
- {
-
- }
+ {}
#endif
//! <b>Effects</b>: Copy constructs the container.
@@ -187,13 +214,13 @@ class flat_set
: base_t(static_cast<const base_t&>(x))
{}
- //! <b>Effects</b>: Move constructs thecontainer. Constructs *this using mx's resources.
+ //! <b>Effects</b>: Move constructs thecontainer. Constructs *this using x's resources.
//!
//! <b>Complexity</b>: Constant.
//!
- //! <b>Postcondition</b>: mx is emptied.
- flat_set(BOOST_RV_REF(flat_set) mx)
- : base_t(boost::move(static_cast<base_t&>(mx)))
+ //! <b>Postcondition</b>: x is emptied.
+ flat_set(BOOST_RV_REF(flat_set) x)
+ : base_t(BOOST_MOVE_BASE(base_t, x))
{}
//! <b>Effects</b>: Copy constructs a container using the specified allocator.
@@ -204,11 +231,11 @@ class flat_set
{}
//! <b>Effects</b>: Move constructs a container using the specified allocator.
- //! Constructs *this using mx's resources.
+ //! Constructs *this using x's resources.
//!
- //! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise
- flat_set(BOOST_RV_REF(flat_set) mx, const allocator_type &a)
- : base_t(boost::move(static_cast<base_t&>(mx)), a)
+ //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise
+ flat_set(BOOST_RV_REF(flat_set) x, const allocator_type &a)
+ : base_t(BOOST_MOVE_BASE(base_t, x), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
@@ -224,8 +251,9 @@ class flat_set
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
flat_set& operator=(BOOST_RV_REF(flat_set) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
- { return static_cast<flat_set&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
+ { return static_cast<flat_set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Copy all elements from il to *this.
@@ -240,11 +268,11 @@ class flat_set
#endif
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
- //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! <b>Effects</b>: Returns a copy of the allocator that
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT;
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
@@ -253,7 +281,7 @@ class flat_set
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT;
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
@@ -262,35 +290,35 @@ class flat_set
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT;
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns an iterator to the first element contained in the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT;
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns an iterator to the end of the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT;
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -298,7 +326,7 @@ class flat_set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -306,7 +334,7 @@ class flat_set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
//! of the reversed container.
@@ -314,7 +342,7 @@ class flat_set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed container.
@@ -322,21 +350,21 @@ class flat_set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -344,7 +372,7 @@ class flat_set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed container.
@@ -352,28 +380,28 @@ class flat_set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns true if the container contains no elements.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT;
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns the number of the elements contained in the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT;
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns the largest possible size of the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT;
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Number of elements for which memory has been allocated.
//! capacity() is always greater than or equal to size().
@@ -381,7 +409,7 @@ class flat_set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT;
+ size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
//! effect. Otherwise, it is a request for allocation of additional memory.
@@ -410,7 +438,7 @@ class flat_set
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object x of type Key constructed with
//! std::forward<Args>(args)... if and only if there is no element in the container
@@ -425,7 +453,7 @@ class flat_set
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- std::pair<iterator,bool> emplace(Args&&... args)
+ std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -441,26 +469,24 @@ class flat_set
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace_hint(const_iterator p, Args&&... args)
+ iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_hint_unique \
- (p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_FLAT_SET_EMPLACE_CODE
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
@@ -613,14 +639,16 @@ class flat_set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- void swap(flat_set& x);
+ void swap(flat_set& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value );
//! <b>Effects</b>: erase(a.begin(),a.end()).
//!
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear() BOOST_CONTAINER_NOEXCEPT;
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns the comparison object out
//! of which a was constructed.
@@ -640,12 +668,63 @@ class flat_set
//! <b>Complexity</b>: Logarithmic.
iterator find(const key_type& x);
- //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
const_iterator find(const key_type& x) const;
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns an iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns a const_iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW;
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns an iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ //! <b>Requires</b>: begin() <= p <= end().
+ //!
+ //! <b>Effects</b>: Returns the index of the element pointed by p
+ //! and size() if p == end().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW;
+
#endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Returns</b>: The number of elements with key equivalent to x.
@@ -661,7 +740,7 @@ class flat_set
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -673,7 +752,7 @@ class flat_set
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -750,10 +829,13 @@ class flat_set
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class Key, class C, class Allocator>
-struct has_trivial_destructor_after_move<boost::container::flat_set<Key, C, Allocator> >
+template <class Key, class Compare, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::flat_set<Key, Compare, Allocator> >
{
- static const bool value = has_trivial_destructor_after_move<Allocator>::value &&has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -777,7 +859,7 @@ namespace container {
//! \tparam Compare is the comparison functor used to order keys
//! \tparam Allocator is the allocator to be used to allocate memory for this container
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
-template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
+template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key> >
#else
template <class Key, class Compare, class Allocator>
#endif
@@ -840,6 +922,12 @@ class flat_multiset
: base_t(false, first, last, comp, a)
{}
+ //! @copydoc ::boost::container::flat_set::flat_set(InputIterator, InputIterator, const allocator_type&)
+ template <class InputIterator>
+ flat_multiset(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(false, first, last, Compare(), a)
+ {}
+
//! <b>Effects</b>: Constructs an empty flat_multiset using the specified comparison object and
//! allocator, and inserts elements from the ordered range [first ,last ). This function
//! is more efficient than the normal range creation for ordered ranges.
@@ -863,6 +951,11 @@ class flat_multiset
: base_t(false, il.begin(), il.end(), comp, a)
{}
+ //! @copydoc ::boost::container::flat_set::flat_set(std::initializer_list<value_type>, const allocator_type&)
+ flat_multiset(std::initializer_list<value_type> il, const allocator_type& a)
+ : base_t(false, il.begin(), il.end(), Compare(), a)
+ {}
+
//! @copydoc ::boost::container::flat_set::flat_set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare& comp, const allocator_type&)
flat_multiset(ordered_unique_range_t, std::initializer_list<value_type> il,
const Compare& comp = Compare(), const allocator_type& a = allocator_type())
@@ -876,8 +969,8 @@ class flat_multiset
{}
//! @copydoc ::boost::container::flat_set(flat_set &&)
- flat_multiset(BOOST_RV_REF(flat_multiset) mx)
- : base_t(boost::move(static_cast<base_t&>(mx)))
+ flat_multiset(BOOST_RV_REF(flat_multiset) x)
+ : base_t(boost::move(static_cast<base_t&>(x)))
{}
//! @copydoc ::boost::container::flat_set(const flat_set &, const allocator_type &)
@@ -886,8 +979,8 @@ class flat_multiset
{}
//! @copydoc ::boost::container::flat_set(flat_set &&, const allocator_type &)
- flat_multiset(BOOST_RV_REF(flat_multiset) mx, const allocator_type &a)
- : base_t(boost::move(static_cast<base_t&>(mx)), a)
+ flat_multiset(BOOST_RV_REF(flat_multiset) x, const allocator_type &a)
+ : base_t(BOOST_MOVE_BASE(base_t, x), a)
{}
//! @copydoc ::boost::container::flat_set::operator=(const flat_set &)
@@ -895,9 +988,10 @@ class flat_multiset
{ return static_cast<flat_multiset&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
//! @copydoc ::boost::container::flat_set::operator=(flat_set &&)
- flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
- { return static_cast<flat_multiset&>(this->base_t::operator=(boost::move(static_cast<base_t&>(mx)))); }
+ flat_multiset& operator=(BOOST_RV_REF(flat_multiset) x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
+ { return static_cast<flat_multiset&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! @copydoc ::boost::container::flat_set::operator=(std::initializer_list<value_type>)
@@ -912,61 +1006,61 @@ class flat_multiset
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! @copydoc ::boost::container::flat_set::get_allocator()
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT;
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::get_stored_allocator()
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT;
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::get_stored_allocator() const
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT;
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::begin()
- iterator begin() BOOST_CONTAINER_NOEXCEPT;
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::begin() const
const_iterator begin() const;
//! @copydoc ::boost::container::flat_set::cbegin() const
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::end()
- iterator end() BOOST_CONTAINER_NOEXCEPT;
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::end() const
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::cend() const
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::rbegin()
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::rbegin() const
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::crbegin() const
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::rend()
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::rend() const
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::crend() const
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::empty() const
- bool empty() const BOOST_CONTAINER_NOEXCEPT;
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::size() const
- size_type size() const BOOST_CONTAINER_NOEXCEPT;
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::max_size() const
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT;
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::capacity() const
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT;
+ size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::reserve(size_type)
void reserve(size_type cnt);
@@ -982,7 +1076,7 @@ class flat_multiset
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type Key constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -993,7 +1087,7 @@ class flat_multiset
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace(Args&&... args)
+ iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -1008,26 +1102,24 @@ class flat_multiset
//!
//! <b>Note</b>: If an element is inserted it might invalidate elements.
template <class... Args>
- iterator emplace_hint(const_iterator p, Args&&... args)
+ iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_hint_equal \
- (p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_FLAT_MULTISET_EMPLACE_CODE
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
@@ -1140,10 +1232,12 @@ class flat_multiset
iterator erase(const_iterator first, const_iterator last);
//! @copydoc ::boost::container::flat_set::swap
- void swap(flat_multiset& x);
+ void swap(flat_multiset& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value );
//! @copydoc ::boost::container::flat_set::clear
- void clear() BOOST_CONTAINER_NOEXCEPT;
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::flat_set::key_comp
key_compare key_comp() const;
@@ -1157,6 +1251,18 @@ class flat_multiset
//! @copydoc ::boost::container::flat_set::find(const key_type& ) const
const_iterator find(const key_type& x) const;
+ //! @copydoc ::boost::container::flat_set::nth(size_type)
+ iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ //! @copydoc ::boost::container::flat_set::nth(size_type) const
+ const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW;
+
+ //! @copydoc ::boost::container::flat_set::index_of(iterator)
+ size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW;
+
+ //! @copydoc ::boost::container::flat_set::index_of(const_iterator) const
+ size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW;
+
//! @copydoc ::boost::container::flat_set::count(const key_type& ) const
size_type count(const key_type& x) const;
@@ -1233,10 +1339,13 @@ class flat_multiset
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class Key, class C, class Allocator>
-struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, C, Allocator> >
+template <class Key, class Compare, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::flat_multiset<Key, Compare, Allocator> >
{
- static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -1247,4 +1356,4 @@ namespace container {
#include <boost/container/detail/config_end.hpp>
-#endif /* BOOST_CONTAINER_FLAT_SET_HPP */
+#endif // BOOST_CONTAINER_FLAT_SET_HPP
diff --git a/boost/container/list.hpp b/boost/container/list.hpp
index 33cc6ee0f8..54da6df518 100644
--- a/boost/container/list.hpp
+++ b/boost/container/list.hpp
@@ -6,48 +6,53 @@
//
// See http://www.boost.org/libs/container for documentation.
//
-
+//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_LIST_HPP
#define BOOST_CONTAINER_LIST_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+
+// container
#include <boost/container/container_fwd.hpp>
-#include <boost/container/detail/version_type.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/algorithm.hpp>
+#include <boost/container/detail/compare_functors.hpp>
+#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/throw_exception.hpp>
+#include <boost/container/detail/node_alloc_holder.hpp>
+#include <boost/container/detail/version_type.hpp>
+// move
#include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp>
-#include <boost/move/detail/move_helpers.hpp>
#include <boost/move/traits.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+# include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+
+// intrusive
#include <boost/intrusive/pointer_traits.hpp>
-#include <boost/container/detail/utilities.hpp>
-#include <boost/container/detail/algorithms.hpp>
#include <boost/intrusive/list.hpp>
+// other
#include <boost/assert.hpp>
-#include <boost/container/detail/node_alloc_holder.hpp>
-
-#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-#else
-//Preprocessor library to emulate perfect forwarding
-#include <boost/container/detail/preprocessor.hpp>
-#endif
-
+// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
-#include <iterator>
-#include <utility>
-#include <memory>
-#include <functional>
-#include <algorithm>
-
namespace boost {
namespace container {
@@ -124,7 +129,7 @@ struct intrusive_list_type
//! \tparam T The type of object that is stored in the list
//! \tparam Allocator The allocator used for all internal memory management
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
-template <class T, class Allocator = std::allocator<T> >
+template <class T, class Allocator = new_allocator<T> >
#else
template <class T, class Allocator>
#endif
@@ -141,44 +146,14 @@ class list
typedef typename AllocHolder::ValAlloc ValAlloc;
typedef typename AllocHolder::Node Node;
typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
- typedef typename AllocHolder::allocator_v1 allocator_v1;
- typedef typename AllocHolder::allocator_v2 allocator_v2;
typedef typename AllocHolder::alloc_version alloc_version;
typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
-
- class equal_to_value
- {
- typedef typename AllocHolder::value_type value_type;
- const value_type &t_;
-
- public:
- equal_to_value(const value_type &t)
- : t_(t)
- {}
-
- bool operator()(const value_type &t)const
- { return t_ == t; }
- };
-
- template<class Pred>
- struct ValueCompareToNodeCompare
- : Pred
- {
- ValueCompareToNodeCompare(Pred pred)
- : Pred(pred)
- {}
-
- bool operator()(const Node &a, const Node &b) const
- { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
-
- bool operator()(const Node &a) const
- { return static_cast<const Pred&>(*this)(a.m_data); }
- };
+ typedef boost::container::equal_to_value<Allocator> equal_to_value_type;
BOOST_COPYABLE_AND_MOVABLE(list)
- typedef container_detail::iterator<typename Icont::iterator, false> iterator_impl;
- typedef container_detail::iterator<typename Icont::iterator, true> const_iterator_impl;
+ typedef container_detail::iterator_from_iiterator<typename Icont::iterator, false> iterator_impl;
+ typedef container_detail::iterator_from_iiterator<typename Icont::iterator, true> const_iterator_impl;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -199,8 +174,8 @@ class list
typedef BOOST_CONTAINER_IMPDEF(NodeAlloc) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
//////////////////////////////////////////////
//
@@ -222,12 +197,12 @@ class list
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit list(const allocator_type &a) BOOST_CONTAINER_NOEXCEPT
+ explicit list(const allocator_type &a) BOOST_NOEXCEPT_OR_NOTHROW
: AllocHolder(a)
{}
- //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
- //! and inserts n copies of value.
+ //! <b>Effects</b>: Constructs a list
+ //! and inserts n value-initialized value_types.
//!
//! <b>Throws</b>: If allocator_type's default constructor
//! throws or T's default or copy constructor throws.
@@ -244,6 +219,17 @@ class list
//! throws or T's default or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
+ list(size_type n, const allocator_type &a)
+ : AllocHolder(a)
+ { this->resize(n); }
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
list(size_type n, const T& value, const Allocator& a = Allocator())
: AllocHolder(a)
{ this->insert(this->cbegin(), n, value); }
@@ -259,13 +245,13 @@ class list
: AllocHolder(x)
{ this->insert(this->cbegin(), x.begin(), x.end()); }
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
list(BOOST_RV_REF(list) x)
- : AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
+ : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x))
{}
//! <b>Effects</b>: Copy constructs a list using the specified allocator.
@@ -280,7 +266,7 @@ class list
{ this->insert(this->cbegin(), x.begin(), x.end()); }
//! <b>Effects</b>: Move constructor sing the specified allocator.
- //! Moves mx's resources to *this.
+ //! Moves x's resources to *this.
//!
//! <b>Throws</b>: If allocation or value_type's copy constructor throws.
//!
@@ -292,7 +278,7 @@ class list
this->icont().swap(x.icont());
}
else{
- this->insert(this->cbegin(), x.begin(), x.end());
+ this->insert(this->cbegin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
}
}
@@ -329,7 +315,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements.
- ~list() BOOST_CONTAINER_NOEXCEPT
+ ~list() BOOST_NOEXCEPT_OR_NOTHROW
{} //AllocHolder clears the list
//! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -368,7 +354,8 @@ class list
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
list& operator=(BOOST_RV_REF(list) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+ || allocator_traits_type::is_always_equal::value)
{
BOOST_ASSERT(this != &x);
NodeAlloc &this_alloc = this->node_alloc();
@@ -463,7 +450,7 @@ class list
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return allocator_type(this->node_alloc()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -473,7 +460,7 @@ class list
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -483,7 +470,7 @@ class list
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->node_alloc(); }
//////////////////////////////////////////////
@@ -497,7 +484,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -505,7 +492,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cbegin(); }
//! <b>Effects</b>: Returns an iterator to the end of the list.
@@ -513,7 +500,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -521,7 +508,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cend(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -530,7 +517,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -539,7 +526,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -548,7 +535,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(begin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -557,7 +544,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crend(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -565,7 +552,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->non_const_icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -573,7 +560,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->non_const_icont().end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -582,7 +569,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->cend()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -591,7 +578,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->cbegin()); }
//////////////////////////////////////////////
@@ -605,7 +592,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return !this->size(); }
//! <b>Effects</b>: Returns the number of the elements contained in the list.
@@ -613,7 +600,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->icont().size(); }
//! <b>Effects</b>: Returns the largest possible size of the list.
@@ -621,7 +608,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return AllocHolder::max_size(); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -665,7 +652,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference front() BOOST_CONTAINER_NOEXCEPT
+ reference front() BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->begin(); }
//! <b>Requires</b>: !empty()
@@ -676,7 +663,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference front() const BOOST_CONTAINER_NOEXCEPT
+ const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->begin(); }
//! <b>Requires</b>: !empty()
@@ -687,7 +674,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference back() BOOST_CONTAINER_NOEXCEPT
+ reference back() BOOST_NOEXCEPT_OR_NOTHROW
{ return *(--this->end()); }
//! <b>Requires</b>: !empty()
@@ -698,7 +685,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference back() const BOOST_CONTAINER_NOEXCEPT
+ const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *(--this->end()); }
//////////////////////////////////////////////
@@ -707,7 +694,7 @@ class list
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the end of the list.
@@ -717,7 +704,7 @@ class list
//!
//! <b>Complexity</b>: Constant
template <class... Args>
- void emplace_back(Args&&... args)
+ void emplace_back(BOOST_FWD_REF(Args)... args)
{ this->emplace(this->cend(), boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -728,7 +715,7 @@ class list
//!
//! <b>Complexity</b>: Constant
template <class... Args>
- void emplace_front(Args&&... args)
+ void emplace_front(BOOST_FWD_REF(Args)... args)
{ this->emplace(this->cbegin(), boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -739,42 +726,34 @@ class list
//!
//! <b>Complexity</b>: Constant
template <class... Args>
- iterator emplace(const_iterator p, Args&&... args)
+ iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
{
NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert(p.get(), *pnode));
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- this->emplace(this->cend() \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- this->emplace(this->cbegin() \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- NodePtr pnode (AllocHolder::create_node \
- (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
- return iterator(this->icont().insert(p.get(), *pnode)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ #define BOOST_CONTAINER_LIST_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ void emplace_back(BOOST_MOVE_UREF##N)\
+ { this->emplace(this->cend() BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ void emplace_front(BOOST_MOVE_UREF##N)\
+ { this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
+ return iterator(this->icont().insert(p.get(), *pnode));\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_LIST_EMPLACE_CODE
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
@@ -786,7 +765,7 @@ class list
void push_front(const T &x);
//! <b>Effects</b>: Constructs a new element in the beginning of the list
- //! and moves the resources of mx to this new element.
+ //! and moves the resources of x to this new element.
//!
//! <b>Throws</b>: If memory allocation throws.
//!
@@ -806,7 +785,7 @@ class list
void push_back(const T &x);
//! <b>Effects</b>: Constructs a new element in the end of the list
- //! and moves the resources of mx to this new element.
+ //! and moves the resources of x to this new element.
//!
//! <b>Throws</b>: If memory allocation throws.
//!
@@ -830,7 +809,7 @@ class list
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
- //! <b>Effects</b>: Insert a new element before p with mx's resources.
+ //! <b>Effects</b>: Insert a new element before p with x's resources.
//!
//! <b>Returns</b>: an iterator to the inserted element.
//!
@@ -866,14 +845,14 @@ class list
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws.
//!
- //! <b>Complexity</b>: Linear to std::distance [first, last).
+ //! <b>Complexity</b>: Linear to distance [first, last).
template <class InpIt>
iterator insert(const_iterator p, InpIt first, InpIt last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
, typename container_detail::enable_if_c
< !container_detail::is_convertible<InpIt, size_type>::value
&& (container_detail::is_input_iterator<InpIt>::value
- || container_detail::is_same<alloc_version, allocator_v1>::value
+ || container_detail::is_same<alloc_version, version_1>::value
)
>::type * = 0
#endif
@@ -897,7 +876,7 @@ class list
, 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_v1>::value
+ || container_detail::is_same<alloc_version, version_1>::value
)
>::type * = 0
)
@@ -906,7 +885,7 @@ class list
insertion_functor func(this->icont(), p.get());
iterator before_p(p.get());
--before_p;
- this->allocate_many_and_construct(first, std::distance(first, last), func);
+ this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
return ++before_p;
}
#endif
@@ -921,7 +900,7 @@ class list
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced std::initializer_list iterator throws.
//!
- //! <b>Complexity</b>: Linear to std::distance [il.begin(), il.end()).
+ //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
iterator insert(const_iterator p, std::initializer_list<value_type> il)
{ return insert(p, il.begin(), il.end()); }
#endif
@@ -931,7 +910,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- void pop_front() BOOST_CONTAINER_NOEXCEPT
+ void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
{ this->erase(this->cbegin()); }
//! <b>Effects</b>: Removes the last element from the list.
@@ -939,7 +918,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- void pop_back() BOOST_CONTAINER_NOEXCEPT
+ void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
{ const_iterator tmp = this->cend(); this->erase(--tmp); }
//! <b>Requires</b>: p must be a valid iterator of *this.
@@ -949,7 +928,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Amortized constant time.
- iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
//! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -959,7 +938,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the distance between first and last.
- iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
//! <b>Effects</b>: Swaps the contents of *this and x.
@@ -968,6 +947,8 @@ class list
//!
//! <b>Complexity</b>: Constant.
void swap(list& x)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
+ || allocator_traits_type::is_always_equal::value)
{ AllocHolder::swap(x); }
//! <b>Effects</b>: Erases all the elements of the list.
@@ -975,7 +956,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements in the list.
- void clear() BOOST_CONTAINER_NOEXCEPT
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ AllocHolder::clear(alloc_version()); }
//////////////////////////////////////////////
@@ -996,7 +977,7 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, list& x) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this != &x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
@@ -1015,7 +996,7 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice(p, static_cast<list&>(x)); }
//! <b>Requires</b>: p must point to an element contained
@@ -1032,7 +1013,7 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, list &x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, list &x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
{
//BOOST_ASSERT(this != &x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
@@ -1053,7 +1034,7 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice(p, static_cast<list&>(x), i); }
//! <b>Requires</b>: p must point to an element contained
@@ -1069,7 +1050,7 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get());
@@ -1088,12 +1069,12 @@ class list
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice(p, static_cast<list&>(x), first, last); }
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
- //! n == std::distance(first, last). this' allocator and x's allocator shall compare equal
+ //! n == distance(first, last). this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
@@ -1106,7 +1087,7 @@ class list
//! list. Iterators of this list and all the references are not invalidated.
//!
//! <b>Note</b>: Non-standard extension
- void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, list &x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
@@ -1114,7 +1095,7 @@ class list
//! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x.
- //! n == std::distance(first, last). this' allocator and x's allocator shall compare equal
+ //! n == distance(first, last). this' allocator and x's allocator shall compare equal
//!
//! <b>Effects</b>: Transfers the range pointed by first and last from list x to this list,
//! before the the element pointed by p. No destructors or copy constructors are called.
@@ -1127,7 +1108,7 @@ class list
//! list. Iterators of this list and all the references are not invalidated.
//!
//! <b>Note</b>: Non-standard extension
- void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice(p, static_cast<list&>(x), first, last, n); }
//! <b>Effects</b>: Removes all the elements that compare equal to value.
@@ -1139,7 +1120,7 @@ class list
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
void remove(const T& value)
- { this->remove_if(equal_to_value(value)); }
+ { this->remove_if(equal_to_value_type(value)); }
//! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied.
@@ -1153,8 +1134,8 @@ class list
template <class Pred>
void remove_if(Pred pred)
{
- typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
+ typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
+ this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
@@ -1181,8 +1162,8 @@ class list
template <class BinaryPredicate>
void unique(BinaryPredicate binary_pred)
{
- typedef ValueCompareToNodeCompare<BinaryPredicate> Predicate;
- this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc()));
+ typedef value_to_node_compare<Node, BinaryPredicate> value_to_node_compare_type;
+ this->icont().unique_and_dispose(value_to_node_compare_type(binary_pred), Destroyer(this->node_alloc()));
}
//! <b>Requires</b>: The lists x and *this must be distinct.
@@ -1231,8 +1212,8 @@ class list
void merge(list &x, const StrictWeakOrdering &comp)
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
- this->icont().merge(x.icont(),
- ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
+ this->icont().merge(x.icont(), value_to_node_compare_type(comp));
}
//! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -1280,7 +1261,8 @@ class list
// nothing if the list has length 0 or 1.
if (this->size() < 2)
return;
- this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
+ this->icont().sort(value_to_node_compare_type(comp));
}
//! <b>Effects</b>: Reverses the order of elements in the list.
@@ -1290,28 +1272,14 @@ class list
//! <b>Complexity</b>: This function is linear time.
//!
//! <b>Note</b>: Iterators and references are not invalidated
- void reverse() BOOST_CONTAINER_NOEXCEPT
+ void reverse() BOOST_NOEXCEPT_OR_NOTHROW
{ this->icont().reverse(); }
//! <b>Effects</b>: Returns true if x and y are equal
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator==(const list& x, const list& y)
- {
- if(x.size() != y.size()){
- return false;
- }
- typedef typename list::const_iterator const_iterator;
- const_iterator end1 = x.end();
-
- const_iterator i1 = x.begin();
- const_iterator i2 = y.begin();
- while (i1 != end1 && *i1 == *i2) {
- ++i1;
- ++i2;
- }
- return i1 == end1;
- }
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
@@ -1323,7 +1291,7 @@ class list
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator<(const list& x, const list& y)
- { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+ { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! <b>Effects</b>: Returns true if x is greater than y
//!
@@ -1448,8 +1416,11 @@ class list
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::list<T, Allocator> >
- : public ::boost::has_trivial_destructor_after_move<Allocator>
-{};
+{
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
namespace container {
diff --git a/boost/container/map.hpp b/boost/container/map.hpp
index 6abfa1a346..4dc6096e1e 100644
--- a/boost/container/map.hpp
+++ b/boost/container/map.hpp
@@ -7,36 +7,45 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
-
#ifndef BOOST_CONTAINER_MAP_HPP
#define BOOST_CONTAINER_MAP_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+// container
#include <boost/container/container_fwd.hpp>
-#include <utility>
-#include <functional>
-#include <memory>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/tree.hpp>
+#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/value_init.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/container/detail/mpl.hpp>
-#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/pair.hpp>
-#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/throw_exception.hpp>
+// move
+#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
#include <boost/move/detail/move_helpers.hpp>
-#include <boost/move/traits.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
+// other
#include <boost/static_assert.hpp>
-#include <boost/container/detail/value_init.hpp>
#include <boost/core/no_exceptions_support.hpp>
-
+// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -55,13 +64,13 @@ namespace container {
//! by this container is the value_type is std::pair<const Key, T>.
//!
//! \tparam Key is the key_type of the map
-//! \tparam Value is the <code>mapped_type</code>
+//! \tparam T is the <code>mapped_type</code>
//! \tparam Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
//! \tparam Allocator is the allocator to allocate the <code>value_type</code>s
//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
//! \tparam MapOptions is an packed option type generated using using boost::container::tree_assoc_options.
template < class Key, class T, class Compare = std::less<Key>
- , class Allocator = std::allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults >
+ , class Allocator = new_allocator< std::pair< const Key, T> >, class MapOptions = tree_assoc_defaults >
#else
template <class Key, class T, class Compare, class Allocator, class MapOptions>
#endif
@@ -93,10 +102,10 @@ class map
//
//////////////////////////////////////////////
- typedef Key key_type;
- typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
- typedef T mapped_type;
- typedef std::pair<const Key, T> value_type;
+ typedef Key key_type;
+ typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
+ typedef T mapped_type;
+ typedef std::pair<const Key, T> value_type;
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
@@ -126,7 +135,7 @@ class map
map()
: base_t()
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -134,11 +143,10 @@ class map
//! and allocator.
//!
//! <b>Complexity</b>: Constant.
- explicit map(const Compare& comp,
- const allocator_type& a = allocator_type())
+ explicit map(const Compare& comp, const allocator_type& a = allocator_type())
: base_t(comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -148,7 +156,7 @@ class map
explicit map(const allocator_type& a)
: base_t(a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -162,7 +170,20 @@ class map
const allocator_type& a = allocator_type())
: base_t(true, first, last, comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Constructs an empty map using the specified
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ map(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(true, first, last, Compare(), a)
+ {
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -181,7 +202,7 @@ class map
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
: base_t(ordered_range, first, last, comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -194,15 +215,37 @@ class map
map(std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
: base_t(true, il.begin(), il.end(), comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
+ //! <b>Effects</b>: Constructs an empty map using the specified
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is il.first() - il.end().
+ map(std::initializer_list<value_type> il, const allocator_type& a)
+ : base_t(true, il.begin(), il.end(), Compare(), a)
+ {
+ //A type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate and must be
+ //! unique values.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
map(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
const allocator_type& a = allocator_type())
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
#endif
@@ -213,7 +256,7 @@ class map
map(const map& x)
: base_t(static_cast<const base_t&>(x))
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -223,9 +266,9 @@ class map
//!
//! <b>Postcondition</b>: x is emptied.
map(BOOST_RV_REF(map) x)
- : base_t(boost::move(static_cast<base_t&>(x)))
+ : base_t(BOOST_MOVE_BASE(base_t, x))
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -235,7 +278,7 @@ class map
map(const map& x, const allocator_type &a)
: base_t(static_cast<const base_t&>(x), a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -246,9 +289,9 @@ class map
//!
//! <b>Postcondition</b>: x is emptied.
map(BOOST_RV_REF(map) x, const allocator_type &a)
- : base_t(boost::move(static_cast<base_t&>(x)), a)
+ : base_t(BOOST_MOVE_BASE(base_t, x), a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -267,8 +310,10 @@ class map
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
map& operator=(BOOST_RV_REF(map) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
- { return static_cast<map&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
+
+ { return static_cast<map&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Assign content of il to *this.
@@ -283,7 +328,7 @@ class map
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! <b>Effects</b>: Returns a copy of the allocator that
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
@@ -296,7 +341,7 @@ class map
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT;
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a reference to the internal allocator.
//!
@@ -305,49 +350,49 @@ class map
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT;
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns an iterator to the first element contained in the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT;
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns an iterator to the end of the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT;
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_iterator to the end of the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -355,7 +400,7 @@ class map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -363,7 +408,7 @@ class map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
//! of the reversed container.
@@ -371,7 +416,7 @@ class map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
//! of the reversed container.
@@ -379,7 +424,7 @@ class map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed container.
@@ -387,7 +432,7 @@ class map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
//! of the reversed container.
@@ -395,28 +440,28 @@ class map
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns true if the container contains no elements.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT;
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns the number of the elements contained in the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT;
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns the largest possible size of the container.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT;
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW;
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -424,7 +469,7 @@ class map
//! Effects: If there is no key equivalent to x in the map, inserts
//! value_type(x, T()) into the map.
//!
- //! Returns: Allocator reference to the mapped_type corresponding to x in *this.
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
mapped_type& operator[](const key_type &k);
@@ -432,7 +477,7 @@ class map
//! Effects: If there is no key equivalent to x in the map, inserts
//! value_type(boost::move(x), T()) into the map (the key is move-constructed)
//!
- //! Returns: Allocator reference to the mapped_type corresponding to x in *this.
+ //! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
mapped_type& operator[](key_type &&k);
@@ -440,7 +485,7 @@ class map
BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
#endif
- //! Returns: Allocator reference to the element whose key is equivalent to x.
+ //! Returns: A reference to the element whose key is equivalent to x.
//! Throws: An exception object of type out_of_range if no such element is present.
//! Complexity: logarithmic.
T& at(const key_type& k)
@@ -452,7 +497,7 @@ class map
return i->second;
}
- //! Returns: Allocator reference to the element whose key is equivalent to x.
+ //! Returns: A reference to the element whose key is equivalent to x.
//! Throws: An exception object of type out_of_range if no such element is present.
//! Complexity: logarithmic.
const T& at(const key_type& k) const
@@ -598,7 +643,7 @@ class map
{ this->base_t::insert_unique(il.begin(), il.end()); }
#endif
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object x of type T constructed with
//! std::forward<Args>(args)... in the container if and only if there is
@@ -612,7 +657,7 @@ class map
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
- std::pair<iterator,bool> emplace(Args&&... args)
+ std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -626,26 +671,24 @@ class map
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
- iterator emplace_hint(const_iterator p, Args&&... args)
+ iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_hint_unique(p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_MAP_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MAP_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_MAP_EMPLACE_CODE
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -656,35 +699,37 @@ class map
//! returns end().
//!
//! <b>Complexity</b>: Amortized constant time
- iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT;
+ iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Erases all elements in the container with key equivalent to x.
//!
//! <b>Returns</b>: Returns the number of erased elements.
//!
//! <b>Complexity</b>: log(size()) + count(k)
- size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT;
+ size_type erase(const key_type& x) BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Erases all the elements in the range [first, last).
//!
//! <b>Returns</b>: Returns last.
//!
//! <b>Complexity</b>: log(size())+N where N is the distance from first to last.
- iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT;
+ iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Swaps the contents of *this and x.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- void swap(map& x);
+ void swap(map& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value )
//! <b>Effects</b>: erase(a.begin(),a.end()).
//!
//! <b>Postcondition</b>: size() == 0.
//!
//! <b>Complexity</b>: linear in size().
- void clear() BOOST_CONTAINER_NOEXCEPT;
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Effects</b>: Returns the comparison object out
//! of which a was constructed.
@@ -704,7 +749,7 @@ class map
//! <b>Complexity</b>: Logarithmic.
iterator find(const key_type& x);
- //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
@@ -726,7 +771,7 @@ class map
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -738,7 +783,7 @@ class map
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -835,10 +880,13 @@ class map
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class K, class T, class C, class Allocator>
-struct has_trivial_destructor_after_move<boost::container::map<K, T, C, Allocator> >
+template <class Key, class T, class Compare, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::map<Key, T, Compare, Allocator> >
{
- static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -863,7 +911,7 @@ namespace container {
//! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
//! \tparam MultiMapOptions is an packed option type generated using using boost::container::tree_assoc_options.
template < class Key, class T, class Compare = std::less<Key>
- , class Allocator = std::allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults>
+ , class Allocator = new_allocator< std::pair< const Key, T> >, class MultiMapOptions = tree_assoc_defaults>
#else
template <class Key, class T, class Compare, class Allocator, class MultiMapOptions>
#endif
@@ -888,6 +936,8 @@ class multimap
> value_compare_impl;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
+
public:
//////////////////////////////////////////////
//
@@ -927,7 +977,7 @@ class multimap
multimap()
: base_t()
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -937,7 +987,7 @@ class multimap
explicit multimap(const Compare& comp, const allocator_type& a = allocator_type())
: base_t(comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -948,7 +998,7 @@ class multimap
explicit multimap(const allocator_type& a)
: base_t(a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -963,7 +1013,20 @@ class multimap
const allocator_type& a = allocator_type())
: base_t(false, first, last, comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ multimap(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(false, first, last, Compare(), a)
+ {
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -992,15 +1055,36 @@ class multimap
const allocator_type& a = allocator_type())
: base_t(false, il.begin(), il.end(), comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
+ BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
+ }
+
+ //! <b>Effects</b>: Constructs an empty multimap using the specified
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is il.first() - il.end().
+ multimap(std::initializer_list<value_type> il, const allocator_type& a)
+ : base_t(false, il.begin(), il.end(), Compare(), a)
+ {
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
+ //! <b>Effects</b>: Constructs an empty set using the specified comparison object and
+ //! allocator, and inserts elements from the ordered range [il.begin(), il.end()). This function
+ //! is more efficient than the normal range creation for ordered ranges.
+ //!
+ //! <b>Requires</b>: [il.begin(), il.end()) must be ordered according to the predicate.
+ //!
+ //! <b>Complexity</b>: Linear in N.
+ //!
+ //! <b>Note</b>: Non-standard extension.
multimap(ordered_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(),
const allocator_type& a = allocator_type())
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
#endif
@@ -1011,7 +1095,7 @@ class multimap
multimap(const multimap& x)
: base_t(static_cast<const base_t&>(x))
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -1021,9 +1105,9 @@ class multimap
//!
//! <b>Postcondition</b>: x is emptied.
multimap(BOOST_RV_REF(multimap) x)
- : base_t(boost::move(static_cast<base_t&>(x)))
+ : base_t(BOOST_MOVE_BASE(base_t, x))
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -1033,7 +1117,7 @@ class multimap
multimap(const multimap& x, const allocator_type &a)
: base_t(static_cast<const base_t&>(x), a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -1043,9 +1127,9 @@ class multimap
//!
//! <b>Postcondition</b>: x is emptied.
multimap(BOOST_RV_REF(multimap) x, const allocator_type &a)
- : base_t(boost::move(static_cast<base_t&>(x)), a)
+ : base_t(BOOST_MOVE_BASE(base_t, x), a)
{
- //Allocator type must be std::pair<CONST Key, T>
+ //A type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
@@ -1059,7 +1143,9 @@ class multimap
//!
//! <b>Complexity</b>: Constant.
multimap& operator=(BOOST_RV_REF(multimap) x)
- { return static_cast<multimap&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
+ { return static_cast<multimap&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Assign content of il to *this.
@@ -1093,31 +1179,31 @@ class multimap
const_iterator cbegin() const;
//! @copydoc ::boost::container::set::end()
- iterator end() BOOST_CONTAINER_NOEXCEPT;
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::end() const
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::cend() const
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::rbegin()
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::rbegin() const
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::crbegin() const
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::rend()
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::rend() const
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::crend() const
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::empty() const
bool empty() const;
@@ -1130,7 +1216,7 @@ class multimap
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the container.
@@ -1142,7 +1228,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
- iterator emplace(Args&&... args)
+ iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -1155,26 +1241,24 @@ class multimap
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
- iterator emplace_hint(const_iterator p, Args&&... args)
+ iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_hint_equal(p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_MULTIMAP_EMPLACE_CODE
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
//! newly inserted element.
@@ -1277,10 +1361,12 @@ class multimap
iterator erase(const_iterator first, const_iterator last);
//! @copydoc ::boost::container::set::swap
- void swap(flat_multiset& x);
+ void swap(multiset& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value );
//! @copydoc ::boost::container::set::clear
- void clear() BOOST_CONTAINER_NOEXCEPT;
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::key_comp
key_compare key_comp() const;
@@ -1294,7 +1380,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic.
iterator find(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to an element with the key
+ //! <b>Returns</b>: A const iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
@@ -1311,7 +1397,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -1323,7 +1409,7 @@ class multimap
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -1388,10 +1474,13 @@ class multimap
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class K, class T, class C, class Allocator>
-struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, Allocator> >
+template <class Key, class T, class Compare, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::multimap<Key, T, Compare, Allocator> >
{
- static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -1402,5 +1491,5 @@ namespace container {
#include <boost/container/detail/config_end.hpp>
-#endif /* BOOST_CONTAINER_MAP_HPP */
+#endif // BOOST_CONTAINER_MAP_HPP
diff --git a/boost/container/new_allocator.hpp b/boost/container/new_allocator.hpp
new file mode 100644
index 0000000000..1ac15d8a25
--- /dev/null
+++ b/boost/container/new_allocator.hpp
@@ -0,0 +1,175 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015. 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_NEW_ALLOCATOR_HPP
+#define BOOST_CONTAINER_NEW_ALLOCATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/throw_exception.hpp>
+#include <cstddef>
+
+//!\file
+
+namespace boost {
+namespace container {
+
+template<bool Value>
+struct new_allocator_bool
+{ static const bool value = Value; };
+
+template<class T>
+class new_allocator;
+
+//! Specialization of new_allocator for void types
+template<>
+class new_allocator<void>
+{
+ public:
+ typedef void value_type;
+ typedef void * pointer;
+ typedef const void* const_pointer;
+ //!A integral constant of type bool with value true
+ typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
+ //!A integral constant of type bool with value true
+ typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
+ // reference-to-void members are impossible
+
+ //!Obtains an new_allocator that allocates
+ //!objects of type T2
+ template<class T2>
+ struct rebind
+ {
+ typedef new_allocator< T2> other;
+ };
+
+ //!Default constructor
+ //!Never throws
+ new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+ {}
+
+ //!Constructor from other new_allocator.
+ //!Never throws
+ new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ {}
+
+ //!Constructor from related new_allocator.
+ //!Never throws
+ template<class T2>
+ new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
+ {}
+
+ //!Swaps two allocators, does nothing
+ //!because this new_allocator is stateless
+ friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ {}
+
+ //!An new_allocator always compares to true, as memory allocated with one
+ //!instance can be deallocated by another instance
+ friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ { return true; }
+
+ //!An new_allocator always compares to false, as memory allocated with one
+ //!instance can be deallocated by another instance
+ friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ { return false; }
+};
+
+
+//! This class is a reduced STL-compatible allocator that allocates memory using operator new
+template<class T>
+class new_allocator
+{
+ public:
+ typedef T value_type;
+ typedef T * pointer;
+ typedef const T * const_pointer;
+ typedef T & reference;
+ typedef const T & const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ //!A integral constant of type bool with value true
+ typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment;
+ //!A integral constant of type bool with value true
+ typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal;
+
+ //!Obtains an new_allocator that allocates
+ //!objects of type T2
+ template<class T2>
+ struct rebind
+ {
+ typedef new_allocator<T2> other;
+ };
+
+ //!Default constructor
+ //!Never throws
+ new_allocator() BOOST_NOEXCEPT_OR_NOTHROW
+ {}
+
+ //!Constructor from other new_allocator.
+ //!Never throws
+ new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ {}
+
+ //!Constructor from related new_allocator.
+ //!Never throws
+ template<class T2>
+ new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW
+ {}
+
+ //!Allocates memory for an array of count elements.
+ //!Throws std::bad_alloc if there is no enough memory
+ pointer allocate(size_type count)
+ {
+ if(BOOST_UNLIKELY(count > this->max_size()))
+ throw_bad_alloc();
+ return static_cast<T*>(::operator new(count*sizeof(T)));
+ }
+
+ //!Deallocates previously allocated memory.
+ //!Never throws
+ void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW
+ { ::operator delete((void*)ptr); }
+
+ //!Returns the maximum number of elements that could be allocated.
+ //!Never throws
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+ { return size_type(-1)/sizeof(T); }
+
+ //!Swaps two allocators, does nothing
+ //!because this new_allocator is stateless
+ friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ {}
+
+ //!An new_allocator always compares to true, as memory allocated with one
+ //!instance can be deallocated by another instance
+ friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ { return true; }
+
+ //!An new_allocator always compares to false, as memory allocated with one
+ //!instance can be deallocated by another instance
+ friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
+ { return false; }
+};
+
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //BOOST_CONTAINER_ALLOCATOR_HPP
diff --git a/boost/container/node_allocator.hpp b/boost/container/node_allocator.hpp
index 8004339eb8..afd6f98a8d 100644
--- a/boost/container/node_allocator.hpp
+++ b/boost/container/node_allocator.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
#define BOOST_CONTAINER_POOLED_NODE_ALLOCATOR_HPP
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
@@ -26,10 +30,7 @@
#include <boost/container/detail/singleton.hpp>
#include <boost/assert.hpp>
-#include <boost/utility/addressof.hpp>
#include <boost/static_assert.hpp>
-#include <memory>
-#include <algorithm>
#include <cstddef>
namespace boost {
@@ -116,11 +117,11 @@ class node_allocator
public:
//!Default constructor
- node_allocator() BOOST_CONTAINER_NOEXCEPT
+ node_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Copy constructor from other node_allocator.
- node_allocator(const node_allocator &) BOOST_CONTAINER_NOEXCEPT
+ node_allocator(const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Copy constructor from related node_allocator.
@@ -130,11 +131,11 @@ class node_allocator
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
, Version
#endif
- > &) BOOST_CONTAINER_NOEXCEPT
+ > &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Destructor
- ~node_allocator() BOOST_CONTAINER_NOEXCEPT
+ ~node_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Returns the number of elements that could be allocated.
@@ -146,7 +147,7 @@ class node_allocator
//!Throws std::bad_alloc if there is no enough memory
pointer allocate(size_type count, const void * = 0)
{
- if(count > this->max_size())
+ if(BOOST_UNLIKELY(count > this->max_size()))
boost::container::throw_bad_alloc();
if(Version == 1 && count == 1){
@@ -157,7 +158,7 @@ class node_allocator
}
else{
void *ret = boost_cont_malloc(count*sizeof(T));
- if(!ret)
+ if(BOOST_UNLIKELY(!ret))
boost::container::throw_bad_alloc();
return static_cast<pointer>(ret);
}
@@ -165,7 +166,7 @@ class node_allocator
//!Deallocate allocated memory.
//!Never throws
- void deallocate(const pointer &ptr, size_type count) BOOST_CONTAINER_NOEXCEPT
+ void deallocate(const pointer &ptr, size_type count) BOOST_NOEXCEPT_OR_NOTHROW
{
(void)count;
if(Version == 1 && count == 1){
@@ -180,7 +181,7 @@ class node_allocator
}
//!Deallocates all free blocks of the pool
- static void deallocate_free_blocks() BOOST_CONTAINER_NOEXCEPT
+ static void deallocate_free_blocks() BOOST_NOEXCEPT_OR_NOTHROW
{
typedef container_detail::shared_node_pool
<sizeof(T), NodesPerBlock> shared_pool_t;
@@ -188,23 +189,19 @@ class node_allocator
singleton_t::instance().deallocate_free_blocks();
}
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size, pointer reuse = pointer())
+ pointer allocation_command
+ (allocation_type command, size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
BOOST_STATIC_ASSERT(( Version > 1 ));
- std::pair<pointer, bool> ret =
- priv_allocation_command(command, limit_size, preferred_size, received_size, reuse);
- if(!ret.first && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION))
+ pointer ret = this->priv_allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+ if(BOOST_UNLIKELY(!ret && !(command & BOOST_CONTAINER_NOTHROW_ALLOCATION)))
boost::container::throw_bad_alloc();
return ret;
}
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
- size_type size(pointer p) const BOOST_CONTAINER_NOEXCEPT
+ size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_STATIC_ASSERT(( Version > 1 ));
return boost_cont_size(p);
@@ -238,7 +235,7 @@ class node_allocator
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
- void deallocate_one(pointer p) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_one(pointer p) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_STATIC_ASSERT(( Version > 1 ));
typedef container_detail::shared_node_pool
@@ -247,7 +244,7 @@ class node_allocator
singleton_t::instance().deallocate_node(p);
}
- void deallocate_individual(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_individual(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_STATIC_ASSERT(( Version > 1 ));
typedef container_detail::shared_node_pool
@@ -264,7 +261,7 @@ class node_allocator
BOOST_STATIC_ASSERT(( Version > 1 ));
boost_cont_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
- if(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
+ if(BOOST_UNLIKELY(!boost_cont_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after( chain.before_begin()
@@ -280,7 +277,7 @@ class node_allocator
BOOST_STATIC_ASSERT(( Version > 1 ));
boost_cont_memchain ch;
boost_cont_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch);
- if(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch)){
+ if(BOOST_UNLIKELY(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after( chain.before_begin()
@@ -289,7 +286,7 @@ class node_allocator
, BOOST_CONTAINER_MEMCHAIN_SIZE(&ch));
}
- void deallocate_many(multiallocation_chain &chain) BOOST_CONTAINER_NOEXCEPT
+ void deallocate_many(multiallocation_chain &chain) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_STATIC_ASSERT(( Version > 1 ));
void *first = &*chain.begin();
@@ -302,37 +299,40 @@ class node_allocator
//!Swaps allocators. Does not throw. If each allocator is placed in a
//!different memory segment, the result is undefined.
- friend void swap(self_t &, self_t &) BOOST_CONTAINER_NOEXCEPT
+ friend void swap(self_t &, self_t &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!An allocator always compares to true, as memory allocated with one
//!instance can be deallocated by another instance
- friend bool operator==(const node_allocator &, const node_allocator &) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator==(const node_allocator &, const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return true; }
//!An allocator always compares to false, as memory allocated with one
//!instance can be deallocated by another instance
- friend bool operator!=(const node_allocator &, const node_allocator &) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator!=(const node_allocator &, const node_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return false; }
private:
- std::pair<pointer, bool> priv_allocation_command
+ pointer priv_allocation_command
(allocation_type command, std::size_t limit_size
- ,std::size_t preferred_size,std::size_t &received_size, void *reuse_ptr)
+ ,size_type &prefer_in_recvd_out_size
+ ,pointer &reuse)
{
+ std::size_t const preferred_size = prefer_in_recvd_out_size;
boost_cont_command_ret_t ret = {0 , 0};
- if(limit_size > this->max_size() || preferred_size > this->max_size()){
- //ret.first = 0;
- return std::pair<pointer, bool>(pointer(), false);
+ if((limit_size > this->max_size()) | (preferred_size > this->max_size())){
+ return pointer();
}
std::size_t l_size = limit_size*sizeof(T);
std::size_t p_size = preferred_size*sizeof(T);
std::size_t r_size;
{
- ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr);
+ void* reuse_ptr_void = reuse;
+ ret = boost_cont_allocation_command(command, sizeof(T), l_size, p_size, &r_size, reuse_ptr_void);
+ reuse = static_cast<T*>(reuse_ptr_void);
}
- received_size = r_size/sizeof(T);
- return std::pair<pointer, bool>(static_cast<pointer>(ret.first), !!ret.second);
+ prefer_in_recvd_out_size = r_size/sizeof(T);
+ return (pointer)ret.first;
}
};
diff --git a/boost/container/options.hpp b/boost/container/options.hpp
index c36ad30143..da8b6a7952 100644
--- a/boost/container/options.hpp
+++ b/boost/container/options.hpp
@@ -13,7 +13,11 @@
#ifndef BOOST_CONTAINER_OPTIONS_HPP
#define BOOST_CONTAINER_OPTIONS_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/scoped_allocator.hpp b/boost/container/scoped_allocator.hpp
index 0a2987194f..55514aae21 100644
--- a/boost/container/scoped_allocator.hpp
+++ b/boost/container/scoped_allocator.hpp
@@ -23,24 +23,31 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-#include <boost/container/scoped_allocator_fwd.hpp>
-#include <boost/type_traits/integral_constant.hpp>
+
#include <boost/container/allocator_traits.hpp>
-#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/detail/utilities.hpp>
-#include <utility>
+#include <boost/container/scoped_allocator_fwd.hpp>
+
+#include <boost/container/detail/addressof.hpp>
+#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/pair.hpp>
+#include <boost/container/detail/type_traits.hpp>
+
+#include <boost/move/adl_move_swap.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
#include <boost/move/utility_core.hpp>
+
#include <boost/core/no_exceptions_support.hpp>
namespace boost { namespace container {
-//! <b>Remark</b>: if a specialization is derived from true_type, indicates that T may be constructed
+//! <b>Remark</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, indicates that T may be constructed
//! with an allocator as its last constructor argument. Ideally, all constructors of T (including the
//! copy and move constructors) should have a variant that accepts a final argument of
//! allocator_type.
//!
-//! <b>Requires</b>: if a specialization is derived from true_type, T must have a nested type,
+//! <b>Requires</b>: if a specialization constructible_with_allocator_suffix<X>::value is true, T must have a nested type,
//! allocator_type and at least one constructor for which allocator_type is the last
//! parameter. If not all constructors of T can be called with a final allocator_type argument,
//! and if T is used in a context where a container must call such a constructor, then the program is
@@ -63,10 +70,10 @@ namespace boost { namespace container {
//! // Specialize trait for class template Z
//! template <class T, class Allocator = allocator<T> >
//! struct constructible_with_allocator_suffix<Z<T,Allocator> >
-//! : ::boost::true_type { };
+//! { static const bool value = true; };
//! </code>
//!
-//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)"
+//! <b>Note</b>: This trait is a workaround inspired by "N2554: The Scoped A Model (Rev 2)"
//! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as
//! in C++03 there is no mechanism to detect if a type can be constructed from arbitrary arguments.
//! Applications aiming portability with several compilers should always define this trait.
@@ -76,15 +83,14 @@ namespace boost { namespace container {
//! to detect if a type should be constructed with suffix or prefix allocator arguments.
template <class T>
struct constructible_with_allocator_suffix
- : ::boost::false_type
-{};
+{ static const bool value = false; };
-//! <b>Remark</b>: if a specialization is derived from true_type, indicates that T may be constructed
+//! <b>Remark</b>: if a specialization constructible_with_allocator_prefix<X>::value is true, indicates that T may be constructed
//! with allocator_arg and T::allocator_type as its first two constructor arguments.
//! Ideally, all constructors of T (including the copy and move constructors) should have a variant
//! that accepts these two initial arguments.
//!
-//! <b>Requires</b>: if a specialization is derived from true_type, T must have a nested type,
+//! <b>Requires</b>: specialization constructible_with_allocator_prefix<X>::value is true, T must have a nested type,
//! allocator_type and at least one constructor for which allocator_arg_t is the first
//! parameter and allocator_type is the second parameter. If not all constructors of T can be
//! called with these initial arguments, and if T is used in a context where a container must call such
@@ -107,13 +113,13 @@ struct constructible_with_allocator_suffix
//! // Variadic constructor and allocator-extended variadic constructor
//! template<class ...Args> Y(Args&& args...);
//! template<class ...Args>
-//! Y(allocator_arg_t, const allocator_type& a, Args&&... args);
+//! Y(allocator_arg_t, const allocator_type& a, BOOST_FWD_REF(Args)... args);
//! };
//!
//! // Specialize trait for class template Y
//! template <class T, class Allocator = allocator<T> >
//! struct constructible_with_allocator_prefix<Y<T,Allocator> >
-//! : ::boost::true_type { };
+//! { static const bool value = true; };
//!
//! </code>
//!
@@ -127,34 +133,34 @@ struct constructible_with_allocator_suffix
//! to detect if a type should be constructed with suffix or prefix allocator arguments.
template <class T>
struct constructible_with_allocator_prefix
- : ::boost::false_type
-{};
+{ static const bool value = false; };
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace container_detail {
-template<typename T, typename Alloc>
+template<typename T, typename Allocator>
struct uses_allocator_imp
{
// Use SFINAE (Substitution Failure Is Not An Error) to detect the
- // presence of an 'allocator_type' nested type convertilble from Alloc.
-
+ // presence of an 'allocator_type' nested type convertilble from Allocator.
private:
+ typedef char yes_type;
+ struct no_type{ char dummy[2]; };
+
// Match this function if TypeT::allocator_type exists and is
- // implicitly convertible from Alloc
- template <typename U>
- static char test(int, typename U::allocator_type);
+ // implicitly convertible from Allocator
+ template <class U>
+ static yes_type test(typename U::allocator_type);
// Match this function if TypeT::allocator_type does not exist or is
- // not convertible from Alloc.
+ // not convertible from Allocator.
template <typename U>
- static int test(LowPriorityConversion<int>, LowPriorityConversion<Alloc>);
-
- static Alloc alloc; // Declared but not defined
+ static no_type test(...);
+ static Allocator alloc; // Declared but not defined
public:
- enum { value = sizeof(test<T>(0, alloc)) == sizeof(char) };
+ static const bool value = sizeof(test<T>(alloc)) == sizeof(yes_type);
};
} //namespace container_detail {
@@ -162,31 +168,34 @@ struct uses_allocator_imp
#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
-//! specialize this type to derive from true_type for a T of user-defined type if T does not
-//! have a nested allocator_type but is nonetheless constructible using the specified Alloc.
+//! Allocator. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may
+//! specialize this type to define uses_allocator<X>::value as true for a T of user-defined type if T does not
+//! have a nested allocator_type but is nonetheless constructible using the specified Allocator.
//!
-//! <b>Result</b>: derived from true_type if Convertible<Alloc,T::allocator_type> and
-//! derived from false_type otherwise.
-template <typename T, typename Alloc>
+//! <b>Result</b>: uses_allocator<T, Allocator>::value== true if Convertible<Allocator,T::allocator_type>,
+//! false otherwise.
+template <typename T, typename Allocator>
struct uses_allocator
- : boost::integral_constant<bool, container_detail::uses_allocator_imp<T, Alloc>::value>
+ : container_detail::uses_allocator_imp<T, Allocator>
{};
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace container_detail {
-template <typename Alloc>
+template <typename Allocator>
struct is_scoped_allocator_imp
{
+ typedef char yes_type;
+ struct no_type{ char dummy[2]; };
+
template <typename T>
- static char test(int, typename T::outer_allocator_type*);
+ static yes_type test(typename T::outer_allocator_type*);
template <typename T>
- static int test(LowPriorityConversion<int>, void*);
+ static int test(...);
- static const bool value = (sizeof(char) == sizeof(test<Alloc>(0, 0)));
+ static const bool value = (sizeof(yes_type) == sizeof(test<Allocator>(0)));
};
template<class MaybeScopedAlloc, bool = is_scoped_allocator_imp<MaybeScopedAlloc>::value >
@@ -229,40 +238,38 @@ struct outermost_allocator_imp<MaybeScopedAlloc, true>
} //namespace container_detail {
-template <typename Alloc>
+template <typename Allocator>
struct is_scoped_allocator
- : boost::integral_constant<bool, container_detail::is_scoped_allocator_imp<Alloc>::value>
+ : container_detail::is_scoped_allocator_imp<Allocator>
{};
-template <typename Alloc>
+template <typename Allocator>
struct outermost_allocator
- : container_detail::outermost_allocator_imp<Alloc>
+ : container_detail::outermost_allocator_imp<Allocator>
{};
-template <typename Alloc>
-typename container_detail::outermost_allocator_imp<Alloc>::type &
- get_outermost_allocator(Alloc &a)
-{ return container_detail::outermost_allocator_imp<Alloc>::get(a); }
+template <typename Allocator>
+typename container_detail::outermost_allocator_imp<Allocator>::type &
+ get_outermost_allocator(Allocator &a)
+{ return container_detail::outermost_allocator_imp<Allocator>::get(a); }
-template <typename Alloc>
-const typename container_detail::outermost_allocator_imp<Alloc>::type &
- get_outermost_allocator(const Alloc &a)
-{ return container_detail::outermost_allocator_imp<Alloc>::get(a); }
+template <typename Allocator>
+const typename container_detail::outermost_allocator_imp<Allocator>::type &
+ get_outermost_allocator(const Allocator &a)
+{ return container_detail::outermost_allocator_imp<Allocator>::get(a); }
namespace container_detail {
// Check if we can detect is_convertible using advanced SFINAE expressions
-#if !defined(BOOST_NO_SFINAE_EXPR)
+#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//! Code inspired by Mathias Gaunard's is_convertible.cpp found in the Boost mailing list
//! http://boost.2283326.n4.nabble.com/type-traits-is-constructible-when-decltype-is-supported-td3575452.html
//! Thanks Mathias!
//With variadic templates, we need a single class to implement the trait
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
template<class T, class ...Args>
- struct is_constructible_impl
+ struct is_constructible
{
typedef char yes_type;
struct no_type
@@ -272,7 +279,7 @@ namespace container_detail {
struct dummy;
template<class X>
- static yes_type test(dummy<sizeof(X(boost::move_detail::declval<Args>()...))>*);
+ static decltype(X(boost::move_detail::declval<Args>()...), true_type()) test(int);
template<class X>
static no_type test(...);
@@ -280,148 +287,39 @@ namespace container_detail {
static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
};
- template<class T, class ...Args>
- struct is_constructible
- : boost::integral_constant<bool, is_constructible_impl<T, Args...>::value>
- {};
-
template <class T, class InnerAlloc, class ...Args>
struct is_constructible_with_allocator_prefix
: is_constructible<T, allocator_arg_t, InnerAlloc, Args...>
{};
- #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
- //Without variadic templates, we need to use the preprocessor to generate
- //some specializations.
-
- #define BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS \
- BOOST_PP_ADD(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, 3)
- //!
-
- //Generate N+1 template parameters so that we can specialize N
- template<class T
- BOOST_PP_ENUM_TRAILING( BOOST_PP_ADD(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 1)
- , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT
- , void)
- >
- struct is_constructible_impl;
-
- //Generate N specializations, from 0 to
- //BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS parameters
- #define BOOST_PP_LOCAL_MACRO(n) \
- template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> \
- struct is_constructible_impl \
- <T BOOST_PP_ENUM_TRAILING_PARAMS(n, P) \
- BOOST_PP_ENUM_TRAILING \
- ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, n) \
- , BOOST_CONTAINER_PP_IDENTITY, void) \
- , void> \
- { \
- typedef char yes_type; \
- struct no_type \
- { char padding[2]; }; \
- \
- template<std::size_t N> \
- struct dummy; \
- \
- template<class X> \
- static yes_type test(dummy<sizeof(X(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_DECLVAL, ~)))>*); \
- \
- template<class X> \
- static no_type test(...); \
- \
- static const bool value = sizeof(test<T>(0)) == sizeof(yes_type); \
- }; \
- //!
-
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- //Finally just inherit from the implementation to define he trait
- template< class T
- BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS
- , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT
- , void)
- >
- struct is_constructible
- : boost::integral_constant
- < bool
- , is_constructible_impl
- < T
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, P)
- , void>::value
- >
- {};
-
- //Finally just inherit from the implementation to define he trait
- template <class T
- ,class InnerAlloc
- BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 2)
- , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT
- , void)
- >
- struct is_constructible_with_allocator_prefix
- : is_constructible
- < T, allocator_arg_t, InnerAlloc
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 2), P)
- >
- {};
-/*
- template <class T
- ,class InnerAlloc
- BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 1)
- , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT
- , void)
- >
- struct is_constructible_with_allocator_suffix
- : is_constructible
- < T
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_CONTAINER_MAX_IS_CONSTRUCTIBLE_PARAMETERS, 1), P)
- , InnerAlloc
- >
- {};*/
-
- #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-
-#else // #if !defined(BOOST_NO_SFINAE_EXPR)
+#else // #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
//Without advanced SFINAE expressions, we can't use is_constructible
//so backup to constructible_with_allocator_xxx
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- template < class T, class InnerAlloc, class ...Args>
+ template <class T, class InnerAlloc, class ...Args>
struct is_constructible_with_allocator_prefix
: constructible_with_allocator_prefix<T>
{};
-/*
- template < class T, class InnerAlloc, class ...Args>
+
+ template <class T, class InnerAlloc, class ...Args>
struct is_constructible_with_allocator_suffix
: constructible_with_allocator_suffix<T>
- {};*/
+ {};
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- template < class T
- , class InnerAlloc
- BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
- , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT
- , void)
- >
+ template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
struct is_constructible_with_allocator_prefix
: constructible_with_allocator_prefix<T>
{};
-/*
- template < class T
- , class InnerAlloc
- BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
- , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT
- , void)
- >
+
+ template <class T, class InnerAlloc, BOOST_MOVE_CLASSDFLT9>
struct is_constructible_with_allocator_suffix
: constructible_with_allocator_suffix<T>
- {};*/
+ {};
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -429,13 +327,14 @@ namespace container_detail {
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+// allocator_arg_t
template < typename OutermostAlloc
, typename InnerAlloc
, typename T
, class ...Args
>
inline void dispatch_allocator_prefix_suffix
- ( boost::true_type use_alloc_prefix, OutermostAlloc& outermost_alloc
+ ( true_type use_alloc_prefix, OutermostAlloc& outermost_alloc
, InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args) ...args)
{
(void)use_alloc_prefix;
@@ -443,13 +342,14 @@ inline void dispatch_allocator_prefix_suffix
( outermost_alloc, p, allocator_arg, inner_alloc, ::boost::forward<Args>(args)...);
}
+// allocator suffix
template < typename OutermostAlloc
, typename InnerAlloc
, typename T
, class ...Args
>
inline void dispatch_allocator_prefix_suffix
- ( boost::false_type use_alloc_prefix, OutermostAlloc& outermost_alloc
+ ( false_type use_alloc_prefix, OutermostAlloc& outermost_alloc
, InnerAlloc &inner_alloc, T* p, BOOST_FWD_REF(Args)...args)
{
(void)use_alloc_prefix;
@@ -463,14 +363,14 @@ template < typename OutermostAlloc
, class ...Args
>
inline void dispatch_uses_allocator
- ( boost::true_type uses_allocator, OutermostAlloc& outermost_alloc
+ ( true_type uses_allocator, OutermostAlloc& outermost_alloc
, InnerAlloc& inner_alloc, T* p, BOOST_FWD_REF(Args)...args)
{
(void)uses_allocator;
//BOOST_STATIC_ASSERT((is_constructible_with_allocator_prefix<T, InnerAlloc, Args...>::value ||
// is_constructible_with_allocator_suffix<T, InnerAlloc, Args...>::value ));
dispatch_allocator_prefix_suffix
- ( is_constructible_with_allocator_prefix<T, InnerAlloc, Args...>()
+ ( bool_< is_constructible_with_allocator_prefix<T, InnerAlloc, Args...>::value>()
, outermost_alloc, inner_alloc, p, ::boost::forward<Args>(args)...);
}
@@ -480,7 +380,7 @@ template < typename OutermostAlloc
, class ...Args
>
inline void dispatch_uses_allocator
- ( boost::false_type uses_allocator, OutermostAlloc & outermost_alloc
+ ( false_type uses_allocator, OutermostAlloc & outermost_alloc
, InnerAlloc & inner_alloc
,T* p, BOOST_FWD_REF(Args)...args)
{
@@ -491,78 +391,53 @@ inline void dispatch_uses_allocator
#else //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-#define BOOST_PP_LOCAL_MACRO(n) \
-template < typename OutermostAlloc \
- , typename InnerAlloc \
- , typename T \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \
- > \
-inline void dispatch_allocator_prefix_suffix( \
- boost::true_type use_alloc_prefix, \
- OutermostAlloc& outermost_alloc, \
- InnerAlloc& inner_alloc, \
- T* p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
-{ \
- (void)use_alloc_prefix, \
- allocator_traits<OutermostAlloc>::construct \
- (outermost_alloc, p, allocator_arg, inner_alloc \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
-} \
- \
-template < typename OutermostAlloc \
- , typename InnerAlloc \
- , typename T \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \
- > \
-inline void dispatch_allocator_prefix_suffix( \
- boost::false_type use_alloc_prefix, \
- OutermostAlloc& outermost_alloc, \
- InnerAlloc& inner_alloc, \
- T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
-{ \
- (void)use_alloc_prefix; \
- allocator_traits<OutermostAlloc>::construct \
- (outermost_alloc, p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
- , inner_alloc); \
-} \
- \
-template < typename OutermostAlloc \
- , typename InnerAlloc \
- , typename T \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \
- > \
-inline void dispatch_uses_allocator(boost::true_type uses_allocator, \
- OutermostAlloc& outermost_alloc, \
- InnerAlloc& inner_alloc, \
- T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
-{ \
- (void)uses_allocator; \
- dispatch_allocator_prefix_suffix \
- (is_constructible_with_allocator_prefix \
- < T, InnerAlloc BOOST_PP_ENUM_TRAILING_PARAMS(n, P)>() \
- , outermost_alloc, inner_alloc, p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
-} \
- \
-template < typename OutermostAlloc \
- , typename InnerAlloc \
- , typename T \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \
- > \
-inline void dispatch_uses_allocator(boost::false_type uses_allocator \
- ,OutermostAlloc & outermost_alloc \
- ,InnerAlloc & inner_alloc \
- ,T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
-{ \
- (void)uses_allocator; (void)inner_alloc; \
- allocator_traits<OutermostAlloc>::construct \
- (outermost_alloc, p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
-} \
-//!
-#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
-#include BOOST_PP_LOCAL_ITERATE()
+#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
+template < typename OutermostAlloc, typename InnerAlloc, typename T\
+ BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \
+inline void dispatch_allocator_prefix_suffix\
+ (true_type use_alloc_prefix, OutermostAlloc& outermost_alloc,\
+ InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+{\
+ (void)use_alloc_prefix,\
+ allocator_traits<OutermostAlloc>::construct\
+ (outermost_alloc, p, allocator_arg, inner_alloc BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+}\
+\
+template < typename OutermostAlloc, typename InnerAlloc, typename T\
+ BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+inline void dispatch_allocator_prefix_suffix\
+ (false_type use_alloc_prefix, OutermostAlloc& outermost_alloc,\
+ InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+{\
+ (void)use_alloc_prefix;\
+ allocator_traits<OutermostAlloc>::construct\
+ (outermost_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N, inner_alloc);\
+}\
+\
+template < typename OutermostAlloc, typename InnerAlloc, typename T\
+ BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+inline void dispatch_uses_allocator\
+ (true_type uses_allocator, OutermostAlloc& outermost_alloc,\
+ InnerAlloc& inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+{\
+ (void)uses_allocator;\
+ dispatch_allocator_prefix_suffix\
+ ( bool_< is_constructible_with_allocator_prefix<T, InnerAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::value >()\
+ , outermost_alloc, inner_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+}\
+\
+template < typename OutermostAlloc, typename InnerAlloc, typename T\
+ BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
+inline void dispatch_uses_allocator\
+ (false_type uses_allocator, OutermostAlloc &outermost_alloc,\
+ InnerAlloc &inner_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+{\
+ (void)uses_allocator; (void)inner_alloc;\
+ allocator_traits<OutermostAlloc>::construct(outermost_alloc, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+}\
+//
+BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE)
+#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE
#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
@@ -587,21 +462,22 @@ class scoped_allocator_adaptor_base
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef scoped_allocator_adaptor
<OuterAlloc, InnerAllocs...> scoped_allocator_type;
- typedef boost::integral_constant<
- bool,
+ typedef container_detail::bool_<
outer_traits_type::propagate_on_container_copy_assignment::value ||
inner_allocator_type::propagate_on_container_copy_assignment::value
> propagate_on_container_copy_assignment;
- typedef boost::integral_constant<
- bool,
+ typedef container_detail::bool_<
outer_traits_type::propagate_on_container_move_assignment::value ||
inner_allocator_type::propagate_on_container_move_assignment::value
> propagate_on_container_move_assignment;
- typedef boost::integral_constant<
- bool,
+ typedef container_detail::bool_<
outer_traits_type::propagate_on_container_swap::value ||
inner_allocator_type::propagate_on_container_swap::value
> propagate_on_container_swap;
+ typedef container_detail::bool_<
+ outer_traits_type::is_always_equal::value &&
+ inner_allocator_type::is_always_equal::value
+ > is_always_equal;
scoped_allocator_adaptor_base()
{}
@@ -668,23 +544,23 @@ class scoped_allocator_adaptor_base
void swap(scoped_allocator_adaptor_base &r)
{
- boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator());
- boost::container::swap_dispatch(this->m_inner, r.inner_allocator());
+ boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
+ boost::adl_move_swap(this->m_inner, r.inner_allocator());
}
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
{ l.swap(r); }
- inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT
+ inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return m_inner; }
- inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT
+ inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_inner; }
- outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT
+ outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<outer_allocator_type&>(*this); }
- const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<const outer_allocator_type&>(*this); }
scoped_allocator_type select_on_container_copy_construction() const
@@ -704,186 +580,157 @@ class scoped_allocator_adaptor_base
//Let's add a dummy first template parameter to allow creating
//specializations up to maximum InnerAlloc count
-template <
- typename OuterAlloc
- , bool Dummy
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q)
- >
+template <typename OuterAlloc, bool Dummy, BOOST_MOVE_CLASSDFLT9>
class scoped_allocator_adaptor_base;
//Specializations for the adaptor with InnerAlloc allocators
-#define BOOST_PP_LOCAL_MACRO(n) \
-template <typename OuterAlloc \
-BOOST_PP_ENUM_TRAILING_PARAMS(n, class Q) \
-> \
-class scoped_allocator_adaptor_base<OuterAlloc, true \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, Q) \
- BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
- , BOOST_CONTAINER_PP_IDENTITY, nat) \
- > \
- : public OuterAlloc \
-{ \
- typedef allocator_traits<OuterAlloc> outer_traits_type; \
- BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base) \
- \
- public: \
- template <class OuterA2> \
- struct rebind_base \
- { \
- typedef scoped_allocator_adaptor_base<OuterA2, true BOOST_PP_ENUM_TRAILING_PARAMS(n, Q) \
- BOOST_PP_ENUM_TRAILING \
- ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
- , BOOST_CONTAINER_PP_IDENTITY, nat) \
- > other; \
- }; \
- \
- typedef OuterAlloc outer_allocator_type; \
- typedef scoped_allocator_adaptor<BOOST_PP_ENUM_PARAMS(n, Q) \
- BOOST_PP_ENUM_TRAILING \
- ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
- , BOOST_CONTAINER_PP_IDENTITY, nat) \
- > inner_allocator_type; \
- typedef scoped_allocator_adaptor<OuterAlloc, BOOST_PP_ENUM_PARAMS(n, Q) \
- BOOST_PP_ENUM_TRAILING \
- ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
- , BOOST_CONTAINER_PP_IDENTITY, nat) \
- > scoped_allocator_type; \
- typedef allocator_traits<inner_allocator_type> inner_traits_type; \
- typedef boost::integral_constant< \
- bool, \
- outer_traits_type::propagate_on_container_copy_assignment::value || \
- inner_allocator_type::propagate_on_container_copy_assignment::value \
- > propagate_on_container_copy_assignment; \
- typedef boost::integral_constant< \
- bool, \
- outer_traits_type::propagate_on_container_move_assignment::value || \
- inner_allocator_type::propagate_on_container_move_assignment::value \
- > propagate_on_container_move_assignment; \
- typedef boost::integral_constant< \
- bool, \
- outer_traits_type::propagate_on_container_swap::value || \
- inner_allocator_type::propagate_on_container_swap::value \
- > propagate_on_container_swap; \
- \
- scoped_allocator_adaptor_base() \
- {} \
- \
- template <class OuterA2> \
- scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _)) \
- : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) \
- , m_inner(BOOST_PP_ENUM_PARAMS(n, q)) \
- {} \
- \
- scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other) \
- : outer_allocator_type(other.outer_allocator()) \
- , m_inner(other.inner_allocator()) \
- {} \
- \
- scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \
- : outer_allocator_type(::boost::move(other.outer_allocator())) \
- , m_inner(::boost::move(other.inner_allocator())) \
- {} \
- \
- template <class OuterA2> \
- scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base<OuterA2, true \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, Q) \
- BOOST_PP_ENUM_TRAILING \
- ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
- , BOOST_CONTAINER_PP_IDENTITY, nat) \
- >& other) \
- : outer_allocator_type(other.outer_allocator()) \
- , m_inner(other.inner_allocator()) \
- {} \
- \
- template <class OuterA2> \
- scoped_allocator_adaptor_base \
- (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, Q) \
- BOOST_PP_ENUM_TRAILING \
- ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
- , BOOST_CONTAINER_PP_IDENTITY, nat) \
- > BOOST_RV_REF_END other) \
- : outer_allocator_type(other.outer_allocator()) \
- , m_inner(other.inner_allocator()) \
- {} \
- \
- public: \
- struct internal_type_t{}; \
- \
- template <class OuterA2> \
- scoped_allocator_adaptor_base \
- ( internal_type_t \
- , BOOST_FWD_REF(OuterA2) outerAlloc \
- , const inner_allocator_type &inner) \
- : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc)) \
- , m_inner(inner) \
- {} \
- \
- public: \
- scoped_allocator_adaptor_base &operator= \
- (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other) \
- { \
- outer_allocator_type::operator=(other.outer_allocator()); \
- m_inner = other.inner_allocator(); \
- return *this; \
- } \
- \
- scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other) \
- { \
- outer_allocator_type::operator=(boost::move(other.outer_allocator())); \
- m_inner = ::boost::move(other.inner_allocator()); \
- return *this; \
- } \
- \
- void swap(scoped_allocator_adaptor_base &r) \
- { \
- boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator()); \
- boost::container::swap_dispatch(this->m_inner, r.inner_allocator()); \
- } \
- \
- friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) \
- { l.swap(r); } \
- \
- inner_allocator_type& inner_allocator() \
- { return m_inner; } \
- \
- inner_allocator_type const& inner_allocator() const \
- { return m_inner; } \
- \
- outer_allocator_type & outer_allocator() \
- { return static_cast<outer_allocator_type&>(*this); } \
- \
- const outer_allocator_type &outer_allocator() const \
- { return static_cast<const outer_allocator_type&>(*this); } \
- \
- scoped_allocator_type select_on_container_copy_construction() const \
- { \
- return scoped_allocator_type \
- (internal_type_t() \
- ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) \
- ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) \
- ); \
- } \
- private: \
- inner_allocator_type m_inner; \
-}; \
+#define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE(N)\
+template <typename OuterAlloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
+class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
+ : public OuterAlloc\
+{\
+ typedef allocator_traits<OuterAlloc> outer_traits_type;\
+ BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)\
+ \
+ public:\
+ template <class OuterA2>\
+ struct rebind_base\
+ {\
+ typedef scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> other;\
+ };\
+ \
+ typedef OuterAlloc outer_allocator_type;\
+ typedef scoped_allocator_adaptor<BOOST_MOVE_TARG##N> inner_allocator_type;\
+ typedef scoped_allocator_adaptor<OuterAlloc, BOOST_MOVE_TARG##N> scoped_allocator_type;\
+ typedef allocator_traits<inner_allocator_type> inner_traits_type;\
+ typedef container_detail::bool_<\
+ outer_traits_type::propagate_on_container_copy_assignment::value ||\
+ inner_allocator_type::propagate_on_container_copy_assignment::value\
+ > propagate_on_container_copy_assignment;\
+ typedef container_detail::bool_<\
+ outer_traits_type::propagate_on_container_move_assignment::value ||\
+ inner_allocator_type::propagate_on_container_move_assignment::value\
+ > propagate_on_container_move_assignment;\
+ typedef container_detail::bool_<\
+ outer_traits_type::propagate_on_container_swap::value ||\
+ inner_allocator_type::propagate_on_container_swap::value\
+ > propagate_on_container_swap;\
+ \
+ typedef container_detail::bool_<\
+ outer_traits_type::is_always_equal::value &&\
+ inner_allocator_type::is_always_equal::value\
+ > is_always_equal;\
+ \
+ scoped_allocator_adaptor_base(){}\
+ \
+ template <class OuterA2>\
+ scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\
+ : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
+ , m_inner(BOOST_MOVE_ARG##N)\
+ {}\
+ \
+ scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)\
+ : outer_allocator_type(other.outer_allocator())\
+ , m_inner(other.inner_allocator())\
+ {}\
+ \
+ scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
+ : outer_allocator_type(::boost::move(other.outer_allocator()))\
+ , m_inner(::boost::move(other.inner_allocator()))\
+ {}\
+ \
+ template <class OuterA2>\
+ scoped_allocator_adaptor_base\
+ (const scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N>& other)\
+ : outer_allocator_type(other.outer_allocator())\
+ , m_inner(other.inner_allocator())\
+ {}\
+ \
+ template <class OuterA2>\
+ scoped_allocator_adaptor_base\
+ (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2, true, BOOST_MOVE_TARG##N> BOOST_RV_REF_END other)\
+ : outer_allocator_type(other.outer_allocator())\
+ , m_inner(other.inner_allocator())\
+ {}\
+ \
+ public:\
+ struct internal_type_t{};\
+ \
+ template <class OuterA2>\
+ scoped_allocator_adaptor_base\
+ ( internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &inner)\
+ : outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))\
+ , m_inner(inner)\
+ {}\
+ \
+ public:\
+ scoped_allocator_adaptor_base &operator=\
+ (BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\
+ {\
+ outer_allocator_type::operator=(other.outer_allocator());\
+ m_inner = other.inner_allocator();\
+ return *this;\
+ }\
+ \
+ scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
+ {\
+ outer_allocator_type::operator=(boost::move(other.outer_allocator()));\
+ m_inner = ::boost::move(other.inner_allocator());\
+ return *this;\
+ }\
+ \
+ void swap(scoped_allocator_adaptor_base &r)\
+ {\
+ boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());\
+ boost::adl_move_swap(this->m_inner, r.inner_allocator());\
+ }\
+ \
+ friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\
+ { l.swap(r); }\
+ \
+ inner_allocator_type& inner_allocator()\
+ { return m_inner; }\
+ \
+ inner_allocator_type const& inner_allocator() const\
+ { return m_inner; }\
+ \
+ outer_allocator_type & outer_allocator()\
+ { return static_cast<outer_allocator_type&>(*this); }\
+ \
+ const outer_allocator_type &outer_allocator() const\
+ { return static_cast<const outer_allocator_type&>(*this); }\
+ \
+ scoped_allocator_type select_on_container_copy_construction() const\
+ {\
+ return scoped_allocator_type\
+ (internal_type_t()\
+ ,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())\
+ ,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())\
+ );\
+ }\
+ private:\
+ inner_allocator_type m_inner;\
+};\
//!
-#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
-#include BOOST_PP_LOCAL_ITERATE()
+BOOST_MOVE_ITERATE_1TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE)
+#undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_BASE_CODE
#endif //#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE ,true
+ #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER BOOST_MOVE_TARG9
+ #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS BOOST_MOVE_CLASS9
+#else
+ #define BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE
+ #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNER InnerAllocs...
+ #define BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS typename... InnerAllocs
+#endif
+
//Specialization for adaptor without any InnerAlloc
template <typename OuterAlloc>
-class scoped_allocator_adaptor_base
- < OuterAlloc
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- , true
- BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, nat)
- #endif
- >
+class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>
: public OuterAlloc
{
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor_base)
@@ -894,11 +741,7 @@ class scoped_allocator_adaptor_base
{
typedef scoped_allocator_adaptor_base
<typename allocator_traits<OuterAlloc>::template portable_rebind_alloc<U>::type
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- , true
- BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat)
- #endif
- > other;
+ BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE > other;
};
typedef OuterAlloc outer_allocator_type;
@@ -912,6 +755,8 @@ class scoped_allocator_adaptor_base
propagate_on_container_move_assignment propagate_on_container_move_assignment;
typedef typename outer_traits_type::
propagate_on_container_swap propagate_on_container_swap;
+ typedef typename outer_traits_type::
+ is_always_equal is_always_equal;
scoped_allocator_adaptor_base()
{}
@@ -931,25 +776,13 @@ class scoped_allocator_adaptor_base
template <class OuterA2>
scoped_allocator_adaptor_base
- (const scoped_allocator_adaptor_base<
- OuterA2
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- , true
- BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat)
- #endif
- >& other)
+ (const scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE>& other)
: outer_allocator_type(other.outer_allocator())
{}
template <class OuterA2>
scoped_allocator_adaptor_base
- (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<
- OuterA2
- #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- , true
- BOOST_PP_ENUM_TRAILING(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, BOOST_CONTAINER_PP_IDENTITY, container_detail::nat)
- #endif
- > BOOST_RV_REF_END other)
+ (BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other)
: outer_allocator_type(other.outer_allocator())
{}
@@ -976,7 +809,7 @@ class scoped_allocator_adaptor_base
void swap(scoped_allocator_adaptor_base &r)
{
- boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator());
+ boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
}
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
@@ -1013,78 +846,65 @@ class scoped_allocator_adaptor_base
//Scoped allocator
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
- //! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor.
- //! The class template scoped_allocator_adaptor is an allocator template that specifies
- //! the memory resource (the outer allocator) to be used by a container (as any other
- //! allocator does) and also specifies an inner allocator resource to be passed to
- //! the constructor of every element within the container.
- //!
- //! This adaptor is
- //! instantiated with one outer and zero or more inner allocator types. If
- //! instantiated with only one allocator type, the inner allocator becomes the
- //! scoped_allocator_adaptor itself, thus using the same allocator resource for the
- //! container and every element within the container and, if the elements themselves
- //! are containers, each of their elements recursively. If instantiated with more than
- //! one allocator, the first allocator is the outer allocator for use by the container,
- //! the second allocator is passed to the constructors of the container's elements,
- //! and, if the elements themselves are containers, the third allocator is passed to
- //! the elements' elements, and so on. If containers are nested to a depth greater
- //! than the number of allocators, the last allocator is used repeatedly, as in the
- //! single-allocator case, for any remaining recursions.
- //!
- //! [<b>Note</b>: The
- //! 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, <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>: <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
+//! This class is a C++03-compatible implementation of std::scoped_allocator_adaptor.
+//! The class template scoped_allocator_adaptor is an allocator template that specifies
+//! the memory resource (the outer allocator) to be used by a container (as any other
+//! allocator does) and also specifies an inner allocator resource to be passed to
+//! the constructor of every element within the container.
+//!
+//! This adaptor is
+//! instantiated with one outer and zero or more inner allocator types. If
+//! instantiated with only one allocator type, the inner allocator becomes the
+//! scoped_allocator_adaptor itself, thus using the same allocator resource for the
+//! container and every element within the container and, if the elements themselves
+//! are containers, each of their elements recursively. If instantiated with more than
+//! one allocator, the first allocator is the outer allocator for use by the container,
+//! the second allocator is passed to the constructors of the container's elements,
+//! and, if the elements themselves are containers, the third allocator is passed to
+//! the elements' elements, and so on. If containers are nested to a depth greater
+//! than the number of allocators, the last allocator is used repeatedly, as in the
+//! single-allocator case, for any remaining recursions.
+//!
+//! [<b>Note</b>: The
+//! 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, <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>: <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
- #else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
- template <typename OuterAlloc, typename ...InnerAllocs>
- class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
+template <typename OuterAlloc, typename ...InnerAllocs>
+class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>
- #endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
+#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-template <typename OuterAlloc
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q)
- >
+template <typename OuterAlloc, BOOST_MOVE_CLASS9>
class scoped_allocator_adaptor
#endif
+
: public container_detail::scoped_allocator_adaptor_base
- <OuterAlloc
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , InnerAllocs...
- #else
- , true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- >
+ <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
{
BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor)
public:
#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)
- , InnerAllocs...
- #else
- , true BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- > base_type;
+ <OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> base_type;
typedef typename base_type::internal_type_t internal_type_t;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef OuterAlloc outer_allocator_type;
@@ -1102,19 +922,29 @@ 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: <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.
+ //! Type: A type with a constant boolean <code>value</code> == true if
+ //!`allocator_traits<Allocator>::propagate_on_container_copy_assignment::value` is
+ //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
typedef typename base_type::
propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
- //! 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.
+ //! Type: A type with a constant boolean <code>value</code> == true if
+ //!`allocator_traits<Allocator>::propagate_on_container_move_assignment::value` is
+ //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
typedef typename base_type::
propagate_on_container_move_assignment propagate_on_container_move_assignment;
- //! 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.
+
+ //! Type: A type with a constant boolean <code>value</code> == true if
+ //! `allocator_traits<Allocator>::propagate_on_container_swap::value` is
+ //! true for any <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
typedef typename base_type::
propagate_on_container_swap propagate_on_container_swap;
+ //! Type: A type with a constant boolean <code>value</code> == true if
+ //!`allocator_traits<Allocator>::is_always_equal::value` is
+ //! true for all <code>Allocator</code> in the set of <code>OuterAlloc</code> and <code>InnerAllocs...</code>, false otherwise.
+ typedef typename base_type::
+ is_always_equal is_always_equal;
+
//! Type: Rebinds scoped allocator to
//! <code>typedef scoped_allocator_adaptor
//! < typename outer_traits_type::template portable_rebind_alloc<U>::type
@@ -1124,12 +954,7 @@ class scoped_allocator_adaptor
{
typedef scoped_allocator_adaptor
< typename outer_traits_type::template portable_rebind_alloc<U>::type
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , InnerAllocs...
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- > other;
+ , BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> other;
};
//! <b>Effects</b>: value-initializes the OuterAlloc base class
@@ -1165,17 +990,14 @@ class scoped_allocator_adaptor
{}
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- #define BOOST_PP_LOCAL_MACRO(n) \
- template <class OuterA2> \
- scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_CONST_REF_PARAM_LIST_Q, _)) \
- : base_type(::boost::forward<OuterA2>(outerAlloc) \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, q) \
- ) \
- {} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE(N)\
+ template <class OuterA2>\
+ scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc BOOST_MOVE_I##N BOOST_MOVE_CREF##N)\
+ : base_type(::boost::forward<OuterA2>(outerAlloc) BOOST_MOVE_I##N BOOST_MOVE_ARG##N)\
+ {}\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE)
+ #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_ADAPTOR_RELATED_ALLOCATOR_CONSTRUCTOR_CODE
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1183,13 +1005,7 @@ class scoped_allocator_adaptor
//!
//! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator from other.
template <class OuterA2>
- scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , InnerAllocs...
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- > &other)
+ scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other)
: base_type(other.base())
{}
@@ -1198,13 +1014,8 @@ class scoped_allocator_adaptor
//! <b>Effects</b>: initializes each allocator within the adaptor with the corresponding allocator
//! rvalue from other.
template <class OuterA2>
- scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor<OuterA2
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , InnerAllocs...
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- > BOOST_RV_REF_END other)
+ scoped_allocator_adaptor(BOOST_RV_REF_BEG scoped_allocator_adaptor
+ <OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> BOOST_RV_REF_END other)
: base_type(::boost::move(other.base()))
{}
@@ -1212,7 +1023,7 @@ class scoped_allocator_adaptor
{ return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
- { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(static_cast<base_type&>(other)))); }
+ { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); }
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Effects</b>: swaps *this with r.
@@ -1225,33 +1036,31 @@ class scoped_allocator_adaptor
//! <b>Returns</b>:
//! <code>static_cast<OuterAlloc&>(*this)</code>.
- outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT;
+ outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Returns</b>:
//! <code>static_cast<const OuterAlloc&>(*this)</code>.
- const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT;
+ const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Returns</b>:
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
- inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT;
+ inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW;
//! <b>Returns</b>:
//! *this if <code>sizeof...(InnerAllocs)</code> is zero; otherwise, inner.
- inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT;
+ inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW;
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>:
//! <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());
- }
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+ { return outer_traits_type::max_size(this->outer_allocator()); }
//! <b>Effects</b>:
//! calls <code>OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)</code>.
template <class T>
- void destroy(T* p) BOOST_CONTAINER_NOEXCEPT
+ void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW
{
allocator_traits<typename outermost_allocator<OuterAlloc>::type>
::destroy(get_outermost_allocator(this->outer_allocator()), p);
@@ -1260,27 +1069,21 @@ class scoped_allocator_adaptor
//! <b>Returns</b>:
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
pointer allocate(size_type n)
- {
- return outer_traits_type::allocate(this->outer_allocator(), n);
- }
+ { return outer_traits_type::allocate(this->outer_allocator(), n); }
//! <b>Returns</b>:
//! <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);
- }
+ { return outer_traits_type::allocate(this->outer_allocator(), n, hint); }
//! <b>Effects</b>:
//! <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);
- }
+ { outer_traits_type::deallocate(this->outer_allocator(), p, n); }
#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
+ //! <b>Returns</b>: A new scoped_allocator_adaptor object where each allocator
+ //! Allocator in the adaptor is initialized from the result of calling
//! <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;
@@ -1331,7 +1134,7 @@ class scoped_allocator_adaptor
construct(T* p, BOOST_FWD_REF(Args)...args)
{
container_detail::dispatch_uses_allocator
- ( uses_allocator<T, inner_allocator_type>()
+ ( container_detail::bool_<uses_allocator<T, inner_allocator_type>::value>()
, get_outermost_allocator(this->outer_allocator())
, this->inner_allocator()
, p, ::boost::forward<Args>(args)...);
@@ -1341,22 +1144,19 @@ class scoped_allocator_adaptor
//Disable this overload if the first argument is pair as some compilers have
//overload selection problems when the first parameter is a pair.
- #define BOOST_PP_LOCAL_MACRO(n) \
- template < typename T \
- BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \
- > \
- typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type \
- construct(T* p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- container_detail::dispatch_uses_allocator \
- ( uses_allocator<T, inner_allocator_type>() \
- , get_outermost_allocator(this->outer_allocator()) \
- , this->inner_allocator() \
- , p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \
+ template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
+ typename container_detail::enable_if_c<!container_detail::is_pair<T>::value, void>::type\
+ construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
+ {\
+ container_detail::dispatch_uses_allocator\
+ ( container_detail::bool_<uses_allocator<T, inner_allocator_type>::value>()\
+ , get_outermost_allocator(this->outer_allocator())\
+ , this->inner_allocator(), p BOOST_MOVE_I##N BOOST_MOVE_FWDQ##N);\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE)
+ #undef BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1427,31 +1227,11 @@ class scoped_allocator_adaptor
template <class Pair, class Pair2>
void construct_pair(Pair* p, const Pair2& pr)
- {
- this->construct(container_detail::addressof(p->first), pr.first);
- BOOST_TRY{
- this->construct(container_detail::addressof(p->second), pr.second);
- }
- BOOST_CATCH(...){
- this->destroy(container_detail::addressof(p->first));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
+ { this->construct_pair(p, pr.first, pr.second); }
template <class Pair, class Pair2>
void construct_pair(Pair* p, BOOST_RV_REF(Pair2) pr)
- {
- this->construct(container_detail::addressof(p->first), ::boost::move(pr.first));
- BOOST_TRY{
- this->construct(container_detail::addressof(p->second), ::boost::move(pr.second));
- }
- BOOST_CATCH(...){
- this->destroy(container_detail::addressof(p->first));
- BOOST_RETHROW
- }
- BOOST_CATCH_END
- }
+ { this->construct_pair(p, ::boost::move(pr.first), ::boost::move(pr.second)); }
//template <class T1, class T2, class... Args1, class... Args2>
//void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
@@ -1466,66 +1246,29 @@ class scoped_allocator_adaptor
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
-template <typename OuterA1, typename OuterA2
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename... InnerAllocs
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q)
- #endif
- >
-inline bool operator==(
- const scoped_allocator_adaptor<OuterA1
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- ,InnerAllocs...
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- >& a,
- const scoped_allocator_adaptor<OuterA2
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- ,InnerAllocs...
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- >& b)
+template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
+inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
+ ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
{
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
const bool has_zero_inner = sizeof...(InnerAllocs) == 0u;
#else
- const bool has_zero_inner =
- boost::container::container_detail::is_same
- <Q0, container_detail::nat>::value;
+ const bool has_zero_inner = boost::container::container_detail::is_same<P0, void>::value;
#endif
-
- return a.outer_allocator() == b.outer_allocator()
- && (has_zero_inner || a.inner_allocator() == b.inner_allocator());
+ typedef typename scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
+ ::outer_allocator_type outer_allocator_type;
+ typedef typename scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>
+ ::inner_allocator_type inner_allocator_type;
+
+ return allocator_traits<outer_allocator_type>::equal(a.outer_allocator(), b.outer_allocator())
+ && (has_zero_inner ||
+ allocator_traits<inner_allocator_type>::equal(a.inner_allocator(), b.inner_allocator()));
}
-template <typename OuterA1, typename OuterA2
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- , typename... InnerAllocs
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, class Q)
- #endif
- >
-inline bool operator!=(
- const scoped_allocator_adaptor<OuterA1
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- ,InnerAllocs...
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- >& a,
- const scoped_allocator_adaptor<OuterA2
- #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- ,InnerAllocs...
- #else
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, Q)
- #endif
- >& b)
-{
- return ! (a == b);
-}
+template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
+inline bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
+ ,const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& b)
+{ return !(a == b); }
}} // namespace boost { namespace container {
diff --git a/boost/container/scoped_allocator_fwd.hpp b/boost/container/scoped_allocator_fwd.hpp
index f19e27e885..003ed9f7f7 100644
--- a/boost/container/scoped_allocator_fwd.hpp
+++ b/boost/container/scoped_allocator_fwd.hpp
@@ -15,16 +15,20 @@
//! This header file forward declares boost::container::scoped_allocator_adaptor
//! and defines the following types:
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/std_fwd.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-#include <boost/container/detail/preprocessor.hpp>
-#include <boost/container/detail/type_traits.hpp>
+#include <boost/move/detail/fwd_macros.hpp>
#endif
namespace boost { namespace container {
@@ -35,41 +39,48 @@ namespace boost { namespace container {
#if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
- template <typename OuterAlloc, typename ...InnerAllocs>
- class scoped_allocator_adaptor;
+ template <typename OuterAlloc, typename ...InnerAllocs>
+ class scoped_allocator_adaptor;
#else // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
- template <typename ...InnerAllocs>
- class scoped_allocator_adaptor;
+ template <typename ...InnerAllocs>
+ class scoped_allocator_adaptor;
- template <typename OuterAlloc, typename ...InnerAllocs>
- class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
+ template <typename OuterAlloc, typename ...InnerAllocs>
+ class scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
#endif // #if !defined(BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST)
-
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-template <typename OuterAlloc
-BOOST_PP_ENUM_TRAILING( BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS
- , BOOST_CONTAINER_PP_TEMPLATE_PARAM_WITH_DEFAULT, container_detail::nat)
->
-class scoped_allocator_adaptor;
+ template <typename OuterAlloc, BOOST_MOVE_CLASSDFLT9>
+ class scoped_allocator_adaptor;
#endif
+ template <int Dummy = 0>
+ struct std_allocator_arg_holder
+ {
+ static ::std::allocator_arg_t *dummy;
+ };
+
+ template <int Dummy>
+ ::std::allocator_arg_t *std_allocator_arg_holder<Dummy>::dummy;
+
+#else //BOOST_CONTAINER_DOXYGEN_INVOKED
+
#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
//! have constructors with allocator_arg_t as the first argument, immediately followed
-//! by an argument of a type that satisfies the Allocator requirements
-struct allocator_arg_t{};
+//! by an argument of a type that satisfies Allocator requirements
+typedef const std::allocator_arg_t & allocator_arg_t;
//! A instance of type allocator_arg_t
//!
-static const allocator_arg_t allocator_arg = allocator_arg_t();
+static allocator_arg_t allocator_arg = BOOST_CONTAINER_DOC1ST(unspecified, *std_allocator_arg_holder<>::dummy);
template <class T>
struct constructible_with_allocator_suffix;
@@ -77,7 +88,7 @@ struct constructible_with_allocator_suffix;
template <class T>
struct constructible_with_allocator_prefix;
-template <typename T, typename Alloc>
+template <typename T, typename Allocator>
struct uses_allocator;
}} // namespace boost { namespace container {
diff --git a/boost/container/set.hpp b/boost/container/set.hpp
index 3e2c2aad0d..79fa1aec66 100644
--- a/boost/container/set.hpp
+++ b/boost/container/set.hpp
@@ -11,27 +11,34 @@
#ifndef BOOST_CONTAINER_SET_HPP
#define BOOST_CONTAINER_SET_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+// container
#include <boost/container/container_fwd.hpp>
-
-#include <utility>
-#include <functional>
-#include <memory>
-
-#include <boost/move/utility_core.hpp>
-#include <boost/move/detail/move_helpers.hpp>
-#include <boost/move/traits.hpp>
+// container/detail
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/tree.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+#include <boost/intrusive/detail/minimal_less_equal_header.hpp>//less, equal
+// move
+#include <boost/move/traits.hpp>
#include <boost/move/utility_core.hpp>
-#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-#include <boost/container/detail/preprocessor.hpp>
+// move/detail
+#include <boost/move/detail/move_helpers.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
#endif
+// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
@@ -53,7 +60,7 @@ namespace container {
//! \tparam Compare is the comparison functor used to order keys
//! \tparam Allocator is the allocator to be used to allocate memory for this container
//! \tparam SetOptions is an packed option type generated using using boost::container::tree_assoc_options.
-template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>, class SetOptions = tree_assoc_defaults >
+template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class SetOptions = tree_assoc_defaults >
#else
template <class Key, class Compare, class Allocator, class SetOptions>
#endif
@@ -134,6 +141,16 @@ class set
: base_t(true, first, last, comp, a)
{}
+ //! <b>Effects</b>: Constructs an empty set using the specified
+ //! allocator, and inserts elements from the range [first ,last ).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [first ,last ) is already sorted using
+ //! comp and otherwise N logN, where N is last - first.
+ template <class InputIterator>
+ set(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(true, first, last, key_compare(), a)
+ {}
+
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [first ,last). This function
//! is more efficient than the normal range creation for ordered ranges.
@@ -160,6 +177,15 @@ class set
: base_t(true, il.begin(), il.end(), comp, a)
{}
+ //! <b>Effects</b>: Constructs an empty set using the specified
+ //! allocator, and inserts elements from the range [il.begin(), il.end()).
+ //!
+ //! <b>Complexity</b>: Linear in N if the range [il.begin(), il.end()) is already sorted using
+ //! comp and otherwise N logN, where N is il.begin() - il.end().
+ set(std::initializer_list<value_type> il, const allocator_type& a)
+ : base_t(true, il.begin(), il.end(), Compare(), a)
+ {}
+
//! <b>Effects</b>: Constructs an empty set using the specified comparison object and
//! allocator, and inserts elements from the ordered unique range [il.begin(), il.end()). This function
//! is more efficient than the normal range creation for ordered ranges.
@@ -170,7 +196,8 @@ class set
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
- set(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
+ set( ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare()
+ , const allocator_type& a = allocator_type())
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{}
#endif
@@ -188,7 +215,7 @@ class set
//!
//! <b>Postcondition</b>: x is emptied.
set(BOOST_RV_REF(set) x)
- : base_t(boost::move(static_cast<base_t&>(x)))
+ : base_t(BOOST_MOVE_BASE(base_t, x))
{}
//! <b>Effects</b>: Copy constructs a set using the specified allocator.
@@ -203,7 +230,7 @@ class set
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
set(BOOST_RV_REF(set) x, const allocator_type &a)
- : base_t(boost::move(static_cast<base_t&>(x)), a)
+ : base_t(BOOST_MOVE_BASE(base_t, x), a)
{}
//! <b>Effects</b>: Makes *this a copy of x.
@@ -221,8 +248,9 @@ class set
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
set& operator=(BOOST_RV_REF(set) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
- { return static_cast<set&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
+ { return static_cast<set&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
set& operator=(std::initializer_list<value_type> il)
@@ -235,7 +263,7 @@ class set
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! <b>Effects</b>: Returns a copy of the Allocator that
+ //! <b>Effects</b>: Returns a copy of the allocator that
//! was passed to the object's constructor.
//!
//! <b>Complexity</b>: Constant.
@@ -371,7 +399,7 @@ class set
size_type max_size() const;
#endif // #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object x of type Key constructed with
//! std::forward<Args>(args)... if and only if there is
@@ -388,7 +416,7 @@ class set
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
- std::pair<iterator,bool> emplace(Args&&... args)
+ std::pair<iterator,bool> emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_unique(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -401,26 +429,24 @@ class set
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
- iterator emplace_hint(const_iterator p, Args&&... args)
+ iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_unique(p, boost::forward<Args>(args)...); }
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }\
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_hint_unique(p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_SET_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ std::pair<iterator,bool> emplace(BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_unique(BOOST_MOVE_FWD##N); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_hint_unique(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SET_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_SET_EMPLACE_CODE
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x if and only if there is no element in the container
@@ -521,7 +547,9 @@ class set
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- void swap(set& x);
+ void swap(set& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value );
//! <b>Effects</b>: erase(a.begin(),a.end()).
//!
@@ -548,7 +576,7 @@ class set
//! <b>Complexity</b>: Logarithmic.
iterator find(const key_type& x);
- //! <b>Returns</b>: Allocator const_iterator pointing to an element with the key
+ //! <b>Returns</b>: A const_iterator pointing to an element with the key
//! equivalent to x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
@@ -576,7 +604,7 @@ class set
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than k, or a.end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -588,7 +616,7 @@ class set
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x);
- //! <b>Returns</b>: Allocator const iterator pointing to the first element with key not
+ //! <b>Returns</b>: A const iterator pointing to the first element with key not
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -680,10 +708,13 @@ class set
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class Key, class C, class SetOptions, class Allocator>
-struct has_trivial_destructor_after_move<boost::container::set<Key, C, Allocator, SetOptions> >
+template <class Key, class Compare, class SetOptions, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::set<Key, Compare, Allocator, SetOptions> >
{
- static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -704,7 +735,7 @@ namespace container {
//! \tparam Compare is the comparison functor used to order keys
//! \tparam Allocator is the allocator to be used to allocate memory for this container
//! \tparam MultiSetOptions is an packed option type generated using using boost::container::tree_assoc_options.
-template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>, class MultiSetOptions = tree_assoc_defaults >
+template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class MultiSetOptions = tree_assoc_defaults >
#else
template <class Key, class Compare, class Allocator, class MultiSetOptions>
#endif
@@ -776,6 +807,12 @@ class multiset
: base_t(false, first, last, comp, a)
{}
+ //! @copydoc ::boost::container::set::set(InputIterator, InputIterator, const allocator_type&)
+ template <class InputIterator>
+ multiset(InputIterator first, InputIterator last, const allocator_type& a)
+ : base_t(false, first, last, key_compare(), a)
+ {}
+
//! <b>Effects</b>: Constructs an empty multiset using the specified comparison object and
//! allocator, and inserts elements from the ordered range [first ,last ). This function
//! is more efficient than the normal range creation for ordered ranges.
@@ -798,13 +835,17 @@ class multiset
: base_t(false, il.begin(), il.end(), comp, a)
{}
+ //! @copydoc ::boost::container::set::set(std::initializer_list<value_type>, const allocator_type&)
+ multiset(std::initializer_list<value_type> il, const allocator_type& a)
+ : base_t(false, il.begin(), il.end(), Compare(), a)
+ {}
+
//! @copydoc ::boost::container::set::set(ordered_unique_range_t, std::initializer_list<value_type>, const Compare& comp, const allocator_type&)
multiset(ordered_unique_range_t, std::initializer_list<value_type> il, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
: base_t(ordered_range, il.begin(), il.end(), comp, a)
{}
#endif
-
//! @copydoc ::boost::container::set::set(const set &)
multiset(const multiset& x)
: base_t(static_cast<const base_t&>(x))
@@ -812,7 +853,7 @@ class multiset
//! @copydoc ::boost::container::set(set &&)
multiset(BOOST_RV_REF(multiset) x)
- : base_t(boost::move(static_cast<base_t&>(x)))
+ : base_t(BOOST_MOVE_BASE(base_t, x))
{}
//! @copydoc ::boost::container::set(const set &, const allocator_type &)
@@ -822,7 +863,7 @@ class multiset
//! @copydoc ::boost::container::set(set &&, const allocator_type &)
multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
- : base_t(boost::move(static_cast<base_t&>(x)), a)
+ : base_t(BOOST_MOVE_BASE(base_t, x), a)
{}
//! @copydoc ::boost::container::set::operator=(const set &)
@@ -831,7 +872,9 @@ class multiset
//! @copydoc ::boost::container::set::operator=(set &&)
multiset& operator=(BOOST_RV_REF(multiset) x)
- { return static_cast<multiset&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_move_assignable<Compare>::value )
+ { return static_cast<multiset&>(this->base_t::operator=(BOOST_MOVE_BASE(base_t, x))); }
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! @copydoc ::boost::container::set::operator=(std::initializer_list<value_type>)
@@ -863,31 +906,31 @@ class multiset
const_iterator cbegin() const;
//! @copydoc ::boost::container::set::end()
- iterator end() BOOST_CONTAINER_NOEXCEPT;
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::end() const
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::cend() const
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::rbegin()
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::rbegin() const
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::crbegin() const
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::rend()
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::rend() const
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::crend() const
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::empty() const
bool empty() const;
@@ -900,7 +943,7 @@ class multiset
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type Key constructed with
//! std::forward<Args>(args)... and returns the iterator pointing to the
@@ -908,7 +951,7 @@ class multiset
//!
//! <b>Complexity</b>: Logarithmic.
template <class... Args>
- iterator emplace(Args&&... args)
+ iterator emplace(BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_equal(boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type Key constructed with
@@ -920,26 +963,24 @@ class multiset
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if t
//! is inserted right before p.
template <class... Args>
- iterator emplace_hint(const_iterator p, Args&&... args)
+ iterator emplace_hint(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->base_t::emplace_hint_equal(p, boost::forward<Args>(args)...); }
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_hint(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { return this->base_t::emplace_hint_equal(p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));} \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
+ #define BOOST_CONTAINER_MULTISET_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_equal(BOOST_MOVE_FWD##N); }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_hint(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ { return this->base_t::emplace_hint_equal(hint BOOST_MOVE_I##N BOOST_MOVE_FWD##N); }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_MULTISET_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_MULTISET_EMPLACE_CODE
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts x and returns the iterator pointing to the
@@ -996,7 +1037,7 @@ class multiset
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! @copydoc ::boost::container::set::insert(std::initializer_list<value_type>)
void insert(std::initializer_list<value_type> il)
- { this->base_t::insert_unique(il.begin(), il.end()); }
+ { this->base_t::insert_equal(il.begin(), il.end()); }
#endif
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1011,10 +1052,12 @@ class multiset
iterator erase(const_iterator first, const_iterator last);
//! @copydoc ::boost::container::set::swap
- void swap(flat_multiset& x);
+ void swap(multiset& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
+ && boost::container::container_detail::is_nothrow_swappable<Compare>::value );
//! @copydoc ::boost::container::set::clear
- void clear() BOOST_CONTAINER_NOEXCEPT;
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW;
//! @copydoc ::boost::container::set::key_comp
key_compare key_comp() const;
@@ -1108,10 +1151,13 @@ class multiset
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
-template <class Key, class C, class Allocator, class MultiSetOptions>
-struct has_trivial_destructor_after_move<boost::container::multiset<Key, C, Allocator, MultiSetOptions> >
+template <class Key, class Compare, class Allocator, class MultiSetOptions>
+struct has_trivial_destructor_after_move<boost::container::multiset<Key, Compare, Allocator, MultiSetOptions> >
{
- static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value &&
+ ::boost::has_trivial_destructor_after_move<Compare>::value;
};
namespace container {
@@ -1122,5 +1168,4 @@ namespace container {
#include <boost/container/detail/config_end.hpp>
-#endif /* BOOST_CONTAINER_SET_HPP */
-
+#endif // BOOST_CONTAINER_SET_HPP
diff --git a/boost/container/slist.hpp b/boost/container/slist.hpp
index b6b4c388a2..b0901ef086 100644
--- a/boost/container/slist.hpp
+++ b/boost/container/slist.hpp
@@ -11,46 +11,48 @@
#ifndef BOOST_CONTAINER_SLIST_HPP
#define BOOST_CONTAINER_SLIST_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+// container
#include <boost/container/container_fwd.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
-#include <boost/move/utility_core.hpp>
-#include <boost/move/detail/move_helpers.hpp>
-#include <boost/move/traits.hpp>
-#include <boost/intrusive/pointer_traits.hpp>
-#include <boost/container/detail/utilities.hpp>
+// container/detail
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/compare_functors.hpp>
+#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/mpl.hpp>
-#include <boost/container/detail/type_traits.hpp>
-#include <boost/core/no_exceptions_support.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// intrusive
+#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/slist.hpp>
-#include <iterator>
-
-
-#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
-//Preprocessor library to emulate perfect forwarding
-#else
-#include <boost/container/detail/preprocessor.hpp>
+// move
+#include <boost/move/iterator.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
#endif
-
-#include <iterator>
-#include <utility>
-#include <memory>
-#include <functional>
-#include <algorithm>
-
+#include <boost/move/detail/move_helpers.hpp>
+// other
+#include <boost/core/no_exceptions_support.hpp>
+// std
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
-
namespace boost {
namespace container {
@@ -155,7 +157,7 @@ struct intrusive_slist_type
//! \tparam T The type of object that is stored in the list
//! \tparam Allocator The allocator used for all internal memory management
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
-template <class T, class Allocator = std::allocator<T> >
+template <class T, class Allocator = new_allocator<T> >
#else
template <class T, class Allocator>
#endif
@@ -167,48 +169,19 @@ class slist
typedef typename
container_detail::intrusive_slist_type<Allocator>::type Icont;
typedef container_detail::node_alloc_holder<Allocator, Icont> AllocHolder;
- typedef typename AllocHolder::NodePtr NodePtr;
- typedef typename AllocHolder::NodeAlloc NodeAlloc;
- typedef typename AllocHolder::ValAlloc ValAlloc;
- typedef typename AllocHolder::Node Node;
- typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
- typedef typename AllocHolder::allocator_v1 allocator_v1;
- typedef typename AllocHolder::allocator_v2 allocator_v2;
- typedef typename AllocHolder::alloc_version alloc_version;
- typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
-
- class equal_to_value
- {
- typedef typename AllocHolder::value_type value_type;
- const value_type &t_;
-
- public:
- equal_to_value(const value_type &t)
- : t_(t)
- {}
-
- bool operator()(const value_type &t)const
- { return t_ == t; }
- };
-
- template<class Pred>
- struct ValueCompareToNodeCompare
- : Pred
- {
- ValueCompareToNodeCompare(Pred pred)
- : Pred(pred)
- {}
-
- bool operator()(const Node &a, const Node &b) const
- { return static_cast<const Pred&>(*this)(a.m_data, b.m_data); }
-
- bool operator()(const Node &a) const
- { return static_cast<const Pred&>(*this)(a.m_data); }
- };
+ typedef typename AllocHolder::NodePtr NodePtr;
+ typedef typename AllocHolder::NodeAlloc NodeAlloc;
+ typedef typename AllocHolder::ValAlloc ValAlloc;
+ typedef typename AllocHolder::Node Node;
+ typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
+ typedef typename AllocHolder::alloc_version alloc_version;
+ typedef boost::container::
+ allocator_traits<Allocator> allocator_traits_type;
+ typedef boost::container::equal_to_value<Allocator> equal_to_value_type;
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;
+ typedef container_detail::iterator_from_iiterator<typename Icont::iterator, false> iterator_impl;
+ typedef container_detail::iterator_from_iiterator<typename Icont::iterator, true > const_iterator_impl;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -252,10 +225,17 @@ class slist
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit slist(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
+ explicit slist(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
: AllocHolder(a)
{}
+ //! <b>Effects</b>: Constructs a list
+ //! and inserts n value-initialized value_types.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
explicit slist(size_type n)
: AllocHolder(allocator_type())
{ this->resize(n); }
@@ -267,6 +247,17 @@ class slist
//! throws or T's default or copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
+ slist(size_type n, const allocator_type &a)
+ : AllocHolder(a)
+ { this->resize(n); }
+
+ //! <b>Effects</b>: Constructs a list that will use a copy of allocator a
+ //! and inserts n copies of value.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type())
: AllocHolder(a)
{ this->insert_after(this->cbefore_begin(), n, x); }
@@ -307,13 +298,13 @@ class slist
: AllocHolder(x)
{ this->insert_after(this->cbefore_begin(), x.begin(), x.end()); }
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
slist(BOOST_RV_REF(slist) x)
- : AllocHolder(boost::move(static_cast<AllocHolder&>(x)))
+ : AllocHolder(BOOST_MOVE_BASE(AllocHolder, x))
{}
//! <b>Effects</b>: Copy constructs a list using the specified allocator.
@@ -340,7 +331,7 @@ class slist
this->icont().swap(x.icont());
}
else{
- this->insert_after(this->cbefore_begin(), x.begin(), x.end());
+ this->insert_after(this->cbefore_begin(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
}
}
@@ -350,7 +341,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements.
- ~slist() BOOST_CONTAINER_NOEXCEPT
+ ~slist() BOOST_NOEXCEPT_OR_NOTHROW
{} //AllocHolder clears the slist
//! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -389,7 +380,8 @@ class slist
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
slist& operator= (BOOST_RV_REF(slist) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+ || allocator_traits_type::is_always_equal::value)
{
BOOST_ASSERT(this != &x);
NodeAlloc &this_alloc = this->node_alloc();
@@ -489,7 +481,7 @@ class slist
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return allocator_type(this->node_alloc()); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -499,7 +491,7 @@ class slist
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -509,7 +501,7 @@ class slist
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->node_alloc(); }
//////////////////////////////////////////////
@@ -525,7 +517,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator before_begin() BOOST_CONTAINER_NOEXCEPT
+ iterator before_begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(end()); }
//! <b>Effects</b>: Returns a non-dereferenceable const_iterator
@@ -535,7 +527,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator before_begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator before_begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cbefore_begin(); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
@@ -543,7 +535,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -551,7 +543,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cbegin(); }
//! <b>Effects</b>: Returns an iterator to the end of the list.
@@ -559,7 +551,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -567,7 +559,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cend(); }
//! <b>Effects</b>: Returns a non-dereferenceable const_iterator
@@ -577,7 +569,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbefore_begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbefore_begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(end()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
@@ -585,7 +577,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->non_const_icont().begin()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -593,7 +585,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->non_const_icont().end()); }
//! <b>Returns</b>: The iterator to the element before i in the sequence.
@@ -605,7 +597,7 @@ class slist
//! <b>Complexity</b>: Linear to the number of elements before i.
//!
//! <b>Note</b>: Non-standard extension.
- iterator previous(iterator p) BOOST_CONTAINER_NOEXCEPT
+ iterator previous(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().previous(p.get())); }
//! <b>Returns</b>: The const_iterator to the element before i in the sequence.
@@ -713,7 +705,7 @@ class slist
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the front of the list
@@ -723,7 +715,7 @@ class slist
//!
//! <b>Complexity</b>: Amortized constant time.
template <class... Args>
- void emplace_front(Args&&... args)
+ void emplace_front(BOOST_FWD_REF(Args)... args)
{ this->emplace_after(this->cbefore_begin(), boost::forward<Args>(args)...); }
//! <b>Effects</b>: Inserts an object of type T constructed with
@@ -734,35 +726,30 @@ class slist
//!
//! <b>Complexity</b>: Constant
template <class... Args>
- iterator emplace_after(const_iterator prev, Args&&... args)
+ iterator emplace_after(const_iterator prev, BOOST_FWD_REF(Args)... args)
{
NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_after(prev.get(), *pnode));
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- this->emplace(this->cbegin() \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace_after(const_iterator prev \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- NodePtr pnode (AllocHolder::create_node \
- (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
- return iterator(this->icont().insert_after(prev.get(), *pnode)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ void emplace_front(BOOST_MOVE_UREF##N)\
+ { this->emplace_after(this->cbefore_begin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace_after(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
+ return iterator(this->icont().insert_after(p.get(), *pnode));\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the beginning of the list.
@@ -774,7 +761,7 @@ class slist
void push_front(const T &x);
//! <b>Effects</b>: Constructs a new element in the beginning of the list
- //! and moves the resources of mx to this new element.
+ //! and moves the resources of x to this new element.
//!
//! <b>Throws</b>: If memory allocation throws.
//!
@@ -856,7 +843,7 @@ class slist
, typename container_detail::enable_if_c
< !container_detail::is_convertible<InpIt, size_type>::value
&& (container_detail::is_input_iterator<InpIt>::value
- || container_detail::is_same<alloc_version, allocator_v1>::value
+ || container_detail::is_same<alloc_version, version_1>::value
)
>::type * = 0
#endif
@@ -894,14 +881,14 @@ class slist
, 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_v1>::value
+ || container_detail::is_same<alloc_version, version_1>::value
)
>::type * = 0
)
{
//Optimized allocation and construction
insertion_functor func(this->icont(), prev.get());
- this->allocate_many_and_construct(first, std::distance(first, last), func);
+ this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
return iterator(func.inserted_first());
}
#endif
@@ -952,6 +939,8 @@ class slist
//!
//! <b>Complexity</b>: Linear to the number of elements on *this and x.
void swap(slist& x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
+ || allocator_traits_type::is_always_equal::value)
{ AllocHolder::swap(x); }
//! <b>Effects</b>: Erases all the elements of the list.
@@ -981,7 +970,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_p, slist& x) BOOST_CONTAINER_NOEXCEPT
+ void splice_after(const_iterator prev_p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this != &x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
@@ -1001,7 +990,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x) BOOST_CONTAINER_NOEXCEPT
+ void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(prev_p, static_cast<slist&>(x)); }
//! <b>Requires</b>: prev_p must be a valid iterator of this.
@@ -1018,7 +1007,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_p, slist& x, const_iterator prev) BOOST_CONTAINER_NOEXCEPT
+ void splice_after(const_iterator prev_p, slist& x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice_after(prev_p.get(), x.icont(), prev.get());
@@ -1038,7 +1027,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, const_iterator prev) BOOST_CONTAINER_NOEXCEPT
+ void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x, const_iterator prev) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(prev_p, static_cast<slist&>(x), prev); }
//! <b>Requires</b>: prev_p must be a valid iterator of this.
@@ -1056,7 +1045,7 @@ class slist
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_p, slist& x,
- const_iterator before_first, const_iterator before_last) BOOST_CONTAINER_NOEXCEPT
+ const_iterator before_first, const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice_after
@@ -1078,13 +1067,13 @@ class slist
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x,
- const_iterator before_first, const_iterator before_last) BOOST_CONTAINER_NOEXCEPT
+ const_iterator before_first, const_iterator before_last) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(prev_p, static_cast<slist&>(x), before_first, before_last); }
//! <b>Requires</b>: prev_p must be a valid iterator of this.
//! before_first and before_last must be valid iterators of x.
//! prev_p must not be contained in [before_first, before_last) range.
- //! n == std::distance(before_first, before_last).
+ //! n == distance(before_first, before_last).
//! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
@@ -1098,7 +1087,7 @@ class slist
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_p, slist& x,
const_iterator before_first, const_iterator before_last,
- size_type n) BOOST_CONTAINER_NOEXCEPT
+ size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice_after
@@ -1108,7 +1097,7 @@ class slist
//! <b>Requires</b>: prev_p must be a valid iterator of this.
//! before_first and before_last must be valid iterators of x.
//! prev_p must not be contained in [before_first, before_last) range.
- //! n == std::distance(before_first, before_last).
+ //! n == distance(before_first, before_last).
//! this' allocator and x's allocator shall compare equal.
//!
//! <b>Effects</b>: Transfers the range [before_first + 1, before_last + 1)
@@ -1122,7 +1111,7 @@ class slist
//! list. Iterators of this list and all the references are not invalidated.
void splice_after(const_iterator prev_p, BOOST_RV_REF(slist) x,
const_iterator before_first, const_iterator before_last,
- size_type n) BOOST_CONTAINER_NOEXCEPT
+ size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(prev_p, static_cast<slist&>(x), before_first, before_last, n); }
//! <b>Effects</b>: Removes all the elements that compare equal to value.
@@ -1134,7 +1123,7 @@ class slist
//! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid.
void remove(const T& value)
- { this->remove_if(equal_to_value(value)); }
+ { this->remove_if(equal_to_value_type(value)); }
//! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied.
@@ -1148,8 +1137,8 @@ class slist
template <class Pred>
void remove_if(Pred pred)
{
- typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
+ typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
+ this->icont().remove_and_dispose_if(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
@@ -1176,8 +1165,8 @@ class slist
template <class Pred>
void unique(Pred pred)
{
- typedef ValueCompareToNodeCompare<Pred> Predicate;
- this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc()));
+ typedef value_to_node_compare<Node, Pred> value_to_node_compare_type;
+ this->icont().unique_and_dispose(value_to_node_compare_type(pred), Destroyer(this->node_alloc()));
}
//! <b>Requires</b>: The lists x and *this must be distinct.
@@ -1225,9 +1214,9 @@ class slist
template <class StrictWeakOrdering>
void merge(slist& x, StrictWeakOrdering comp)
{
+ typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
- this->icont().merge(x.icont(),
- ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ this->icont().merge(x.icont(), value_to_node_compare_type(comp));
}
//! <b>Requires</b>: p must be a comparison function that induces a strict weak
@@ -1272,10 +1261,11 @@ class slist
template <class StrictWeakOrdering>
void sort(StrictWeakOrdering comp)
{
+ typedef value_to_node_compare<Node, StrictWeakOrdering> value_to_node_compare_type;
// nothing if the slist has length 0 or 1.
if (this->size() < 2)
return;
- this->icont().sort(ValueCompareToNodeCompare<StrictWeakOrdering>(comp));
+ this->icont().sort(value_to_node_compare_type(comp));
}
//! <b>Effects</b>: Reverses the order of elements in the list.
@@ -1285,7 +1275,7 @@ class slist
//! <b>Complexity</b>: This function is linear time.
//!
//! <b>Note</b>: Iterators and references are not invalidated
- void reverse() BOOST_CONTAINER_NOEXCEPT
+ void reverse() BOOST_NOEXCEPT_OR_NOTHROW
{ this->icont().reverse(); }
//////////////////////////////////////////////
@@ -1294,7 +1284,7 @@ class slist
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... before p
@@ -1304,24 +1294,22 @@ class slist
//!
//! <b>Complexity</b>: Linear to the elements before p
template <class... Args>
- iterator emplace(const_iterator p, Args&&... args)
+ iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
{ return this->emplace_after(this->previous(p), boost::forward<Args>(args)...); }
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace (const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- return this->emplace_after \
- (this->previous(p) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #define BOOST_CONTAINER_SLIST_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ return this->emplace_after(this->previous(p) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SLIST_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_SLIST_EMPLACE_CODE
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Requires</b>: p must be a valid iterator of *this.
@@ -1337,7 +1325,7 @@ class slist
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
- //! <b>Effects</b>: Insert a new element before p with mx's resources.
+ //! <b>Effects</b>: Insert a new element before p with x's resources.
//!
//! <b>Returns</b>: an iterator to the inserted element.
//!
@@ -1374,7 +1362,7 @@ class slist
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws.
//!
- //! <b>Complexity</b>: Linear to std::distance [first, last) plus
+ //! <b>Complexity</b>: Linear to distance [first, last) plus
//! linear to the elements before p.
template <class InIter>
iterator insert(const_iterator p, InIter first, InIter last)
@@ -1409,7 +1397,7 @@ class slist
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements before p.
- iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->erase_after(previous(p))); }
//! <b>Requires</b>: first and last must be valid iterator to elements in *this.
@@ -1420,7 +1408,7 @@ class slist
//!
//! <b>Complexity</b>: Linear to the distance between first and last plus
//! linear to the elements before first.
- iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->erase_after(previous(first), last)); }
//! <b>Requires</b>: p must point to an element contained
@@ -1435,7 +1423,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, slist& x) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(this->previous(p), x); }
//! <b>Requires</b>: p must point to an element contained
@@ -1450,7 +1438,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
//! this list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, BOOST_RV_REF(slist) x) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice(p, static_cast<slist&>(x)); }
//! <b>Requires</b>: p must point to an element contained
@@ -1467,7 +1455,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, slist& x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(this->previous(p), x, this->previous(i)); }
//! <b>Requires</b>: p must point to an element contained
@@ -1484,7 +1472,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice(p, static_cast<slist&>(x), i); }
//! <b>Requires</b>: p must point to an element contained
@@ -1501,7 +1489,7 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, slist& x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice_after(this->previous(p), x, this->previous(first), this->previous(last)); }
//! <b>Requires</b>: p must point to an element contained
@@ -1518,28 +1506,14 @@ class slist
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
- void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{ this->splice(p, static_cast<slist&>(x), first, last); }
//! <b>Effects</b>: Returns true if x and y are equal
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator==(const slist& x, const slist& y)
- {
- if(x.size() != y.size()){
- return false;
- }
- typedef typename slist<T,Allocator>::const_iterator const_iterator;
- const_iterator end1 = x.end();
-
- const_iterator i1 = x.begin();
- const_iterator i2 = y.begin();
- while (i1 != end1 && *i1 == *i2){
- ++i1;
- ++i2;
- }
- return i1 == end1;
- }
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
@@ -1551,7 +1525,7 @@ class slist
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator<(const slist& x, const slist& y)
- { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+ { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! <b>Effects</b>: Returns true if x is greater than y
//!
@@ -1672,8 +1646,11 @@ namespace boost {
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::slist<T, Allocator> >
- : public ::boost::has_trivial_destructor_after_move<Allocator>
-{};
+{
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
namespace container {
@@ -1686,9 +1663,13 @@ namespace container {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
-//Ummm, I don't like to define things in namespace std, but
-//there is no other way
-namespace std {
+#if defined(__clang__) && defined(_LIBCPP_VERSION)
+ #define BOOST_CONTAINER_CLANG_INLINE_STD_NS
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wc++11-extensions"
+#endif
+
+BOOST_CONTAINER_STD_NS_BEG
template <class T, class Allocator>
class insert_iterator<boost::container::slist<T, Allocator> >
@@ -1721,7 +1702,12 @@ class insert_iterator<boost::container::slist<T, Allocator> >
insert_iterator<Container>& operator++(int){ return *this; }
};
-} //namespace std;
+BOOST_CONTAINER_STD_NS_END
+
+#ifdef BOOST_CONTAINER_CLANG_INLINE_STD_NS
+ #pragma GCC diagnostic pop
+ #undef BOOST_CONTAINER_CLANG_INLINE_STD_NS
+#endif //BOOST_CONTAINER_CLANG_INLINE_STD_NS
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
diff --git a/boost/container/small_vector.hpp b/boost/container/small_vector.hpp
new file mode 100644
index 0000000000..7ef0c238a3
--- /dev/null
+++ b/boost/container/small_vector.hpp
@@ -0,0 +1,565 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015. 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_CONTAINER_SMALL_VECTOR_HPP
+#define BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/container_fwd.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/container/allocator_traits.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+// container/detail
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/version_type.hpp>
+
+//move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/iterator.hpp>
+
+//move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+
+//std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list> //for std::initializer_list
+#endif
+
+namespace boost {
+namespace container {
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+template <class T, class Allocator = new_allocator<T> >
+class small_vector_base;
+
+#endif
+
+//! A non-standard allocator used to implement `small_vector`.
+//! Users should never use it directly. It is described here
+//! for documentation purposes.
+//!
+//! This allocator inherits from a standard-conforming allocator
+//! and forwards member functiond to the standard allocator except
+//! when internal storage is being used as memory source.
+//!
+//! This allocator is a "partially_propagable" allocator and
+//! defines `is_partially_propagable` as true_type.
+//!
+//! A partially propagable allocator means that not all storage
+//! allocatod by an instance of `small_vector_allocator` can be
+//! deallocated by another instance of this type, even is both
+//! instances compare equal or an instance is propagated to another
+//! one using the copy/move constructor or assignment. The storage that
+//! can never be propagated is identified by `storage_is_unpropagable(p)`.
+//!
+//! `boost::container::vector` supports partially propagable allocators
+//! fallbacking to deep copy/swap/move operations when internal storage
+//! is being used to store vector elements.
+//!
+//! `small_vector_allocator` assumes that will be instantiated as
+//! `boost::container::vector< T, small_vector_allocator<Allocator> >`
+//! and internal storage can be obtained downcasting that vector
+//! to `small_vector_base<T>`.
+template<class Allocator>
+class small_vector_allocator
+ : public Allocator
+{
+ typedef unsigned int allocation_type;
+ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ private:
+
+ BOOST_COPYABLE_AND_MOVABLE(small_vector_allocator)
+
+ const Allocator &as_base() const
+ { return static_cast<const Allocator&>(*this); }
+
+ Allocator &as_base()
+ { return static_cast<Allocator&>(*this); }
+
+ #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+ public:
+ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ typedef allocator_traits<Allocator> allocator_traits_type;
+ #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+ typedef typename allocator_traits<Allocator>::value_type value_type;
+ typedef typename allocator_traits<Allocator>::pointer pointer;
+ typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
+ typedef typename allocator_traits<Allocator>::reference reference;
+ typedef typename allocator_traits<Allocator>::const_reference const_reference;
+ typedef typename allocator_traits<Allocator>::size_type size_type;
+ typedef typename allocator_traits<Allocator>::difference_type difference_type;
+ typedef typename allocator_traits<Allocator>::void_pointer void_pointer;
+ typedef typename allocator_traits<Allocator>::const_void_pointer const_void_pointer;
+
+ typedef typename allocator_traits<Allocator>::propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
+ typedef typename allocator_traits<Allocator>::propagate_on_container_move_assignment propagate_on_container_move_assignment;
+ typedef typename allocator_traits<Allocator>::propagate_on_container_swap propagate_on_container_swap;
+ //! An integral constant with member `::value == false`
+ typedef BOOST_CONTAINER_IMPDEF(container_detail::bool_<false>) is_always_equal;
+ //! An integral constant with member `::value == true`
+ typedef BOOST_CONTAINER_IMPDEF(container_detail::bool_<true>) is_partially_propagable;
+
+ BOOST_CONTAINER_DOCIGN(typedef container_detail::version_type<small_vector_allocator BOOST_CONTAINER_I 1> version;)
+
+ //!Obtains an small_vector_allocator that allocates
+ //!objects of type T2
+ template<class T2>
+ struct rebind
+ {
+ typedef typename allocator_traits<Allocator>::template rebind_alloc<T2>::type other;
+ };
+
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //!Constructor from arbitrary arguments
+ template<class ...Args>
+ explicit small_vector_allocator(BOOST_FWD_REF(Args) ...args)
+ : Allocator(::boost::forward<Args>(args)...)
+ {}
+ #else
+ #define BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ explicit small_vector_allocator(BOOST_MOVE_UREF##N)\
+ : Allocator(BOOST_MOVE_FWD##N)\
+ {}\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE)
+ #undef BOOST_CONTAINER_SMALL_VECTOR_ALLOCATOR_CTOR_CODE
+ #endif
+
+ //!Constructor from other small_vector_allocator.
+ //!Never throws
+ small_vector_allocator(const small_vector_allocator &other) BOOST_NOEXCEPT_OR_NOTHROW
+ : Allocator(other.as_base())
+ {}
+
+ //!Move constructor from small_vector_allocator.
+ //!Never throws
+ small_vector_allocator(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
+ : Allocator(::boost::move(other.as_base()))
+ {}
+
+ //!Constructor from related small_vector_allocator.
+ //!Never throws
+ template<class OtherAllocator>
+ small_vector_allocator(const small_vector_allocator<OtherAllocator> &other) BOOST_NOEXCEPT_OR_NOTHROW
+ : Allocator(other.as_base())
+ {}
+
+ //!Move constructor from related small_vector_allocator.
+ //!Never throws
+ template<class OtherAllocator>
+ small_vector_allocator(BOOST_RV_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
+ : Allocator(::boost::move(other.as_base()))
+ {}
+
+ //!Assignment from other small_vector_allocator.
+ //!Never throws
+ small_vector_allocator & operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
+ { return static_cast<small_vector_allocator&>(this->Allocator::operator=(other.as_base())); }
+
+ //!Move constructor from other small_vector_allocator.
+ //!Never throws
+ small_vector_allocator & operator=(BOOST_RV_REF(small_vector_allocator) other) BOOST_NOEXCEPT_OR_NOTHROW
+ { return static_cast<small_vector_allocator&>(this->Allocator::operator=(::boost::move(other.as_base()))); }
+
+ //!Assignment from related small_vector_allocator.
+ //!Never throws
+ template<class OtherAllocator>
+ small_vector_allocator & operator=(BOOST_COPY_ASSIGN_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
+ { return static_cast<small_vector_allocator&>(this->Allocator::operator=(other.as_base())); }
+
+ //!Move assignment from related small_vector_allocator.
+ //!Never throws
+ template<class OtherAllocator>
+ small_vector_allocator & operator=(BOOST_RV_REF(small_vector_allocator<OtherAllocator>) other) BOOST_NOEXCEPT_OR_NOTHROW
+ { return static_cast<small_vector_allocator&>(this->Allocator::operator=(::boost::move(other.as_base()))); }
+
+ //!Allocates storage from the standard-conforming allocator
+ pointer allocate(size_type count, const_void_pointer hint = const_void_pointer())
+ { return allocator_traits_type::allocate(this->as_base(), count, hint); }
+
+ //!Deallocates previously allocated memory.
+ //!Never throws
+ void deallocate(pointer ptr, size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ if(!this->is_internal_storage(ptr))
+ allocator_traits_type::deallocate(this->as_base(), ptr, n);
+ }
+
+ //!Returns the maximum number of elements that could be allocated.
+ //!Never throws
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
+ { return allocator_traits_type::max_size(this->as_base()); }
+
+ small_vector_allocator select_on_container_copy_construction() const
+ { return small_vector_allocator(allocator_traits_type::select_on_container_copy_construction(this->as_base())); }
+
+ bool storage_is_unpropagable(pointer p) const
+ { return this->is_internal_storage(p) || allocator_traits_type::storage_is_unpropagable(this->as_base(), p); }
+
+ //!Swaps two allocators, does nothing
+ //!because this small_vector_allocator is stateless
+ friend void swap(small_vector_allocator &l, small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
+ { boost::adl_move_swap(l.as_base(), r.as_base()); }
+
+ //!An small_vector_allocator always compares to true, as memory allocated with one
+ //!instance can be deallocated by another instance (except for unpropagable storage)
+ friend bool operator==(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
+ { return allocator_traits_type::equal(l.as_base(), r.as_base()); }
+
+ //!An small_vector_allocator always compares to false, as memory allocated with one
+ //!instance can be deallocated by another instance
+ friend bool operator!=(const small_vector_allocator &l, const small_vector_allocator &r) BOOST_NOEXCEPT_OR_NOTHROW
+ { return !(l == r); }
+
+ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ /*
+ //!An advanced function that offers in-place expansion shrink to fit and new allocation
+ //!capabilities. Memory allocated with this function can only be deallocated with deallocate()
+ //!or deallocate_many().
+ //!This function is available only with Version == 2
+ pointer allocation_command(allocation_type command,
+ size_type limit_size,
+ size_type &prefer_in_recvd_out_size,
+ pointer &reuse)
+ { return allocator_traits_type::allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
+
+ //!Returns maximum the number of objects the previously allocated memory
+ //!pointed by p can hold.
+ //!Memory must not have been allocated with
+ //!allocate_one or allocate_individual.
+ //!This function is available only with Version == 2
+ size_type size(pointer p) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return allocator_traits_type::size(p); }
+ */
+ private:
+ /*
+ //!Allocates just one object. Memory allocated with this function
+ //!must be deallocated only with deallocate_one().
+ //!Throws bad_alloc if there is no enough memory
+ //!This function is available only with Version == 2
+ using Allocator::allocate_one;
+ using Allocator::allocate_individual;
+ using Allocator::deallocate_one;
+ using Allocator::deallocate_individual;
+ using Allocator::allocate_many;
+ using Allocator::deallocate_many;*/
+
+ bool is_internal_storage(pointer p) const
+ { return this->internal_storage() == p; }
+
+ pointer internal_storage() const
+ {
+ typedef typename Allocator::value_type value_type;
+ typedef container_detail::vector_alloc_holder< small_vector_allocator<Allocator> > vector_alloc_holder_t;
+ typedef vector<value_type, small_vector_allocator<Allocator> > vector_base;
+ typedef small_vector_base<value_type, Allocator> derived_type;
+ //
+ const vector_alloc_holder_t &v_holder = static_cast<const vector_alloc_holder_t &>(*this);
+ const vector_base &v_base = reinterpret_cast<const vector_base &>(v_holder);
+ const derived_type &d_base = static_cast<const derived_type &>(v_base);
+ return d_base.internal_storage();
+ }
+ #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+//! This class consists of common code from all small_vector<T, N> types that don't depend on the
+//! "N" template parameter. This class is non-copyable and non-destructible, so this class tipically
+//! used as reference argument to functions that read or write small vectors. Since `small_vector<T, N>`
+//! derives from `small_vector_base<T>`, the conversion to `small_vector_base` is implicit:
+//! <code>
+//!
+//! //Clients can pass any small_vector<Foo, N>.
+//! void read_any_small_vector_of_foo(const small_vector_base<Foo> &in_parameter);
+//! void modify_any_small_vector_of_foo(small_vector_base<Foo> &out_parameter);
+//!
+//! void some_function()
+//! {
+//! small_vector<Foo, 8> myvector;
+//! read_any_small_vector_of_foo(myvector); // Reads myvector
+//! modify_any_small_vector_of_foo(myvector); // Modifies myvector
+//! }
+//! </code>
+//!
+//! All `boost::container:vector` member functions are inherited. See `vector` documentation for details.
+//!
+template <class T, class SecondaryAllocator>
+class small_vector_base
+ : public vector<T, small_vector_allocator<SecondaryAllocator> >
+{
+ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ typedef typename allocator_traits<SecondaryAllocator>::pointer pointer;
+
+ BOOST_COPYABLE_AND_MOVABLE(small_vector_base)
+
+ friend class small_vector_allocator<SecondaryAllocator>;
+
+ pointer internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ return boost::intrusive::pointer_traits<pointer>::pointer_to
+ (*const_cast<T*>(static_cast<const T*>(static_cast<const void*>(&m_storage_start))));
+ }
+
+ typedef vector<T, small_vector_allocator<SecondaryAllocator> > base_type;
+ base_type &as_base() { return static_cast<base_type&>(*this); }
+ const base_type &as_base() const { return static_cast<const base_type&>(*this); }
+
+ public:
+ typedef typename container_detail::aligned_storage
+ <sizeof(T), container_detail::alignment_of<T>::value>::type storage_type;
+ typedef small_vector_allocator<SecondaryAllocator> allocator_type;
+
+ protected:
+ typedef typename base_type::initial_capacity_t initial_capacity_t;
+
+ explicit small_vector_base(initial_capacity_t, std::size_t initial_capacity)
+ : base_type(initial_capacity_t(), this->internal_storage(), initial_capacity)
+ {}
+
+ template<class AllocFwd>
+ explicit small_vector_base(initial_capacity_t, std::size_t capacity, BOOST_FWD_REF(AllocFwd) a)
+ : base_type(initial_capacity_t(), this->internal_storage(), capacity, ::boost::forward<AllocFwd>(a))
+ {}
+
+ ~small_vector_base(){}
+
+ using base_type::is_propagable_from;
+ using base_type::steal_resources;
+
+ private:
+ //The only member
+ storage_type m_storage_start;
+
+ #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+ public:
+ small_vector_base& operator=(BOOST_COPY_ASSIGN_REF(small_vector_base) other)
+ { return static_cast<small_vector_base&>(this->base_type::operator=(static_cast<base_type const&>(other))); }
+
+ small_vector_base& operator=(BOOST_RV_REF(small_vector_base) other)
+ { return static_cast<small_vector_base&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
+
+ void swap(small_vector_base &other)
+ { return this->base_type::swap(other); }
+};
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+/////////////////////////////////////////////////////
+//
+// small_vector_storage_calculator
+//
+/////////////////////////////////////////////////////
+template<std::size_t Needed, std::size_t Hdr, std::size_t SSize, bool NeedsZero = (0u == Needed || Needed <= Hdr)>
+struct small_vector_storage_calculator_helper
+{
+ static const std::size_t value = (Needed - Hdr - 1u)/SSize + 1u;
+};
+
+template<std::size_t Needed, std::size_t Hdr, std::size_t SSize>
+struct small_vector_storage_calculator_helper<Needed, Hdr, SSize, true>
+{
+ static const std::size_t value = 0u;
+};
+
+template<class Storage, class Allocator, class T, std::size_t N>
+struct small_vector_storage_calculator
+{
+ typedef small_vector_base<T, Allocator> svh_type;
+ typedef vector<T, small_vector_allocator<Allocator> > svhb_type;
+ static const std::size_t s_align = container_detail::alignment_of<Storage>::value;
+ static const std::size_t s_size = sizeof(Storage);
+ static const std::size_t svh_sizeof = sizeof(svh_type);
+ static const std::size_t svhb_sizeof = sizeof(svhb_type);
+ static const std::size_t s_start = ((svhb_sizeof-1)/s_align+1)*s_align;
+ static const std::size_t header_bytes = svh_sizeof-s_start;
+ static const std::size_t needed_bytes = sizeof(T)*N;
+ static const std::size_t needed_extra_storages =
+ small_vector_storage_calculator_helper<needed_bytes, header_bytes, s_size>::value;
+};
+
+/////////////////////////////////////////////////////
+//
+// small_vector_storage_definer
+//
+/////////////////////////////////////////////////////
+template<class Storage, std::size_t N>
+struct small_vector_storage
+{
+ Storage m_rest_of_storage[N];
+};
+
+template<class Storage>
+struct small_vector_storage<Storage, 0>
+{};
+
+template<class Allocator, std::size_t N>
+struct small_vector_storage_definer
+{
+ typedef typename Allocator::value_type value_type;
+ typedef typename small_vector_base<value_type, Allocator>::storage_type storage_type;
+ static const std::size_t needed_extra_storages =
+ small_vector_storage_calculator<storage_type, Allocator, value_type, N>::needed_extra_storages;
+ typedef small_vector_storage<storage_type, needed_extra_storages> type;
+};
+
+#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+//! small_vector a vector-like container optimized for the case when it contains few elements.
+//! It contains some preallocated elements in-place, which allows it to avoid the use of dynamic storage allocation
+//! when the actual number of elements is below that preallocated threshold.
+//!
+//! `small_vector<T, N, Allocator>` is convertible to `small_vector_base<T, Allocator>` that is independent
+//! from the preallocated element capacity, so client code does not need to be templated on that N argument.
+//!
+//! All `boost::container::vector` member functions are inherited. See `vector` documentation for details.
+//!
+//! \tparam T The type of object that is stored in the small_vector
+//! \tparam N The number of preallocated elements stored inside small_vector. It shall be less than Allocator::max_size();
+//! \tparam Allocator The allocator used for memory management when the number of elements exceeds N.
+template <class T, std::size_t N, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>) >
+class small_vector : public small_vector_base<T, Allocator>
+ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ , private small_vector_storage_definer<Allocator, N>::type
+ #endif
+{
+ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ typedef small_vector_base<T, Allocator> base_type;
+ typedef typename small_vector_storage_definer<Allocator, N>::type remaining_storage_holder;
+
+ BOOST_COPYABLE_AND_MOVABLE(small_vector)
+
+ typedef typename base_type::initial_capacity_t initial_capacity_t;
+ typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type;
+
+ public:
+ typedef small_vector_storage_calculator< typename small_vector_base<T, Allocator>
+ ::storage_type, Allocator, T, N> storage_test;
+
+ static const std::size_t needed_extra_storages = storage_test::needed_extra_storages;
+ static const std::size_t needed_bytes = storage_test::needed_bytes;
+ static const std::size_t header_bytes = storage_test::header_bytes;
+ static const std::size_t s_start = storage_test::s_start;
+
+ typedef typename base_type::allocator_type allocator_type;
+ typedef typename base_type::size_type size_type;
+ typedef typename base_type::value_type value_type;
+
+ static std::size_t internal_capacity()
+ { return (sizeof(small_vector) - storage_test::s_start)/sizeof(T); }
+
+ #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+ public:
+ small_vector()
+ : base_type(initial_capacity_t(), internal_capacity())
+ {}
+
+ explicit small_vector(size_type n)
+ : base_type(initial_capacity_t(), internal_capacity())
+ { this->resize(n); }
+
+ explicit small_vector(const allocator_type &a)
+ : base_type(initial_capacity_t(), internal_capacity(), a)
+ {}
+
+ small_vector(size_type n, const allocator_type &a)
+ : base_type(initial_capacity_t(), internal_capacity(), a)
+ { this->resize(n); }
+
+ small_vector(const small_vector &other)
+ : base_type( initial_capacity_t(), internal_capacity()
+ , allocator_traits_type::select_on_container_copy_construction(other.get_stored_allocator()))
+ { this->assign(other.cbegin(), other.cend()); }
+
+ small_vector(const small_vector &other, const allocator_type &a)
+ : base_type(initial_capacity_t(), internal_capacity(), a)
+ { this->assign(other.cbegin(), other.cend()); }
+
+ small_vector(BOOST_RV_REF(small_vector) other)
+ : base_type(initial_capacity_t(), internal_capacity(), ::boost::move(other.get_stored_allocator()))
+ { this->move_construct_impl(other, other.get_stored_allocator()); }
+
+ small_vector(BOOST_RV_REF(small_vector) other, const allocator_type &a)
+ : base_type(initial_capacity_t(), internal_capacity(), a)
+ { this->move_construct_impl(other, a); }
+
+ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ small_vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
+ : base_type(initial_capacity_t(), internal_capacity(), a)
+ {
+ this->assign(il.begin(), il.end());
+ }
+ #endif
+
+ small_vector& operator=(BOOST_COPY_ASSIGN_REF(small_vector) other)
+ { return static_cast<small_vector&>(this->base_type::operator=(static_cast<base_type const&>(other))); }
+
+ small_vector& operator=(BOOST_RV_REF(small_vector) other)
+ { return static_cast<small_vector&>(this->base_type::operator=(BOOST_MOVE_BASE(base_type, other))); }
+
+ void swap(small_vector &other)
+ { return this->base_type::swap(other); }
+
+ #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+ private:
+ void move_construct_impl(small_vector &x, const allocator_type &a)
+ {
+ if(base_type::is_propagable_from(x.get_stored_allocator(), x.data(), a, true)){
+ this->steal_resources(x);
+ }
+ else{
+ this->assign( boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.begin()))
+ , boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.end ()))
+ );
+ }
+ }
+ #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+};
+
+}}
+
+#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+/*
+namespace boost {
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template <class T, class Allocator>
+struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
+{
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
+
+}
+*/
+#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif // #ifndef BOOST_CONTAINER_CONTAINER_SMALL_VECTOR_HPP
diff --git a/boost/container/stable_vector.hpp b/boost/container/stable_vector.hpp
index b8b415758e..76c9e9f07b 100644
--- a/boost/container/stable_vector.hpp
+++ b/boost/container/stable_vector.hpp
@@ -19,48 +19,59 @@
#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
#define BOOST_CONTAINER_STABLE_VECTOR_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
+
+// container
+#include <boost/container/allocator_traits.hpp>
#include <boost/container/container_fwd.hpp>
-#include <boost/assert.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/addressof.hpp>
+#include <boost/container/detail/algorithm.hpp> //algo_equal(), algo_lexicographical_compare
+#include <boost/container/detail/alloc_helpers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
-#include <boost/container/detail/utilities.hpp>
+#include <boost/container/detail/construct_in_place.hpp>
+#include <boost/container/detail/iterator.hpp>
#include <boost/container/detail/iterators.hpp>
-#include <boost/container/detail/algorithms.hpp>
-#include <boost/container/allocator_traits.hpp>
-#include <boost/container/throw_exception.hpp>
+#include <boost/container/detail/placement_new.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+// intrusive
#include <boost/intrusive/pointer_traits.hpp>
-#include <boost/core/no_exceptions_support.hpp>
-#include <boost/aligned_storage.hpp>
+// intrusive/detail
+#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
+// move
#include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp>
+#include <boost/move/adl_move_swap.hpp>
+// move/detail
#include <boost/move/detail/move_helpers.hpp>
-#include <boost/container/detail/placement_new.hpp>
-#include <algorithm>
-
-
-#include <memory>
+// other
+#include <boost/assert.hpp>
+#include <boost/core/no_exceptions_support.hpp>
+// std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
-
-#include <boost/container/vector.hpp>
-
-//#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
-
+ #include <boost/container/vector.hpp>
+ //#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
namespace container {
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
-#include <initializer_list>
-#endif
-
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace stable_vector_detail{
@@ -261,103 +272,103 @@ class stable_vector_iterator
public:
- explicit stable_vector_iterator(node_base_ptr p) BOOST_CONTAINER_NOEXCEPT
+ explicit stable_vector_iterator(node_base_ptr p) BOOST_NOEXCEPT_OR_NOTHROW
: m_pn(p)
{}
- stable_vector_iterator() BOOST_CONTAINER_NOEXCEPT
+ stable_vector_iterator() BOOST_NOEXCEPT_OR_NOTHROW
: m_pn() //Value initialization to achieve "null iterators" (N3644)
{}
- stable_vector_iterator(stable_vector_iterator<Pointer, false> const& other) BOOST_CONTAINER_NOEXCEPT
+ stable_vector_iterator(stable_vector_iterator<Pointer, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
: m_pn(other.node_pointer())
{}
- node_ptr node_pointer() const BOOST_CONTAINER_NOEXCEPT
+ node_ptr node_pointer() const BOOST_NOEXCEPT_OR_NOTHROW
{ return node_ptr_traits::static_cast_from(m_pn); }
public:
//Pointer like operators
- reference operator*() const BOOST_CONTAINER_NOEXCEPT
+ reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
{ return node_pointer()->value; }
- pointer operator->() const BOOST_CONTAINER_NOEXCEPT
+ pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
{ return ptr_traits::pointer_to(this->operator*()); }
//Increment / Decrement
- stable_vector_iterator& operator++() BOOST_CONTAINER_NOEXCEPT
+ stable_vector_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
{
node_base_ptr_ptr p(this->m_pn->up);
this->m_pn = *(++p);
return *this;
}
- stable_vector_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
+ stable_vector_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
{ stable_vector_iterator tmp(*this); ++*this; return stable_vector_iterator(tmp); }
- stable_vector_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
+ stable_vector_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
{
node_base_ptr_ptr p(this->m_pn->up);
this->m_pn = *(--p);
return *this;
}
- stable_vector_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
+ stable_vector_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
{ stable_vector_iterator tmp(*this); --*this; return stable_vector_iterator(tmp); }
- reference operator[](difference_type off) const BOOST_CONTAINER_NOEXCEPT
+ reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW
{ return node_ptr_traits::static_cast_from(this->m_pn->up[off])->value; }
- stable_vector_iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT
+ stable_vector_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
{
if(off) this->m_pn = this->m_pn->up[off];
return *this;
}
- friend stable_vector_iterator operator+(const stable_vector_iterator &left, difference_type off) BOOST_CONTAINER_NOEXCEPT
+ friend stable_vector_iterator operator+(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
{
stable_vector_iterator tmp(left);
tmp += off;
return tmp;
}
- friend stable_vector_iterator operator+(difference_type off, const stable_vector_iterator& right) BOOST_CONTAINER_NOEXCEPT
+ friend stable_vector_iterator operator+(difference_type off, const stable_vector_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
{
stable_vector_iterator tmp(right);
tmp += off;
return tmp;
}
- stable_vector_iterator& operator-=(difference_type off) BOOST_CONTAINER_NOEXCEPT
+ stable_vector_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
{ *this += -off; return *this; }
- friend stable_vector_iterator operator-(const stable_vector_iterator &left, difference_type off) BOOST_CONTAINER_NOEXCEPT
+ friend stable_vector_iterator operator-(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
{
stable_vector_iterator tmp(left);
tmp -= off;
return tmp;
}
- friend difference_type operator-(const stable_vector_iterator& left, const stable_vector_iterator& right) BOOST_CONTAINER_NOEXCEPT
+ friend difference_type operator-(const stable_vector_iterator& left, const stable_vector_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
{ return left.m_pn->up - right.m_pn->up; }
//Comparison operators
- friend bool operator== (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator== (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_pn == r.m_pn; }
- friend bool operator!= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator!= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_pn != r.m_pn; }
- friend bool operator< (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator< (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_pn->up < r.m_pn->up; }
- friend bool operator<= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator<= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_pn->up <= r.m_pn->up; }
- friend bool operator> (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator> (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_pn->up > r.m_pn->up; }
- friend bool operator>= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator>= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_pn->up >= r.m_pn->up; }
};
@@ -410,7 +421,7 @@ class stable_vector_iterator
//! \tparam T The type of object that is stored in the stable_vector
//! \tparam Allocator The allocator used for all internal memory management
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
-template <class T, class Allocator = std::allocator<T> >
+template <class T, class Allocator = new_allocator<T> >
#else
template <class T, class Allocator>
#endif
@@ -453,10 +464,6 @@ class stable_vector
typedef typename node_ptr_traits::reference node_reference;
typedef typename const_node_ptr_traits::reference const_node_reference;
- typedef ::boost::container::container_detail::
- integral_constant<unsigned, 1> allocator_v1;
- typedef ::boost::container::container_detail::
- integral_constant<unsigned, 2> allocator_v2;
typedef ::boost::container::container_detail::integral_constant
<unsigned, boost::container::container_detail::
version<Allocator>::value> alloc_version;
@@ -506,8 +513,8 @@ class stable_vector
typedef node_allocator_type stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
@@ -544,13 +551,13 @@ class stable_vector
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit stable_vector(const allocator_type& al) BOOST_CONTAINER_NOEXCEPT
+ explicit stable_vector(const allocator_type& al) BOOST_NOEXCEPT_OR_NOTHROW
: internal_data(al), index(al)
{
STABLE_VECTOR_CHECK_INVARIANT;
}
- //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+ //! <b>Effects</b>: Constructs a stable_vector
//! and inserts n value initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor
@@ -566,7 +573,7 @@ class stable_vector
cod.release();
}
- //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+ //! <b>Effects</b>: Constructs a stable_vector
//! and inserts n default initialized values.
//!
//! <b>Throws</b>: If allocator_type's default constructor
@@ -585,6 +592,40 @@ class stable_vector
}
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+ //! and inserts n value initialized values.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ explicit stable_vector(size_type n, const allocator_type &a)
+ : internal_data(), index(a)
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->resize(n);
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
+ //! and inserts n default initialized values.
+ //!
+ //! <b>Throws</b>: If allocator_type's default constructor
+ //! throws or T's default or copy constructor throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ stable_vector(size_type n, default_init_t, const allocator_type &a)
+ : internal_data(), index(a)
+ {
+ stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
+ this->resize(n, default_init);
+ STABLE_VECTOR_CHECK_INVARIANT;
+ cod.release();
+ }
+
+ //! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
//! and inserts n copies of value.
//!
//! <b>Throws</b>: If allocator_type's default constructor
@@ -652,7 +693,7 @@ class stable_vector
}
#endif
- //! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
+ //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
@@ -678,7 +719,7 @@ class stable_vector
}
//! <b>Effects</b>: Move constructor using the specified allocator.
- //! Moves mx's resources to *this.
+ //! Moves x's resources to *this.
//!
//! <b>Throws</b>: If allocator_type's copy constructor throws.
//!
@@ -687,11 +728,12 @@ class stable_vector
: internal_data(a), index(a)
{
if(this->priv_node_alloc() == x.priv_node_alloc()){
+ this->index.swap(x.index);
this->priv_swap_members(x);
}
else{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
- this->insert(this->cend(), x.begin(), x.end());
+ this->insert(this->cend(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -736,7 +778,7 @@ class stable_vector
return *this;
}
- //! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
+ //! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
//!
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
//! before the function.
@@ -748,7 +790,8 @@ class stable_vector
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+ || allocator_traits_type::is_always_equal::value)
{
//for move constructor, no aliasing (&x != this) is assummed.
BOOST_ASSERT(this != &x);
@@ -766,7 +809,7 @@ class stable_vector
//Move allocator if needed
container_detail::move_alloc(this_alloc, x_alloc, flag);
//Take resources
- this->index = boost::move(x.index);
+ this->index.swap(x.index);
this->priv_swap_members(x);
}
//Else do a one by one move
@@ -856,7 +899,7 @@ class stable_vector
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -866,7 +909,7 @@ class stable_vector
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_node_alloc(); }
//////////////////////////////////////////////
@@ -880,7 +923,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return (this->index.empty()) ? this->end(): iterator(node_ptr_traits::static_cast_from(this->index.front())); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
@@ -888,7 +931,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return (this->index.empty()) ? this->cend() : const_iterator(node_ptr_traits::static_cast_from(this->index.front())) ; }
//! <b>Effects</b>: Returns an iterator to the end of the stable_vector.
@@ -896,7 +939,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->priv_get_end_node()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
@@ -904,7 +947,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->priv_get_end_node()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -913,7 +956,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(this->end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -922,7 +965,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->end()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -931,7 +974,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(this->begin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -940,7 +983,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->begin()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the stable_vector.
@@ -948,7 +991,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->begin(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the stable_vector.
@@ -956,7 +999,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->end(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -965,7 +1008,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->rbegin(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -974,7 +1017,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend()const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crend()const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->rend(); }
//////////////////////////////////////////////
@@ -988,7 +1031,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->index.size() <= ExtraPointers; }
//! <b>Effects</b>: Returns the number of the elements contained in the stable_vector.
@@ -996,10 +1039,10 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{
const size_type index_size = this->index.size();
- return (index_size - ExtraPointers) & (std::size_t(0u) -std::size_t(index_size != 0));
+ return (index_size - ExtraPointers) & (size_type(0u) -size_type(index_size != 0));
}
//! <b>Effects</b>: Returns the largest possible size of the stable_vector.
@@ -1007,7 +1050,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->index.max_size() - ExtraPointers; }
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -1065,7 +1108,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+ size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
{
const size_type index_size = this->index.size();
BOOST_ASSERT(!index_size || index_size >= ExtraPointers);
@@ -1153,7 +1196,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference front() BOOST_CONTAINER_NOEXCEPT
+ reference front() BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<node_reference>(*this->index.front()).value; }
//! <b>Requires</b>: !empty()
@@ -1164,7 +1207,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference front() const BOOST_CONTAINER_NOEXCEPT
+ const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<const_node_reference>(*this->index.front()).value; }
//! <b>Requires</b>: !empty()
@@ -1175,7 +1218,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference back() BOOST_CONTAINER_NOEXCEPT
+ reference back() BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<node_reference>(*this->index[this->size()-1u]).value; }
//! <b>Requires</b>: !empty()
@@ -1186,7 +1229,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference back() const BOOST_CONTAINER_NOEXCEPT
+ const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<const_node_reference>(*this->index[this->size()-1u]).value; }
//! <b>Requires</b>: size() > n.
@@ -1197,7 +1240,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
+ reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(n < this->size());
return static_cast<node_reference>(*this->index[n]).value;
@@ -1211,12 +1254,73 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
+ const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(n < this->size());
return static_cast<const_node_reference>(*this->index[n]).value;
}
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns an iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->size() >= n);
+ return (this->index.empty()) ? this->end() : iterator(node_ptr_traits::static_cast_from(this->index[n]));
+ }
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns a const_iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->size() >= n);
+ return (this->index.empty()) ? this->cend() : iterator(node_ptr_traits::static_cast_from(this->index[n]));
+ }
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns an iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->priv_index_of(p.node_pointer()); }
+
+ //! <b>Requires</b>: begin() <= p <= end().
+ //!
+ //! <b>Effects</b>: Returns the index of the element pointed by p
+ //! and size() if p == end().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->priv_index_of(p.node_pointer()); }
+
//! <b>Requires</b>: size() > n.
//!
//! <b>Effects</b>: Returns a reference to the nth element
@@ -1255,7 +1359,7 @@ class stable_vector
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the end of the stable_vector.
@@ -1294,40 +1398,33 @@ class stable_vector
#else
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
- BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
- EmplaceFunctor; \
- typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
- EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
- BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
- BOOST_PP_RPAREN_IF(n); \
- this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator()); \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(const_iterator p \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
- BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >) \
- EmplaceFunctor; \
- typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; \
- EmplaceFunctor ef BOOST_PP_LPAREN_IF(n) \
- BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) \
- BOOST_PP_RPAREN_IF(n); \
- size_type pos_n = p - this->cbegin(); \
- this->insert(p, EmplaceIterator(ef), EmplaceIterator()); \
- return iterator(this->begin() + pos_n); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #define BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ void emplace_back(BOOST_MOVE_UREF##N)\
+ {\
+ typedef emplace_functor##N\
+ BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\
+ EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\
+ this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ typedef emplace_functor##N\
+ BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
+ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\
+ EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\
+ const size_type pos_n = p - this->cbegin();\
+ this->insert(p, EmplaceIterator(ef), EmplaceIterator());\
+ return this->begin() += pos_n;\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the end of the stable_vector.
@@ -1339,7 +1436,7 @@ class stable_vector
void push_back(const T &x);
//! <b>Effects</b>: Constructs a new element in the end of the stable_vector
- //! and moves the resources of mx to this new element.
+ //! and moves the resources of x to this new element.
//!
//! <b>Throws</b>: If memory allocation throws.
//!
@@ -1364,7 +1461,7 @@ class stable_vector
//! <b>Requires</b>: p must be a valid iterator of *this.
//!
- //! <b>Effects</b>: Insert a new element before p with mx's resources.
+ //! <b>Effects</b>: Insert a new element before p with x's resources.
//!
//! <b>Returns</b>: an iterator to the inserted element.
//!
@@ -1401,7 +1498,7 @@ class stable_vector
//!
//! <b>Returns</b>: an iterator to the first inserted element or p if first == last.
//!
- //! <b>Complexity</b>: Linear to std::distance [il.begin(), il.end()).
+ //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
iterator insert(const_iterator p, std::initializer_list<value_type> il)
{
STABLE_VECTOR_CHECK_INVARIANT;
@@ -1418,7 +1515,7 @@ class stable_vector
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws or T's copy constructor throws.
//!
- //! <b>Complexity</b>: Linear to std::distance [first, last).
+ //! <b>Complexity</b>: Linear to distance [first, last).
template <class InputIterator>
iterator insert(const_iterator p, InputIterator first, InputIterator last
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1446,7 +1543,7 @@ class stable_vector
>::type * = 0
)
{
- const size_type num_new = static_cast<size_type>(std::distance(first, last));
+ const size_type num_new = static_cast<size_type>(boost::container::iterator_distance(first, last));
const size_type idx = static_cast<size_type>(p - this->cbegin());
if(num_new){
//Fills the node pool and inserts num_new null pointers in idx.
@@ -1483,7 +1580,7 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant time.
- void pop_back() BOOST_CONTAINER_NOEXCEPT
+ void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
{ this->erase(--this->cend()); }
//! <b>Effects</b>: Erases the element at p.
@@ -1492,7 +1589,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to the elements between p and the
//! last element. Constant if p is the last element.
- iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{
STABLE_VECTOR_CHECK_INVARIANT;
const size_type d = p - this->cbegin();
@@ -1509,7 +1606,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to the distance between first and last
//! plus linear to the elements between p and the last element.
- iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{
STABLE_VECTOR_CHECK_INVARIANT;
const const_iterator cbeg(this->cbegin());
@@ -1541,6 +1638,8 @@ class stable_vector
//!
//! <b>Complexity</b>: Constant.
void swap(stable_vector & x)
+ BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
+ || allocator_traits_type::is_always_equal::value)
{
STABLE_VECTOR_CHECK_INVARIANT;
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
@@ -1555,14 +1654,14 @@ class stable_vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements in the stable_vector.
- void clear() BOOST_CONTAINER_NOEXCEPT
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ this->erase(this->cbegin(),this->cend()); }
//! <b>Effects</b>: Returns true if x and y are equal
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator==(const stable_vector& x, const stable_vector& y)
- { return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); }
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
@@ -1574,7 +1673,7 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator<(const stable_vector& x, const stable_vector& y)
- { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+ { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
//! <b>Effects</b>: Returns true if x is greater than y
//!
@@ -1603,6 +1702,14 @@ class stable_vector
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
+ size_type priv_index_of(node_ptr p) const
+ {
+ //Check range
+ BOOST_ASSERT(this->index.empty() || (this->index.data() <= p->up));
+ BOOST_ASSERT(this->index.empty() || p->up <= (this->index.data() + this->index.size()));
+ return this->index.empty() ? 0 : p->up - this->index.data();
+ }
+
class insert_rollback
{
public:
@@ -1844,7 +1951,7 @@ class stable_vector
void priv_swap_members(stable_vector &x)
{
- boost::container::swap_dispatch(this->internal_data.pool_size, x.internal_data.pool_size);
+ boost::adl_move_swap(this->internal_data.pool_size, x.internal_data.pool_size);
index_traits_type::readjust_end_node(this->index, this->internal_data.end_node);
index_traits_type::readjust_end_node(x.index, x.internal_data.end_node);
}
@@ -1929,20 +2036,23 @@ class stable_vector
#undef STABLE_VECTOR_CHECK_INVARIANT
-#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
-
-/*
+} //namespace container {
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::stable_vector<T, Allocator> >
- : public has_trivial_destructor_after_move<Allocator>::value
-{};
+{
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
-*/
+namespace container {
+
+#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
-}}
+}} //namespace boost{ namespace container {
#include <boost/container/detail/config_end.hpp>
diff --git a/boost/container/static_vector.hpp b/boost/container/static_vector.hpp
index 1ae80114b3..c36832dfa3 100644
--- a/boost/container/static_vector.hpp
+++ b/boost/container/static_vector.hpp
@@ -11,14 +11,23 @@
#ifndef BOOST_CONTAINER_STATIC_VECTOR_HPP
#define BOOST_CONTAINER_STATIC_VECTOR_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
-
+#include <boost/container/detail/workaround.hpp>
+#include <boost/container/detail/type_traits.hpp>
#include <boost/container/vector.hpp>
-#include <boost/aligned_storage.hpp>
+
+#include <cstddef>
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list>
+#endif
namespace boost { namespace container {
@@ -32,34 +41,33 @@ class static_storage_allocator
public:
typedef T value_type;
- static_storage_allocator() BOOST_CONTAINER_NOEXCEPT
+ static_storage_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{}
- static_storage_allocator(const static_storage_allocator &) BOOST_CONTAINER_NOEXCEPT
+ static_storage_allocator(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{}
- static_storage_allocator & operator=(const static_storage_allocator &) BOOST_CONTAINER_NOEXCEPT
+ static_storage_allocator & operator=(const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{}
- T* internal_storage() const BOOST_CONTAINER_NOEXCEPT
+ T* internal_storage() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_cast<T*>(static_cast<const T*>(static_cast<const void*>(&storage))); }
- T* internal_storage() BOOST_CONTAINER_NOEXCEPT
+ T* internal_storage() BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<T*>(static_cast<void*>(&storage)); }
static const std::size_t internal_capacity = N;
typedef boost::container::container_detail::version_type<static_storage_allocator, 0> version;
- friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator==(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return false; }
- friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator!=(const static_storage_allocator &, const static_storage_allocator &) BOOST_NOEXCEPT_OR_NOTHROW
{ return true; }
private:
- typename boost::aligned_storage
- <sizeof(T)*N, boost::alignment_of<T>::value>::type storage;
+ typename aligned_storage<sizeof(T)*N, alignment_of<T>::value>::type storage;
};
} //namespace container_detail {
@@ -135,7 +143,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- static_vector() BOOST_CONTAINER_NOEXCEPT
+ static_vector() BOOST_NOEXCEPT_OR_NOTHROW
: base_t()
{}
@@ -259,13 +267,13 @@ public:
//! @param other The static_vector which content will be moved to this one.
//!
//! @par Throws
- //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
- //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
+ //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
+ //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
//!
//! @par Complexity
//! Linear O(N).
static_vector(BOOST_RV_REF(static_vector) other)
- : base_t(boost::move(static_cast<base_t&>(other)))
+ : base_t(BOOST_MOVE_BASE(base_t, other))
{}
//! @pre <tt>other.size() <= capacity()</tt>
@@ -275,14 +283,14 @@ public:
//! @param other The static_vector which content will be moved to this one.
//!
//! @par Throws
- //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
- //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
+ //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor throws.
+ //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor throws.
//!
//! @par Complexity
//! Linear O(N).
template <std::size_t C>
static_vector(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
- : base_t(boost::move(static_cast<typename static_vector<value_type, C>::base_t&>(other)))
+ : base_t(BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other))
{}
//! @brief Copy assigns Values stored in the other static_vector to this one.
@@ -310,9 +318,7 @@ public:
//! @par Complexity
//! Linear O(N).
static_vector & operator=(std::initializer_list<value_type> il)
- {
- return static_cast<static_vector&>(base_t::operator=(il));
- }
+ { return static_cast<static_vector&>(base_t::operator=(il)); }
#endif
//! @pre <tt>other.size() <= capacity()</tt>
@@ -338,14 +344,14 @@ public:
//! @param other The static_vector which content will be moved to this one.
//!
//! @par Throws
- //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
- //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
+ //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
+ //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//!
//! @par Complexity
//! Linear O(N).
static_vector & operator=(BOOST_RV_REF(static_vector) other)
{
- return static_cast<static_vector&>(base_t::operator=(boost::move(static_cast<base_t&>(other))));
+ return static_cast<static_vector&>(base_t::operator=(BOOST_MOVE_BASE(base_t, other)));
}
//! @pre <tt>other.size() <= capacity()</tt>
@@ -355,8 +361,8 @@ public:
//! @param other The static_vector which content will be moved to this one.
//!
//! @par Throws
- //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
- //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
+ //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws.
+ //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws.
//!
//! @par Complexity
//! Linear O(N).
@@ -364,7 +370,7 @@ public:
static_vector & operator=(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
{
return static_cast<static_vector&>(base_t::operator=
- (boost::move(static_cast<typename static_vector<value_type, C>::base_t&>(other))));
+ (BOOST_MOVE_BASE(typename static_vector<value_type BOOST_MOVE_I C>::base_t, other)));
}
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -383,8 +389,8 @@ public:
//! @param other The static_vector which content will be swapped with this one's content.
//!
//! @par Throws
- //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
- //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
+ //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
+ //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//!
//! @par Complexity
//! Linear O(N).
@@ -397,8 +403,8 @@ public:
//! @param other The static_vector which content will be swapped with this one's content.
//!
//! @par Throws
- //! @li If \c boost::has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
- //! @li If \c boost::has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
+ //! @li If \c has_nothrow_move<Value>::value is \c true and Value's move constructor or move assignment throws,
+ //! @li If \c has_nothrow_move<Value>::value is \c false and Value's copy constructor or copy assignment throws,
//!
//! @par Complexity
//! Linear O(N).
@@ -462,7 +468,7 @@ public:
//!
//! @par Complexity
//! Linear O(N).
- void reserve(size_type count) BOOST_CONTAINER_NOEXCEPT;
+ void reserve(size_type count) BOOST_NOEXCEPT_OR_NOTHROW;
//! @pre <tt>size() < capacity()</tt>
//!
@@ -703,7 +709,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- void clear() BOOST_CONTAINER_NOEXCEPT;
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW;
//! @pre <tt>i < size()</tt>
//!
@@ -769,6 +775,66 @@ public:
//! Constant O(1).
const_reference operator[](size_type i) const;
+ //! @pre <tt>i =< size()</tt>
+ //!
+ //! @brief Returns a iterator to the i-th element.
+ //!
+ //! @param i The element's index.
+ //!
+ //! @return a iterator to the i-th element.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ iterator nth(size_type i);
+
+ //! @pre <tt>i =< size()</tt>
+ //!
+ //! @brief Returns a const_iterator to the i-th element.
+ //!
+ //! @param i The element's index.
+ //!
+ //! @return a const_iterator to the i-th element.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ const_iterator nth(size_type i) const;
+
+ //! @pre <tt>begin() <= p <= end()</tt>
+ //!
+ //! @brief Returns the index of the element pointed by p.
+ //!
+ //! @param i The element's index.
+ //!
+ //! @return The index of the element pointed by p.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ size_type index_of(iterator p);
+
+ //! @pre <tt>begin() <= p <= end()</tt>
+ //!
+ //! @brief Returns the index of the element pointed by p.
+ //!
+ //! @param i The index of the element pointed by p.
+ //!
+ //! @return a const_iterator to the i-th element.
+ //!
+ //! @par Throws
+ //! Nothing by default.
+ //!
+ //! @par Complexity
+ //! Constant O(1).
+ size_type index_of(const_iterator p) const;
+
//! @pre \c !empty()
//!
//! @brief Returns reference to the first element.
@@ -833,7 +899,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- Value * data() BOOST_CONTAINER_NOEXCEPT;
+ Value * data() BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Const pointer such that <tt>[data(), data() + size())</tt> is a valid range.
//! For a non-empty vector <tt>data() == &front()</tt>.
@@ -843,7 +909,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const Value * data() const BOOST_CONTAINER_NOEXCEPT;
+ const Value * data() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns iterator to the first element.
//!
@@ -854,7 +920,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- iterator begin() BOOST_CONTAINER_NOEXCEPT;
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns const iterator to the first element.
//!
@@ -865,7 +931,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns const iterator to the first element.
//!
@@ -876,7 +942,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns iterator to the one after the last element.
//!
@@ -887,7 +953,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- iterator end() BOOST_CONTAINER_NOEXCEPT;
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns const iterator to the one after the last element.
//!
@@ -898,7 +964,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns const iterator to the one after the last element.
//!
@@ -909,7 +975,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT;
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns reverse iterator to the first element of the reversed container.
//!
@@ -921,7 +987,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns const reverse iterator to the first element of the reversed container.
//!
@@ -933,7 +999,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns const reverse iterator to the first element of the reversed container.
//!
@@ -945,7 +1011,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns reverse iterator to the one after the last element of the reversed container.
//!
@@ -957,7 +1023,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT;
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
//!
@@ -969,7 +1035,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns const reverse iterator to the one after the last element of the reversed container.
//!
@@ -981,7 +1047,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT;
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns container's capacity.
//!
@@ -992,7 +1058,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- static size_type capacity() BOOST_CONTAINER_NOEXCEPT;
+ static size_type capacity() BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns container's capacity.
//!
@@ -1003,7 +1069,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- static size_type max_size() BOOST_CONTAINER_NOEXCEPT;
+ static size_type max_size() BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns the number of stored elements.
//!
@@ -1014,7 +1080,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- size_type size() const BOOST_CONTAINER_NOEXCEPT;
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Queries if the container contains elements.
//!
@@ -1026,7 +1092,7 @@ public:
//!
//! @par Complexity
//! Constant O(1).
- bool empty() const BOOST_CONTAINER_NOEXCEPT;
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW;
#else
friend void swap(static_vector &x, static_vector &y)
diff --git a/boost/container/string.hpp b/boost/container/string.hpp
index 1c3cf3bbc8..e5ec287cf8 100644
--- a/boost/container/string.hpp
+++ b/boost/container/string.hpp
@@ -11,36 +11,44 @@
#ifndef BOOST_CONTAINER_STRING_HPP
#define BOOST_CONTAINER_STRING_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-
-#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
-#include <boost/container/throw_exception.hpp>
-#include <boost/container/detail/utilities.hpp>
-#include <boost/container/detail/iterators.hpp>
-#include <boost/container/detail/algorithms.hpp>
-#include <boost/container/detail/version_type.hpp>
-#include <boost/container/detail/allocation_type.hpp>
+// container
#include <boost/container/allocator_traits.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
+#include <boost/container/throw_exception.hpp>
+// container/detail
+#include <boost/container/detail/alloc_helpers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/container/detail/allocation_type.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/min_max.hpp>
#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/next_capacity.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/version_type.hpp>
+
#include <boost/move/utility_core.hpp>
+#include <boost/move/adl_move_swap.hpp>
#include <boost/static_assert.hpp>
-#include <boost/functional/hash.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/core/no_exceptions_support.hpp>
+#include <boost/container/detail/minimal_char_traits_header.hpp>
+#include <boost/functional/hash.hpp>
+
-#include <functional>
-#include <string>
-#include <utility>
-#include <iterator>
-#include <memory>
#include <algorithm>
+#include <functional> //bind2nd, etc.
#include <iosfwd>
#include <istream>
#include <ostream>
@@ -49,8 +57,6 @@
#include <cstddef>
#include <climits>
#include <boost/container/detail/type_traits.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/aligned_storage.hpp>
#include <boost/move/traits.hpp>
namespace boost {
@@ -152,8 +158,8 @@ class basic_string_base
//This type has the same alignment and size as long_t but it's POD
//so, unlike long_t, it can be placed in a union
- typedef typename boost::aligned_storage< sizeof(long_t),
- container_detail::alignment_of<long_t>::value>::type long_raw_t;
+ typedef typename container_detail::aligned_storage
+ <sizeof(long_t), container_detail::alignment_of<long_t>::value>::type long_raw_t;
protected:
static const size_type MinInternalBufferChars = 8;
@@ -250,23 +256,20 @@ class basic_string_base
protected:
- typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
- typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::version<Allocator>::value> alloc_version;
- std::pair<pointer, bool>
- allocation_command(allocation_type command,
+ pointer allocation_command(allocation_type command,
size_type limit_size,
- size_type preferred_size,
- size_type &received_size, pointer reuse = 0)
+ size_type &prefer_in_recvd_out_size,
+ pointer &reuse)
{
if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
- reuse = pointer();
+ reuse = 0;
command &= ~(expand_fwd | expand_bwd);
}
return container_detail::allocator_version_traits<Allocator>::allocation_command
- (this->alloc(), command, limit_size, preferred_size, received_size, reuse);
+ (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse);
}
size_type next_capacity(size_type additional_objects) const
@@ -313,7 +316,8 @@ class basic_string_base
if (n <= this->max_size()) {
if(n > InternalBufferChars){
size_type new_cap = this->next_capacity(n);
- pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first;
+ pointer reuse = 0;
+ pointer p = this->allocation_command(allocate_new, n, new_cap, reuse);
this->is_short(false);
this->priv_long_addr(p);
this->priv_long_size(0);
@@ -411,7 +415,9 @@ class basic_string_base
{
if(this->is_short()){
if(other.is_short()){
- std::swap(this->members_.m_repr, other.members_.m_repr);
+ repr_t tmp(this->members_.m_repr);
+ this->members_.m_repr = other.members_.m_repr;
+ other.members_.m_repr = tmp;
}
else{
short_t short_backup(this->members_.m_repr.short_repr());
@@ -432,7 +438,7 @@ class basic_string_base
this->members_.m_repr.short_repr() = short_backup;
}
else{
- boost::container::swap_dispatch(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
+ boost::adl_move_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
}
}
}
@@ -475,7 +481,7 @@ class basic_string_base
//! \tparam Traits The Character Traits type, which encapsulates basic character operations
//! \tparam Allocator The allocator, used for internal memory management.
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
-template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT> >
+template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = new_allocator<CharT> >
#else
template <class CharT, class Traits, class Allocator>
#endif
@@ -543,15 +549,13 @@ class basic_string
typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
typedef BOOST_CONTAINER_IMPDEF(pointer) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
static const size_type npos = size_type(-1);
#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;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -586,7 +590,7 @@ class basic_string
//! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
//!
//! <b>Throws</b>: Nothing
- explicit basic_string(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT
+ explicit basic_string(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
: base_t(a)
{ this->priv_terminate_string(); }
@@ -607,7 +611,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- basic_string(BOOST_RV_REF(basic_string) s) BOOST_CONTAINER_NOEXCEPT
+ basic_string(BOOST_RV_REF(basic_string) s) BOOST_NOEXCEPT_OR_NOTHROW
: base_t(boost::move(s.alloc()))
{
if(s.alloc() == this->alloc()){
@@ -713,7 +717,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- ~basic_string() BOOST_CONTAINER_NOEXCEPT
+ ~basic_string() BOOST_NOEXCEPT_OR_NOTHROW
{}
//! <b>Effects</b>: Copy constructs a string.
@@ -751,7 +755,8 @@ class basic_string
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
basic_string& operator=(BOOST_RV_REF(basic_string) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+ || allocator_traits_type::is_always_equal::value)
{
//for move constructor, no aliasing (&x != this) is assummed.
BOOST_ASSERT(this != &x);
@@ -791,7 +796,7 @@ class basic_string
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -801,7 +806,7 @@ class basic_string
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -811,7 +816,7 @@ class basic_string
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->alloc(); }
//////////////////////////////////////////////
@@ -825,7 +830,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_addr(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
@@ -833,7 +838,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_addr(); }
//! <b>Effects</b>: Returns an iterator to the end of the vector.
@@ -841,7 +846,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_end_addr(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the vector.
@@ -849,7 +854,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_end_addr(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -858,7 +863,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(this->priv_end_addr()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -867,7 +872,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -876,7 +881,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(this->priv_addr()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -885,7 +890,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crend(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
@@ -893,7 +898,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_addr(); }
//! <b>Effects</b>: Returns a const_iterator to the end of the vector.
@@ -901,7 +906,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_end_addr(); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -910,7 +915,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->priv_end_addr()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -919,7 +924,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->priv_addr()); }
//////////////////////////////////////////////
@@ -933,7 +938,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return !this->priv_size(); }
//! <b>Effects</b>: Returns the number of the elements contained in the vector.
@@ -941,7 +946,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_size(); }
//! <b>Effects</b>: Returns the number of the elements contained in the vector.
@@ -949,7 +954,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type length() const BOOST_CONTAINER_NOEXCEPT
+ size_type length() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->size(); }
//! <b>Effects</b>: Returns the largest possible size of the vector.
@@ -957,7 +962,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return base_t::max_size(); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -1009,7 +1014,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+ size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->priv_capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1066,7 +1071,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
+ reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{ return *(this->priv_addr() + n); }
//! <b>Requires</b>: size() > n.
@@ -1077,7 +1082,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
+ const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{ return *(this->priv_addr() + n); }
//! <b>Requires</b>: size() > n.
@@ -1220,7 +1225,7 @@ class basic_string
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: *this
- basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_CONTAINER_NOEXCEPT
+ basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_NOEXCEPT_OR_NOTHROW
{ return this->swap_data(ms), *this; }
//! <b>Requires</b>: pos <= str.size()
@@ -1458,27 +1463,28 @@ class basic_string
{
const size_type n_pos = p - this->cbegin();
if (first != last) {
- const size_type n = std::distance(first, last);
+ const size_type n = boost::container::iterator_distance(first, last);
const size_type old_size = this->priv_size();
const size_type remaining = this->capacity() - old_size;
const pointer old_start = this->priv_addr();
bool enough_capacity = false;
- std::pair<pointer, bool> allocation_ret;
size_type new_cap = 0;
//Check if we have enough capacity
+ pointer hint = pointer();
+ pointer allocation_ret = pointer();
if (remaining >= n){
enough_capacity = true;
}
else {
//Otherwise expand current buffer or allocate new storage
new_cap = this->next_capacity(n);
+ hint = old_start;
allocation_ret = this->allocation_command
- (allocate_new | expand_fwd | expand_bwd, old_size + n + 1,
- new_cap, new_cap, old_start);
+ (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint);
//Check forward expansion
- if(old_start == allocation_ret.first){
+ if(old_start == allocation_ret){
enough_capacity = true;
this->priv_storage(new_cap);
}
@@ -1501,7 +1507,7 @@ class basic_string
}
else {
ForwardIter mid = first;
- std::advance(mid, elems_after + 1);
+ boost::container::iterator_advance(mid, elems_after + 1);
priv_uninitialized_copy(mid, last, old_start + old_size + 1);
const size_type newer_size = old_size + (n - elems_after);
@@ -1514,8 +1520,8 @@ class basic_string
}
}
else{
- pointer new_start = allocation_ret.first;
- if(!allocation_ret.second){
+ pointer new_start = allocation_ret;
+ if(!hint){
//Copy data to new buffer
size_type new_length = 0;
//This can't throw, since characters are POD
@@ -1585,7 +1591,7 @@ class basic_string
//!
//! <b>Returns</b>: An iterator which points to the element immediately following p prior to the element being
//! erased. If no such element exists, end() is returned.
- iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{
// The move includes the terminating null.
CharT * const ptr = const_cast<CharT*>(container_detail::to_raw_pointer(p));
@@ -1605,7 +1611,7 @@ class basic_string
//!
//! <b>Returns</b>: An iterator which points to the element pointed to by last prior to
//! the other elements being erased. If no such element exists, end() is returned.
- iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+ iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
{
CharT * f = const_cast<CharT*>(container_detail::to_raw_pointer(first));
if (first != last) { // The move includes the terminating null.
@@ -1625,7 +1631,7 @@ class basic_string
//! <b>Throws</b>: Nothing
//!
//! <b>Effects</b>: Equivalent to erase(size() - 1, 1).
- void pop_back() BOOST_CONTAINER_NOEXCEPT
+ void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
{
const size_type old_size = this->priv_size();
Traits::assign(this->priv_addr()[old_size-1], CharT(0));
@@ -1637,7 +1643,7 @@ class basic_string
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements in the vector.
- void clear() BOOST_CONTAINER_NOEXCEPT
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW
{
if (!this->empty()) {
Traits::assign(*this->priv_addr(), CharT(0));
@@ -1850,7 +1856,7 @@ class basic_string
>::type * = 0
)
{
- difference_type n = std::distance(j1, j2);
+ difference_type n = boost::container::iterator_distance(j1, j2);
const difference_type len = i2 - i1;
if (len >= n) {
this->priv_copy(j1, j2, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
@@ -1858,7 +1864,7 @@ class basic_string
}
else {
ForwardIter m = j1;
- std::advance(m, len);
+ boost::container::iterator_advance(m, len);
this->priv_copy(j1, m, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
this->insert(i2, m, j2);
}
@@ -1891,6 +1897,8 @@ class basic_string
//!
//! <b>Throws</b>: Nothing
void swap(basic_string& x)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
+ || allocator_traits_type::is_always_equal::value)
{
this->base_t::swap_data(x);
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
@@ -1905,18 +1913,18 @@ class basic_string
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
//!
- //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
+ //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
//!
//! <b>Complexity</b>: constant time.
- const CharT* c_str() const BOOST_CONTAINER_NOEXCEPT
+ const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::to_raw_pointer(this->priv_addr()); }
//! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
//!
- //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()].
+ //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
//!
//! <b>Complexity</b>: constant time.
- const CharT* data() const BOOST_CONTAINER_NOEXCEPT
+ const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::to_raw_pointer(this->priv_addr()); }
//////////////////////////////////////////////
@@ -2357,8 +2365,8 @@ class basic_string
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;
+ pointer reuse = 0;
+ pointer new_start = this->allocation_command(allocate_new, n, new_cap, reuse);
size_type new_length = 0;
const pointer addr = this->priv_addr();
@@ -2389,7 +2397,7 @@ class basic_string
template<class AllocVersion>
void priv_shrink_to_fit_dynamic_buffer
( AllocVersion
- , typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v1> >::type* = 0)
+ , typename container_detail::enable_if<container_detail::is_same<AllocVersion, version_1> >::type* = 0)
{
//Allocate a new buffer.
size_type real_cap = 0;
@@ -2398,13 +2406,14 @@ class basic_string
const size_type long_storage = this->priv_long_storage();
//We can make this nothrow as chars are always NoThrowCopyables
BOOST_TRY{
- const std::pair<pointer, bool> ret = this->allocation_command
- (allocate_new, long_size+1, long_size+1, real_cap, long_addr);
+ pointer reuse = 0;
+ real_cap = long_size+1;
+ const pointer ret = this->allocation_command(allocate_new, long_size+1, real_cap, reuse);
//Copy and update
- Traits::copy( container_detail::to_raw_pointer(ret.first)
+ Traits::copy( container_detail::to_raw_pointer(ret)
, container_detail::to_raw_pointer(this->priv_long_addr())
, long_size+1);
- this->priv_long_addr(ret.first);
+ this->priv_long_addr(ret);
this->priv_storage(real_cap);
//And release old buffer
this->alloc().deallocate(long_addr, long_storage);
@@ -2418,13 +2427,12 @@ class basic_string
template<class AllocVersion>
void priv_shrink_to_fit_dynamic_buffer
( AllocVersion
- , typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v2> >::type* = 0)
+ , typename container_detail::enable_if<container_detail::is_same<AllocVersion, version_2> >::type* = 0)
{
- size_type received_size;
+ size_type received_size = this->priv_long_size()+1;
+ pointer hint = this->priv_long_addr();
if(this->alloc().allocation_command
- ( shrink_in_place | nothrow_allocation
- , this->priv_long_storage(), this->priv_long_size()+1
- , received_size, this->priv_long_addr()).first){
+ ( shrink_in_place | nothrow_allocation, this->priv_long_storage(), received_size, hint)){
this->priv_storage(received_size);
}
}
@@ -2504,7 +2512,7 @@ class basic_string
InputIter f, InputIter l,
container_detail::false_)
{
- typedef typename std::iterator_traits<InputIter>::iterator_category Category;
+ typedef typename boost::container::iterator_traits<InputIter>::iterator_category Category;
return this->priv_replace(first, last, f, l, Category());
}
@@ -2518,7 +2526,7 @@ class basic_string
typedef basic_string
<char
,std::char_traits<char>
- ,std::allocator<char> >
+ ,new_allocator<char> >
string;
//!Typedef for a basic_string of
@@ -2526,7 +2534,7 @@ string;
typedef basic_string
<wchar_t
,std::char_traits<wchar_t>
- ,std::allocator<wchar_t> >
+ ,new_allocator<wchar_t> >
wstring;
#endif
@@ -2552,29 +2560,29 @@ template <class CharT, class Traits, class Allocator> inline
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT, Traits, Allocator> operator+
- ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END mx
- , BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END my)
+ ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
+ , BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
{
- mx += my;
- return boost::move(mx);
+ x += y;
+ return boost::move(x);
}
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT, Traits, Allocator> operator+
- ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END mx
+ ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
, const basic_string<CharT,Traits,Allocator>& y)
{
- mx += y;
- return boost::move(mx);
+ x += y;
+ return boost::move(x);
}
template <class CharT, class Traits, class Allocator> inline
basic_string<CharT, Traits, Allocator> operator+
(const basic_string<CharT,Traits,Allocator>& x
- ,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END my)
+ ,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
{
- my.insert(my.begin(), x.begin(), x.end());
- return boost::move(my);
+ y.insert(y.begin(), x.begin(), x.end());
+ return boost::move(y);
}
template <class CharT, class Traits, class Allocator> inline
@@ -2899,15 +2907,15 @@ inline std::size_t hash_value(basic_string<Ch, std::char_traits<Ch>, Allocator>
namespace boost {
-template <class T>
-struct has_trivial_destructor_after_move;
-
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class C, class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
- : public ::boost::has_trivial_destructor_after_move<Allocator>
-{};
+{
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
}
diff --git a/boost/container/throw_exception.hpp b/boost/container/throw_exception.hpp
index 02768856e5..2c893e95c8 100644
--- a/boost/container/throw_exception.hpp
+++ b/boost/container/throw_exception.hpp
@@ -11,7 +11,11 @@
#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP
#define BOOST_CONTAINER_THROW_EXCEPTION_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
diff --git a/boost/container/vector.hpp b/boost/container/vector.hpp
index 765a2c6861..1b6d963934 100644
--- a/boost/container/vector.hpp
+++ b/boost/container/vector.hpp
@@ -11,51 +11,57 @@
#ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP
#define BOOST_CONTAINER_CONTAINER_VECTOR_HPP
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-#include <boost/container/container_fwd.hpp>
-
-//#include <cstddef> //Already included by container_fwd.hpp
-#include <memory> //for std::allocator
-#include <iterator> //for std::random_access_iterator_tag
-#include <utility> //for std::pair,std::distance
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
-#include <initializer_list> //for std::initializer_list
-#endif
-
-#include <boost/core/no_exceptions_support.hpp>
-#include <boost/assert.hpp>
-#include <boost/move/utility_core.hpp>
-#include <boost/move/iterator.hpp>
-#include <boost/move/algorithm.hpp>
-#include <boost/move/detail/move_helpers.hpp>
-#include <boost/move/traits.hpp>
-#include <boost/container/detail/version_type.hpp>
-#include <boost/container/detail/allocation_type.hpp>
-#include <boost/container/detail/utilities.hpp>
-#include <boost/container/detail/iterators.hpp>
-#include <boost/container/detail/algorithms.hpp>
-#include <boost/container/detail/destroyers.hpp>
+// container
+#include <boost/container/container_fwd.hpp>
#include <boost/container/allocator_traits.hpp>
-#include <boost/container/detail/allocator_version_traits.hpp>
+#include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp>
+// container detail
+#include <boost/container/detail/advanced_insert_int.hpp>
+#include <boost/container/detail/algorithm.hpp> //equal()
+#include <boost/container/detail/alloc_helpers.hpp>
+#include <boost/container/detail/allocation_type.hpp>
+#include <boost/container/detail/copy_move_algo.hpp>
+#include <boost/container/detail/destroyers.hpp>
+#include <boost/container/detail/iterator.hpp>
+#include <boost/container/detail/iterators.hpp>
+#include <boost/container/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/next_capacity.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/detail/advanced_insert_int.hpp>
-
+#include <boost/container/detail/version_type.hpp>
+// intrusive
#include <boost/intrusive/pointer_traits.hpp>
+// move
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/move/utility_core.hpp>
+// move/detail
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
+#endif
+#include <boost/move/detail/move_helpers.hpp>
+// other
+#include <boost/core/no_exceptions_support.hpp>
+#include <boost/assert.hpp>
-#include <boost/type_traits/has_trivial_destructor.hpp>
-#include <boost/type_traits/has_trivial_copy.hpp>
-#include <boost/type_traits/has_trivial_assign.hpp>
-#include <boost/type_traits/has_nothrow_copy.hpp>
-#include <boost/type_traits/has_nothrow_assign.hpp>
-#include <boost/type_traits/has_nothrow_constructor.hpp>
+//std
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+#include <initializer_list> //for std::initializer_list
+#endif
namespace boost {
namespace container {
@@ -81,7 +87,7 @@ class vec_iterator
rebind_pointer<const value_type>::type
, Pointer
>::type pointer;
- typedef typename boost::intrusive::pointer_traits<Pointer> ptr_traits;
+ typedef typename boost::intrusive::pointer_traits<pointer> ptr_traits;
typedef typename ptr_traits::reference reference;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -89,13 +95,13 @@ class vec_iterator
Pointer m_ptr;
public:
- const Pointer &get_ptr() const BOOST_CONTAINER_NOEXCEPT
+ const Pointer &get_ptr() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_ptr; }
- Pointer &get_ptr() BOOST_CONTAINER_NOEXCEPT
+ Pointer &get_ptr() BOOST_NOEXCEPT_OR_NOTHROW
{ return m_ptr; }
- explicit vec_iterator(Pointer ptr) BOOST_CONTAINER_NOEXCEPT
+ explicit vec_iterator(Pointer ptr) BOOST_NOEXCEPT_OR_NOTHROW
: m_ptr(ptr)
{}
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -103,84 +109,84 @@ class vec_iterator
public:
//Constructors
- vec_iterator() BOOST_CONTAINER_NOEXCEPT
+ vec_iterator() BOOST_NOEXCEPT_OR_NOTHROW
: m_ptr() //Value initialization to achieve "null iterators" (N3644)
{}
- vec_iterator(vec_iterator<Pointer, false> const& other) BOOST_CONTAINER_NOEXCEPT
+ vec_iterator(vec_iterator<Pointer, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
: m_ptr(other.get_ptr())
{}
//Pointer like operators
- reference operator*() const BOOST_CONTAINER_NOEXCEPT
+ reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *m_ptr; }
- pointer operator->() const BOOST_CONTAINER_NOEXCEPT
+ pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
- reference operator[](difference_type off) const BOOST_CONTAINER_NOEXCEPT
+ reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_ptr[off]; }
//Increment / Decrement
- vec_iterator& operator++() BOOST_CONTAINER_NOEXCEPT
+ vec_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
{ ++m_ptr; return *this; }
- vec_iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
+ vec_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
{ return vec_iterator(m_ptr++); }
- vec_iterator& operator--() BOOST_CONTAINER_NOEXCEPT
+ vec_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
{ --m_ptr; return *this; }
- vec_iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
+ vec_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
{ return vec_iterator(m_ptr--); }
//Arithmetic
- vec_iterator& operator+=(difference_type off) BOOST_CONTAINER_NOEXCEPT
+ vec_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
{ m_ptr += off; return *this; }
- vec_iterator& operator-=(difference_type off) BOOST_CONTAINER_NOEXCEPT
+ vec_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
{ m_ptr -= off; return *this; }
- friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_CONTAINER_NOEXCEPT
+ friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
{ return vec_iterator(x.m_ptr+off); }
- friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_CONTAINER_NOEXCEPT
+ friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW
{ right.m_ptr += off; return right; }
- friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_CONTAINER_NOEXCEPT
+ friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW
{ left.m_ptr -= off; return left; }
- friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_CONTAINER_NOEXCEPT
+ friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW
{ return left.m_ptr - right.m_ptr; }
//Comparison operators
- friend bool operator== (const vec_iterator& l, const vec_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator== (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_ptr == r.m_ptr; }
- friend bool operator!= (const vec_iterator& l, const vec_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator!= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_ptr != r.m_ptr; }
- friend bool operator< (const vec_iterator& l, const vec_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator< (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_ptr < r.m_ptr; }
- friend bool operator<= (const vec_iterator& l, const vec_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator<= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_ptr <= r.m_ptr; }
- friend bool operator> (const vec_iterator& l, const vec_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator> (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_ptr > r.m_ptr; }
- friend bool operator>= (const vec_iterator& l, const vec_iterator& r) BOOST_CONTAINER_NOEXCEPT
+ friend bool operator>= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
{ return l.m_ptr >= r.m_ptr; }
};
} //namespace container_detail {
template<class Pointer, bool IsConst>
-const Pointer &vector_iterator_get_ptr(const container_detail::vec_iterator<Pointer, IsConst> &it) BOOST_CONTAINER_NOEXCEPT
+const Pointer &vector_iterator_get_ptr(const container_detail::vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
{ return it.get_ptr(); }
template<class Pointer, bool IsConst>
-Pointer &get_ptr(container_detail::vec_iterator<Pointer, IsConst> &it) BOOST_CONTAINER_NOEXCEPT
+Pointer &get_ptr(container_detail::vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
{ return it.get_ptr(); }
namespace container_detail {
@@ -199,7 +205,7 @@ struct vector_get_ptr_pointer_to_non_const
typedef typename pointer_traits_t
::template rebind_pointer<non_const_element_type>::type return_type;
- static return_type get_ptr(const const_pointer &ptr) BOOST_CONTAINER_NOEXCEPT
+ static return_type get_ptr(const const_pointer &ptr) BOOST_NOEXCEPT_OR_NOTHROW
{ return boost::intrusive::pointer_traits<return_type>::const_cast_from(ptr); }
};
@@ -207,7 +213,7 @@ template<class Pointer>
struct vector_get_ptr_pointer_to_non_const<Pointer, false>
{
typedef const Pointer & return_type;
- static return_type get_ptr(const Pointer &ptr) BOOST_CONTAINER_NOEXCEPT
+ static return_type get_ptr(const Pointer &ptr) BOOST_NOEXCEPT_OR_NOTHROW
{ return ptr; }
};
@@ -215,7 +221,7 @@ struct vector_get_ptr_pointer_to_non_const<Pointer, false>
template<class MaybeConstPointer>
typename container_detail::vector_get_ptr_pointer_to_non_const<MaybeConstPointer>::return_type
- vector_iterator_get_ptr(const MaybeConstPointer &ptr) BOOST_CONTAINER_NOEXCEPT
+ vector_iterator_get_ptr(const MaybeConstPointer &ptr) BOOST_NOEXCEPT_OR_NOTHROW
{
return container_detail::vector_get_ptr_pointer_to_non_const<MaybeConstPointer>::get_ptr(ptr);
}
@@ -230,12 +236,12 @@ static const uninitialized_size_t uninitialized_size = uninitialized_size_t();
template <class T>
struct vector_value_traits_base
{
- static const bool trivial_dctr = boost::has_trivial_destructor<T>::value;
- static const bool trivial_dctr_after_move = ::boost::has_trivial_destructor_after_move<T>::value;
- static const bool trivial_copy = has_trivial_copy<T>::value;
- static const bool nothrow_copy = has_nothrow_copy<T>::value || trivial_copy;
- static const bool trivial_assign = has_trivial_assign<T>::value;
- static const bool nothrow_assign = has_nothrow_assign<T>::value || trivial_assign;
+ static const bool trivial_dctr = is_trivially_destructible<T>::value;
+ static const bool trivial_dctr_after_move = has_trivial_destructor_after_move<T>::value;
+ static const bool trivial_copy = is_trivially_copy_constructible<T>::value;
+ static const bool nothrow_copy = is_nothrow_copy_constructible<T>::value || trivial_copy;
+ static const bool trivial_assign = is_trivially_copy_assignable<T>::value;
+ static const bool nothrow_assign = is_nothrow_copy_assignable<T>::value || trivial_assign;
};
@@ -266,20 +272,38 @@ struct vector_alloc_holder
BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder)
public:
+ typedef Allocator allocator_type;
typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::size_type size_type;
typedef typename allocator_traits_type::value_type value_type;
+ static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator)
+ {
+ (void)propagate_allocator; (void)p; (void)to_alloc; (void)from_alloc;
+ return (!allocator_traits_type::is_partially_propagable::value ||
+ !allocator_traits_type::storage_is_unpropagable(from_alloc, p)) &&
+ (propagate_allocator || allocator_traits_type::equal(from_alloc, to_alloc));
+ }
+
+ static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p, bool const propagate_allocator)
+ {
+ (void)propagate_allocator; (void)l_p; (void)r_p; (void)l_a; (void)r_a;
+ return (!allocator_traits_type::is_partially_propagable::value ||
+ (!allocator_traits_type::storage_is_unpropagable(r_a, r_p) &&
+ !allocator_traits_type::storage_is_unpropagable(l_a, l_p))
+ ) && (propagate_allocator || allocator_traits_type::equal(l_a, r_a));
+ }
+
//Constructor, does not throw
vector_alloc_holder()
- BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
+ BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value)
: Allocator(), m_start(), m_size(), m_capacity()
{}
//Constructor, does not throw
template<class AllocConvertible>
- explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT
+ explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW
: Allocator(boost::forward<AllocConvertible>(a)), m_start(), m_size(), m_capacity()
{}
@@ -292,7 +316,8 @@ struct vector_alloc_holder
, m_capacity()
{
if(initial_size){
- m_start = this->allocation_command(allocate_new, initial_size, initial_size, m_capacity, m_start).first;
+ pointer reuse = 0;
+ m_start = this->allocation_command(allocate_new, initial_size, m_capacity = initial_size, reuse);
}
}
@@ -304,13 +329,13 @@ struct vector_alloc_holder
, m_capacity()
{
if(initial_size){
- m_start = this->allocation_command
- (allocate_new, initial_size, initial_size, m_capacity, m_start).first;
+ pointer reuse = 0;
+ m_start = this->allocation_command(allocate_new, initial_size, m_capacity = initial_size, reuse);
}
}
- vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_CONTAINER_NOEXCEPT
- : Allocator(boost::move(static_cast<Allocator&>(holder)))
+ vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW
+ : Allocator(BOOST_MOVE_BASE(Allocator, holder))
, m_start(holder.m_start)
, m_size(holder.m_size)
, m_capacity(holder.m_capacity)
@@ -319,35 +344,78 @@ struct vector_alloc_holder
holder.m_size = holder.m_capacity = 0;
}
- void first_allocation(size_type cap)
+ vector_alloc_holder(pointer p, size_type capacity, BOOST_RV_REF(vector_alloc_holder) holder)
+ : Allocator(BOOST_MOVE_BASE(Allocator, holder))
+ , m_start(p)
+ , m_size(holder.m_size)
+ , m_capacity(capacity)
{
- if(cap){
- m_start = this->allocation_command
- (allocate_new, cap, cap, m_capacity, m_start).first;
+ allocator_type &this_alloc = this->alloc();
+ allocator_type &x_alloc = holder.alloc();
+ if(this->is_propagable_from(x_alloc, holder.start(), this_alloc, true)){
+ if(this->m_capacity){
+ this->alloc().deallocate(this->m_start, this->m_capacity);
+ }
+ m_start = holder.m_start;
+ m_capacity = holder.m_capacity;
+ holder.m_start = pointer();
+ holder.m_capacity = holder.m_size = 0;
+ }
+ else if(this->m_capacity < holder.m_size){
+ size_type const n = holder.m_size;
+ pointer reuse = pointer();
+ m_start = this->allocation_command(allocate_new, n, m_capacity = n, reuse);
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- ++this->num_alloc;
+ this->num_alloc += n != 0;
#endif
}
}
- void first_allocation_same_allocator_type(size_type cap)
- { this->first_allocation(cap); }
+ vector_alloc_holder(pointer p, size_type n)
+ BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value)
+ : Allocator()
+ , m_start(p)
+ , m_size()
+ , m_capacity(n)
+ {}
+
+ template<class AllocFwd>
+ vector_alloc_holder(pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a)
+ : Allocator(::boost::forward<AllocFwd>(a))
+ , m_start(p)
+ , m_size()
+ , m_capacity(n)
+ {}
- ~vector_alloc_holder() BOOST_CONTAINER_NOEXCEPT
+ ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW
{
if(this->m_capacity){
this->alloc().deallocate(this->m_start, this->m_capacity);
}
}
- std::pair<pointer, bool>
- allocation_command(boost::container::allocation_type command,
- size_type limit_size,
- size_type preferred_size,
- size_type &received_size, const pointer &reuse = pointer())
+ pointer allocation_command(boost::container::allocation_type command,
+ size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
{
- return allocator_version_traits<Allocator>::allocation_command
- (this->alloc(), command, limit_size, preferred_size, received_size, reuse);
+ typedef typename container_detail::version<Allocator>::type alloc_version;
+ return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse);
+ }
+
+ bool try_expand_fwd(size_type at_least)
+ {
+ //There is not enough memory, try to expand the old one
+ const size_type new_cap = this->capacity() + at_least;
+ size_type real_cap = new_cap;
+ pointer reuse = this->start();
+ bool const success = !!this->allocation_command(expand_fwd, new_cap, real_cap, reuse);
+ //Check for forward expansion
+ if(success){
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_expand_fwd;
+ #endif
+ this->capacity(real_cap);
+ }
+ return success;
}
size_type next_capacity(size_type additional_objects) const
@@ -362,37 +430,71 @@ struct vector_alloc_holder
size_type m_size;
size_type m_capacity;
- void swap(vector_alloc_holder &x) BOOST_CONTAINER_NOEXCEPT
+ void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
{
- boost::container::swap_dispatch(this->m_start, x.m_start);
- boost::container::swap_dispatch(this->m_size, x.m_size);
- boost::container::swap_dispatch(this->m_capacity, x.m_capacity);
+ boost::adl_move_swap(this->m_start, x.m_start);
+ boost::adl_move_swap(this->m_size, x.m_size);
+ boost::adl_move_swap(this->m_capacity, x.m_capacity);
}
- void move_from_empty(vector_alloc_holder &x) BOOST_CONTAINER_NOEXCEPT
+ void steal_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
{
- //this->m_size was previously initialized
this->m_start = x.m_start;
+ this->m_size = x.m_size;
this->m_capacity = x.m_capacity;
x.m_start = pointer();
x.m_size = x.m_capacity = 0;
}
- Allocator &alloc() BOOST_CONTAINER_NOEXCEPT
+ Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW
{ return *this; }
- const Allocator &alloc() const BOOST_CONTAINER_NOEXCEPT
+ const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *this; }
- const pointer &start() const BOOST_CONTAINER_NOEXCEPT { return m_start; }
- const size_type &capacity() const BOOST_CONTAINER_NOEXCEPT { return m_capacity; }
- void start(const pointer &p) BOOST_CONTAINER_NOEXCEPT { m_start = p; }
- void capacity(const size_type &c) BOOST_CONTAINER_NOEXCEPT { m_capacity = c; }
+ const pointer &start() const BOOST_NOEXCEPT_OR_NOTHROW { return m_start; }
+ const size_type &capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return m_capacity; }
+ void start(const pointer &p) BOOST_NOEXCEPT_OR_NOTHROW { m_start = p; }
+ void capacity(const size_type &c) BOOST_NOEXCEPT_OR_NOTHROW { m_capacity = c; }
+
+ private:
+ void priv_first_allocation(size_type cap)
+ {
+ if(cap){
+ pointer reuse = 0;
+ m_start = this->allocation_command(allocate_new, cap, cap, reuse);
+ m_capacity = cap;
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ ++this->num_alloc;
+ #endif
+ }
+ }
+
+ pointer priv_allocation_command(version_1, boost::container::allocation_type command,
+ size_type ,
+ size_type &prefer_in_recvd_out_size,
+ pointer &reuse)
+ {
+ (void)command;
+ BOOST_ASSERT( (command & allocate_new));
+ BOOST_ASSERT(!(command & nothrow_allocation));
+ pointer const p = allocator_traits_type::allocate(this->alloc(), prefer_in_recvd_out_size, reuse);
+ reuse = pointer();
+ return p;
+ }
+
+ pointer priv_allocation_command(version_2, boost::container::allocation_type command,
+ size_type limit_size,
+ size_type &prefer_in_recvd_out_size,
+ pointer &reuse)
+ {
+ return this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
+ }
};
//!This struct deallocates and allocated memory
template <class Allocator>
-struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsigned, 0> >
+struct vector_alloc_holder<Allocator, version_0>
: public Allocator
{
private:
@@ -409,13 +511,13 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
//Constructor, does not throw
vector_alloc_holder()
- BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
+ BOOST_NOEXCEPT_IF(container_detail::is_nothrow_default_constructible<Allocator>::value)
: Allocator(), m_size()
{}
//Constructor, does not throw
template<class AllocConvertible>
- explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT
+ explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW
: Allocator(boost::forward<AllocConvertible>(a)), m_size()
{}
@@ -426,7 +528,7 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
, m_size(initial_size) //Size is initialized here...
{
//... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
- this->first_allocation(initial_size);
+ this->priv_first_allocation(initial_size);
}
//Constructor, does not throw
@@ -435,11 +537,11 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
, m_size(initial_size) //Size is initialized here...
{
//... and capacity here, so vector, must call uninitialized_xxx in the derived constructor
- this->first_allocation(initial_size);
+ this->priv_first_allocation(initial_size);
}
vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder)
- : Allocator(boost::move(static_cast<Allocator&>(holder)))
+ : Allocator(BOOST_MOVE_BASE(Allocator, holder))
, m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this
{
::boost::container::uninitialized_move_alloc_n
@@ -453,60 +555,62 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
{
//Different allocator type so we must check we have enough storage
const size_type n = holder.m_size;
- this->first_allocation(n);
+ this->priv_first_allocation(n);
::boost::container::uninitialized_move_alloc_n
(this->alloc(), container_detail::to_raw_pointer(holder.start()), n, container_detail::to_raw_pointer(this->start()));
}
- void first_allocation(size_type cap)
+ void priv_first_allocation(size_type cap)
{
if(cap > Allocator::internal_capacity){
throw_bad_alloc();
}
}
- void first_allocation_same_allocator_type(size_type) BOOST_CONTAINER_NOEXCEPT
- {}
-
- //Destructor
- ~vector_alloc_holder() BOOST_CONTAINER_NOEXCEPT
- {}
-
- void swap(vector_alloc_holder &x)
+ void deep_swap(vector_alloc_holder &x)
{
- this->priv_swap_members_impl(x);
+ this->priv_deep_swap(x);
}
template<class OtherAllocator, class OtherAllocatorVersion>
- void swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
+ void deep_swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
{
if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){
throw_bad_alloc();
}
- this->priv_swap_members_impl(x);
+ this->priv_deep_swap(x);
+ }
+
+ void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
+ { //Containers with version 0 allocators can't be moved without moving elements one by one
+ throw_bad_alloc();
}
- void move_from_empty(vector_alloc_holder &)
- { //Containers with version 0 allocators can't be moved without move elements one by one
+
+ void steal_resources(vector_alloc_holder &)
+ { //Containers with version 0 allocators can't be moved without moving elements one by one
throw_bad_alloc();
}
- Allocator &alloc() BOOST_CONTAINER_NOEXCEPT
+ Allocator &alloc() BOOST_NOEXCEPT_OR_NOTHROW
{ return *this; }
- const Allocator &alloc() const BOOST_CONTAINER_NOEXCEPT
+ const Allocator &alloc() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *this; }
- pointer start() const BOOST_CONTAINER_NOEXCEPT { return Allocator::internal_storage(); }
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT { return Allocator::internal_capacity; }
+ bool try_expand_fwd(size_type at_least)
+ { return !at_least; }
+
+ pointer start() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_storage(); }
+ size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_capacity; }
size_type m_size;
private:
template<class OtherAllocator, class OtherAllocatorVersion>
- void priv_swap_members_impl(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
+ void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x)
{
- const std::size_t MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity;
+ const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity;
value_type *const first_this = container_detail::to_raw_pointer(this->start());
value_type *const first_x = container_detail::to_raw_pointer(x.start());
@@ -516,7 +620,7 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
else{
boost::container::deep_swap_alloc_n<MaxTmpStorage>(this->alloc(), first_x, x.m_size, first_this, this->m_size);
}
- boost::container::swap_dispatch(this->m_size, x.m_size);
+ boost::adl_move_swap(this->m_size, x.m_size);
}
};
@@ -531,23 +635,30 @@ struct vector_alloc_holder<Allocator, container_detail::integral_constant<unsign
//!
//! \tparam T The type of object that is stored in the vector
//! \tparam Allocator The allocator used for all internal memory management
-template <class T, class Allocator BOOST_CONTAINER_DOCONLY(= std::allocator<T>) >
+template <class T, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>) >
class vector
{
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
typedef typename container_detail::version<Allocator>::type alloc_version;
- boost::container::container_detail::vector_alloc_holder
- <Allocator, alloc_version> m_holder;
+ typedef boost::container::container_detail::vector_alloc_holder<Allocator> alloc_holder_t;
+ alloc_holder_t m_holder;
typedef allocator_traits<Allocator> allocator_traits_type;
template <class U, class UAllocator>
friend class vector;
- typedef typename ::boost::container::allocator_traits
- <Allocator>::pointer pointer_impl;
+ typedef typename allocator_traits_type::pointer pointer_impl;
typedef container_detail::vec_iterator<pointer_impl, false> iterator_impl;
typedef container_detail::vec_iterator<pointer_impl, true > const_iterator_impl;
+ protected:
+ static bool is_propagable_from(const Allocator &from_alloc, pointer_impl p, const Allocator &to_alloc, bool const propagate_allocator)
+ { return alloc_holder_t::is_propagable_from(from_alloc, p, to_alloc, propagate_allocator); }
+
+ static bool are_swap_propagable( const Allocator &l_a, pointer_impl l_p
+ , const Allocator &r_a, pointer_impl r_p, bool const propagate_allocator)
+ { return alloc_holder_t::are_swap_propagable(l_a, l_p, r_a, r_p, propagate_allocator); }
+
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
//////////////////////////////////////////////
@@ -572,19 +683,30 @@ class vector
typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator;
typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator;
#endif
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<iterator>) reverse_iterator;
- typedef BOOST_CONTAINER_IMPDEF(container_detail::reverse_iterator<const_iterator>) const_reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
+ typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private:
BOOST_COPYABLE_AND_MOVABLE(vector)
typedef container_detail::vector_value_traits<Allocator> value_traits;
+ typedef constant_iterator<T, difference_type> cvalue_iterator;
- typedef container_detail::integral_constant<unsigned, 0> allocator_v0;
- typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
- typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
+ protected:
+
+ void steal_resources(vector &x)
+ { return this->m_holder.steal_resources(x.m_holder); }
+
+ struct initial_capacity_t{};
+ template<class AllocFwd>
+ vector(initial_capacity_t, pointer initial_memory, size_type capacity, BOOST_FWD_REF(AllocFwd) a)
+ : m_holder(initial_memory, capacity, ::boost::forward<AllocFwd>(a))
+ {}
+
+ vector(initial_capacity_t, pointer initial_memory, size_type capacity)
+ : m_holder(initial_memory, capacity)
+ {}
- typedef constant_iterator<T, difference_type> cvalue_iterator;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
public:
@@ -596,11 +718,10 @@ class vector
//! <b>Effects</b>: Constructs a vector taking the allocator as parameter.
//!
- //! <b>Throws</b>: If allocator_type's default constructor throws.
+ //! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- vector()
- BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor<Allocator>::value)
+ vector() BOOST_NOEXCEPT_OR_NOTHROW
: m_holder()
{}
@@ -609,14 +730,13 @@ class vector
//! <b>Throws</b>: Nothing
//!
//! <b>Complexity</b>: Constant.
- explicit vector(const Allocator& a) BOOST_CONTAINER_NOEXCEPT
+ explicit vector(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
: m_holder(a)
{}
- //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
- //! and inserts n value initialized values.
+ //! <b>Effects</b>: Constructs a vector and inserts n value initialized values.
//!
- //! <b>Throws</b>: If allocator_type's default constructor or allocation
+ //! <b>Throws</b>: If allocator_type's allocation
//! throws or T's value initialization throws.
//!
//! <b>Complexity</b>: Linear to n.
@@ -633,7 +753,7 @@ class vector
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
//! and inserts n default initialized values.
//!
- //! <b>Throws</b>: If allocator_type's default constructor or allocation
+ //! <b>Throws</b>: If allocator_type's allocation
//! throws or T's default initialization throws.
//!
//! <b>Complexity</b>: Linear to n.
@@ -649,10 +769,46 @@ class vector
(this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
}
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts n value initialized values.
+ //!
+ //! <b>Throws</b>: If allocator_type's allocation
+ //! throws or T's value initialization throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ explicit vector(size_type n, const allocator_type &a)
+ : m_holder(container_detail::uninitialized_size, a, n)
+ {
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ this->num_alloc += n != 0;
+ #endif
+ boost::container::uninitialized_value_init_alloc_n
+ (this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
+ }
+
+ //! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
+ //! and inserts n default initialized values.
+ //!
+ //! <b>Throws</b>: If allocator_type's allocation
+ //! throws or T's default initialization throws.
+ //!
+ //! <b>Complexity</b>: Linear to n.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ vector(size_type n, default_init_t, const allocator_type &a)
+ : m_holder(container_detail::uninitialized_size, a, n)
+ {
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ this->num_alloc += n != 0;
+ #endif
+ boost::container::uninitialized_default_init_alloc_n
+ (this->m_holder.alloc(), n, container_detail::to_raw_pointer(this->m_holder.start()));
+ }
+
//! <b>Effects</b>: Constructs a vector
//! and inserts n copies of value.
//!
- //! <b>Throws</b>: If allocator_type's default constructor or allocation
+ //! <b>Throws</b>: If allocator_type's allocation
//! throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
@@ -686,32 +842,32 @@ class vector
//! <b>Effects</b>: Constructs a vector
//! and inserts a copy of the range [first, last) in the vector.
//!
- //! <b>Throws</b>: If allocator_type's default constructor or allocation
+ //! <b>Throws</b>: If allocator_type's allocation
//! throws or T's constructor taking a dereferenced InIt throws.
//!
//! <b>Complexity</b>: Linear to the range [first, last).
template <class InIt>
vector(InIt first, InIt last)
: m_holder()
- { this->insert(this->cend(), first, last); }
+ { this->assign(first, last); }
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
//! and inserts a copy of the range [first, last) in the vector.
//!
- //! <b>Throws</b>: If allocator_type's default constructor or allocation
+ //! <b>Throws</b>: If allocator_type's allocation
//! throws or T's constructor taking a dereferenced InIt throws.
//!
//! <b>Complexity</b>: Linear to the range [first, last).
template <class InIt>
vector(InIt first, InIt last, const allocator_type& a)
: m_holder(a)
- { this->insert(this->cend(), first, last); }
+ { this->assign(first, last); }
//! <b>Effects</b>: Copy constructs a vector.
//!
//! <b>Postcondition</b>: x == *this.
//!
- //! <b>Throws</b>: If allocator_type's default constructor or allocation
+ //! <b>Throws</b>: If allocator_type's allocation
//! throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to the elements x contains.
@@ -728,30 +884,28 @@ class vector
, x.size(), container_detail::to_raw_pointer(this->m_holder.start()));
}
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
+ //!
+ //! <b>Throws</b>: Nothing
+ //!
+ //! <b>Complexity</b>: Constant.
+ vector(BOOST_RV_REF(vector) x) BOOST_NOEXCEPT_OR_NOTHROW
+ : m_holder(boost::move(x.m_holder))
+ { BOOST_STATIC_ASSERT((!allocator_traits_type::is_partially_propagable::value)); }
+
+ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Constructs a vector that will use a copy of allocator a
//! and inserts a copy of the range [il.begin(), il.last()) in the vector
//!
- //! <b>Throws</b>: If allocator_type's default constructor
- //! throws or T's constructor taking a dereferenced initializer_list iterator throws.
+ //! <b>Throws</b>: If T's constructor taking a dereferenced initializer_list iterator throws.
//!
//! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
vector(std::initializer_list<value_type> il, const allocator_type& a = allocator_type())
: m_holder(a)
{
- insert(cend(), il.begin(), il.end());
+ this->assign(il.begin(), il.end());
}
-#endif
-
-
- //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
- //!
- //! <b>Throws</b>: Nothing
- //!
- //! <b>Complexity</b>: Constant.
- vector(BOOST_RV_REF(vector) x) BOOST_CONTAINER_NOEXCEPT
- : m_holder(boost::move(x.m_holder))
- {}
+ #endif
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -799,17 +953,18 @@ class vector
//!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
vector(BOOST_RV_REF(vector) x, const allocator_type &a)
- : m_holder(container_detail::uninitialized_size, a, x.size())
+ : m_holder( container_detail::uninitialized_size, a
+ , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true) ? 0 : x.size()
+ )
{
- #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- this->num_alloc += x.size() != 0;
- #endif
- if(x.m_holder.alloc() == a){
- this->m_holder.move_from_empty(x.m_holder);
+ if(is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true)){
+ this->m_holder.steal_resources(x.m_holder);
}
else{
const size_type n = x.size();
- this->m_holder.first_allocation_same_allocator_type(n);
+ #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+ this->num_alloc += n != 0;
+ #endif
::boost::container::uninitialized_move_alloc_n_source
( this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start())
, n, container_detail::to_raw_pointer(this->m_holder.start()));
@@ -822,7 +977,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements.
- ~vector() BOOST_CONTAINER_NOEXCEPT
+ ~vector() BOOST_NOEXCEPT_OR_NOTHROW
{
boost::container::destroy_alloc_n
(this->get_stored_allocator(), container_detail::to_raw_pointer(this->m_holder.start()), this->m_holder.m_size);
@@ -845,16 +1000,16 @@ class vector
return *this;
}
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Make *this container contains elements from il.
//!
//! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
vector& operator=(std::initializer_list<value_type> il)
{
- assign(il.begin(), il.end());
+ this->assign(il.begin(), il.end());
return *this;
}
-#endif
+ #endif
//! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
//!
@@ -868,7 +1023,8 @@ class vector
//! propagate_on_container_move_assignment is true or
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
vector& operator=(BOOST_RV_REF(vector) x)
- BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
+ BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
+ || allocator_traits_type::is_always_equal::value)
{
this->priv_move_assign(boost::move(x));
return *this;
@@ -928,10 +1084,10 @@ class vector
//! <b>Complexity</b>: Linear to n.
template <class InIt>
void assign(InIt first, InIt last
- BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I typename container_detail::enable_if_c
- < !container_detail::is_convertible<InIt BOOST_CONTAINER_I size_type>::value &&
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InIt BOOST_MOVE_I size_type>::value &&
( container_detail::is_input_iterator<InIt>::value ||
- container_detail::is_same<alloc_version BOOST_CONTAINER_I allocator_v0>::value )
+ container_detail::is_same<alloc_version BOOST_MOVE_I version_0>::value )
>::type * = 0) )
{
//Overwrite all elements we can from [first, last)
@@ -943,7 +1099,7 @@ class vector
if (first == last){
//There are no more elements in the sequence, erase remaining
- T* const end_pos = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
+ T* const end_pos = this->back_raw();
const size_type n = static_cast<size_type>(end_pos - container_detail::iterator_to_raw_pointer(cur));
this->priv_destroy_last_n(n);
}
@@ -953,7 +1109,7 @@ class vector
}
}
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Effects</b>: Assigns the the range [il.begin(), il.end()) to *this.
//!
//! <b>Throws</b>: If memory allocation throws or
@@ -961,9 +1117,9 @@ class vector
//!
void assign(std::initializer_list<T> il)
{
- assign(il.begin(), il.end());
+ this->assign(il.begin(), il.end());
}
-#endif
+ #endif
//! <b>Effects</b>: Assigns the the range [first, last) to *this.
//!
@@ -973,22 +1129,22 @@ class vector
//! <b>Complexity</b>: Linear to n.
template <class FwdIt>
void assign(FwdIt first, FwdIt last
- BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I typename container_detail::enable_if_c
- < !container_detail::is_convertible<FwdIt BOOST_CONTAINER_I size_type>::value &&
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c
+ < !container_detail::is_convertible<FwdIt BOOST_MOVE_I size_type>::value &&
( !container_detail::is_input_iterator<FwdIt>::value &&
- !container_detail::is_same<alloc_version BOOST_CONTAINER_I allocator_v0>::value )
+ !container_detail::is_same<alloc_version BOOST_MOVE_I version_0>::value )
>::type * = 0)
)
{
//For Fwd iterators the standard only requires EmplaceConstructible and assignable 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 input_sz = static_cast<size_type>(boost::container::iterator_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 = 0;
- std::pair<pointer, bool> ret =
- this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, input_sz, real_cap, this->m_holder.start());
- if(!ret.second){ //New allocation, just emplace new values
+ pointer reuse(this->m_holder.start());
+ pointer const ret(this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, real_cap = input_sz, reuse));
+ if(!reuse){ //New allocation, just emplace new values
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc;
#endif
@@ -997,7 +1153,7 @@ class vector
this->priv_destroy_all();
this->m_holder.alloc().deallocate(old_p, old_capacity);
}
- this->m_holder.start(ret.first);
+ this->m_holder.start(ret);
this->m_holder.capacity(real_cap);
this->m_holder.m_size = 0;
this->priv_uninitialized_construct_at_end(first, last);
@@ -1042,7 +1198,7 @@ class vector
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
- allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+ allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->m_holder.alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1052,7 +1208,7 @@ class vector
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+ stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->m_holder.alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -1062,7 +1218,7 @@ class vector
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
- const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+ const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->m_holder.alloc(); }
//////////////////////////////////////////////
@@ -1076,7 +1232,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator begin() BOOST_CONTAINER_NOEXCEPT
+ iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->m_holder.start()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
@@ -1084,7 +1240,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->m_holder.start()); }
//! <b>Effects</b>: Returns an iterator to the end of the vector.
@@ -1092,7 +1248,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- iterator end() BOOST_CONTAINER_NOEXCEPT
+ iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->m_holder.start() + this->m_holder.m_size); }
//! <b>Effects</b>: Returns a const_iterator to the end of the vector.
@@ -1100,7 +1256,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cend(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -1109,7 +1265,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(this->end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1118,7 +1274,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -1127,7 +1283,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+ reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(this->begin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1136,7 +1292,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crend(); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
@@ -1144,7 +1300,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->m_holder.start()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the vector.
@@ -1152,7 +1308,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+ const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_iterator(this->m_holder.start() + this->m_holder.m_size); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -1161,7 +1317,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->end());}
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -1170,7 +1326,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+ const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->begin()); }
//////////////////////////////////////////////
@@ -1184,7 +1340,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- bool empty() const BOOST_CONTAINER_NOEXCEPT
+ bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return !this->m_holder.m_size; }
//! <b>Effects</b>: Returns the number of the elements contained in the vector.
@@ -1192,7 +1348,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type size() const BOOST_CONTAINER_NOEXCEPT
+ size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->m_holder.m_size; }
//! <b>Effects</b>: Returns the largest possible size of the vector.
@@ -1200,7 +1356,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+ size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return allocator_traits_type::max_size(this->m_holder.alloc()); }
//! <b>Effects</b>: Inserts or erases elements at the end such that
@@ -1238,7 +1394,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+ size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->m_holder.capacity(); }
//! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
@@ -1250,7 +1406,7 @@ class vector
void reserve(size_type new_cap)
{
if (this->capacity() < new_cap){
- this->priv_reserve(new_cap, alloc_version());
+ this->priv_reserve_no_capacity(new_cap, alloc_version());
}
}
@@ -1277,7 +1433,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference front() BOOST_CONTAINER_NOEXCEPT
+ reference front() BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->m_holder.start(); }
//! <b>Requires</b>: !empty()
@@ -1288,7 +1444,7 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference front() const BOOST_CONTAINER_NOEXCEPT
+ const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->m_holder.start(); }
//! <b>Requires</b>: !empty()
@@ -1299,8 +1455,11 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference back() BOOST_CONTAINER_NOEXCEPT
- { return this->m_holder.start()[this->m_holder.m_size - 1]; }
+ reference back() BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->m_holder.m_size > 0);
+ return this->m_holder.start()[this->m_holder.m_size - 1];
+ }
//! <b>Requires</b>: !empty()
//!
@@ -1310,8 +1469,11 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference back() const BOOST_CONTAINER_NOEXCEPT
- { return this->m_holder.start()[this->m_holder.m_size - 1]; }
+ const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->m_holder.m_size > 0);
+ return this->m_holder.start()[this->m_holder.m_size - 1];
+ }
//! <b>Requires</b>: size() > n.
//!
@@ -1321,8 +1483,11 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
- { return this->m_holder.start()[n]; }
+ reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->m_holder.m_size > n);
+ return this->m_holder.start()[n];
+ }
//! <b>Requires</b>: size() > n.
//!
@@ -1332,8 +1497,71 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
- { return this->m_holder.start()[n]; }
+ const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ return this->m_holder.start()[n];
+ }
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns an iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->m_holder.m_size >= n);
+ return iterator(this->m_holder.start()+n);
+ }
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns a const_iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
+ {
+ BOOST_ASSERT(this->m_holder.m_size >= n);
+ return const_iterator(this->m_holder.start()+n);
+ }
+
+ //! <b>Requires</b>: size() >= n.
+ //!
+ //! <b>Effects</b>: Returns an iterator to the nth element
+ //! from the beginning of the container. Returns end()
+ //! if n == size().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->priv_index_of(vector_iterator_get_ptr(p)); }
+
+ //! <b>Requires</b>: begin() <= p <= end().
+ //!
+ //! <b>Effects</b>: Returns the index of the element pointed by p
+ //! and size() if p == end().
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Note</b>: Non-standard extension
+ size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
+ { return this->priv_index_of(vector_iterator_get_ptr(p)); }
//! <b>Requires</b>: size() > n.
//!
@@ -1363,22 +1591,22 @@ class vector
//
//////////////////////////////////////////////
- //! <b>Returns</b>: Allocator pointer such that [data(),data() + size()) is a valid range.
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
//! For a non-empty vector, data() == &front().
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- T* data() BOOST_CONTAINER_NOEXCEPT
+ T* data() BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::to_raw_pointer(this->m_holder.start()); }
- //! <b>Returns</b>: Allocator pointer such that [data(),data() + size()) is a valid range.
+ //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
//! For a non-empty vector, data() == &front().
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- const T * data() const BOOST_CONTAINER_NOEXCEPT
+ const T * data() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::to_raw_pointer(this->m_holder.start()); }
//////////////////////////////////////////////
@@ -1387,7 +1615,7 @@ class vector
//
//////////////////////////////////////////////
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts an object of type T constructed with
//! std::forward<Args>(args)... in the end of the vector.
//!
@@ -1396,19 +1624,38 @@ class vector
//!
//! <b>Complexity</b>: Amortized constant time.
template<class ...Args>
- void emplace_back(Args &&...args)
+ void emplace_back(BOOST_FWD_REF(Args)...args)
{
- if (BOOST_LIKELY(this->m_holder.m_size < this->m_holder.capacity())){
- T* const back_pos = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
+ if (BOOST_LIKELY(this->room_enough())){
//There is more memory, just construct a new object at the end
- allocator_traits_type::construct(this->m_holder.alloc(), back_pos, ::boost::forward<Args>(args)...);
+ allocator_traits_type::construct(this->m_holder.alloc(), this->back_raw(), ::boost::forward<Args>(args)...);
++this->m_holder.m_size;
}
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(::boost::forward<Args>(args)...), alloc_version());
+ (this->back_ptr(), 1, type(::boost::forward<Args>(args)...), alloc_version());
+ }
+ }
+
+ //! <b>Effects</b>: Inserts an object of type T constructed with
+ //! std::forward<Args>(args)... in the end of the vector.
+ //!
+ //! <b>Throws</b>: If the in-place constructor throws.
+ //!
+ //! <b>Complexity</b>: Constant time.
+ //!
+ //! <b>Note</b>: Non-standard extension.
+ template<class ...Args>
+ bool stable_emplace_back(BOOST_FWD_REF(Args)...args)
+ {
+ const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));
+ if (BOOST_LIKELY(is_room_enough)){
+ //There is more memory, just construct a new object at the end
+ allocator_traits_type::construct(this->m_holder.alloc(), this->back_raw(), ::boost::forward<Args>(args)...);
+ ++this->m_holder.m_size;
}
+ return is_room_enough;
}
//! <b>Requires</b>: position must be a valid iterator of *this.
@@ -1422,51 +1669,55 @@ class vector
//! <b>Complexity</b>: If position is end(), amortized constant time
//! Linear time otherwise.
template<class ...Args>
- iterator emplace(const_iterator position, Args && ...args)
+ iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args)
{
//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(::boost::forward<Args>(args)...), alloc_version());
- }
-
- #else
+ , type(::boost::forward<Args>(args)...));
+ }
+
+ #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ #define BOOST_CONTAINER_VECTOR_EMPLACE_CODE(N) \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ void emplace_back(BOOST_MOVE_UREF##N)\
+ {\
+ if (BOOST_LIKELY(this->room_enough())){\
+ allocator_traits_type::construct (this->m_holder.alloc()\
+ , this->back_raw() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ ++this->m_holder.m_size;\
+ }\
+ else{\
+ typedef container_detail::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+ this->priv_forward_range_insert_no_capacity\
+ ( this->back_ptr(), 1, type(BOOST_MOVE_FWD##N), alloc_version());\
+ }\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ bool stable_emplace_back(BOOST_MOVE_UREF##N)\
+ {\
+ const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));\
+ if (BOOST_LIKELY(is_room_enough)){\
+ allocator_traits_type::construct (this->m_holder.alloc()\
+ , this->back_raw() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
+ ++this->m_holder.m_size;\
+ }\
+ return is_room_enough;\
+ }\
+ \
+ BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
+ iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
+ {\
+ typedef container_detail::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
+ return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), 1, type(BOOST_MOVE_FWD##N));\
+ }\
+ //
+ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VECTOR_EMPLACE_CODE)
+ #undef BOOST_CONTAINER_VECTOR_EMPLACE_CODE
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- T* const back_pos = container_detail::to_raw_pointer \
- (this->m_holder.start()) + this->m_holder.m_size; \
- if (BOOST_LIKELY(this->m_holder.m_size < this->m_holder.capacity())){ \
- allocator_traits_type::construct (this->m_holder.alloc() \
- , back_pos BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- ++this->m_holder.m_size; \
- } \
- else{ \
- 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 \
- , type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)), alloc_version()); \
- } \
- } \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- iterator emplace(const_iterator pos \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- typedef 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 \
- , type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)), alloc_version()); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #endif
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//! <b>Effects</b>: Inserts a copy of x at the end of the vector.
@@ -1525,7 +1776,7 @@ class vector
iterator insert(const_iterator p, size_type n, const T& 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());
+ return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy);
}
//! <b>Requires</b>: p must be a valid iterator of *this.
@@ -1537,11 +1788,11 @@ class vector
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws or T's copy/move constructor/assignment throws.
//!
- //! <b>Complexity</b>: Linear to std::distance [first, last).
+ //! <b>Complexity</b>: Linear to boost::container::iterator_distance [first, last).
template <class InIt>
iterator insert(const_iterator pos, InIt first, InIt last
- BOOST_CONTAINER_DOCIGN(BOOST_CONTAINER_I typename container_detail::enable_if_c
- < !container_detail::is_convertible<InIt BOOST_CONTAINER_I size_type>::value
+ BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename container_detail::enable_if_c
+ < !container_detail::is_convertible<InIt BOOST_MOVE_I size_type>::value
&& container_detail::is_input_iterator<InIt>::value
>::type * = 0)
)
@@ -1565,12 +1816,12 @@ class vector
)
{
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());
+ return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), boost::container::iterator_distance(first, last), proxy);
}
#endif
//! <b>Requires</b>: p must be a valid iterator of *this. num, must
- //! be equal to std::distance(first, last)
+ //! be equal to boost::container::iterator_distance(first, last)
//!
//! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
//!
@@ -1579,9 +1830,9 @@ class vector
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
//! dereferenced InpIt throws or T's copy/move constructor/assignment throws.
//!
- //! <b>Complexity</b>: Linear to std::distance [first, last).
+ //! <b>Complexity</b>: Linear to boost::container::iterator_distance [first, last).
//!
- //! <b>Note</b>: This function avoids a linear operation to calculate std::distance[first, last)
+ //! <b>Note</b>: This function avoids a linear operation to calculate boost::container::iterator_distance[first, last)
//! for forward and bidirectional iterators, and a one by one insertion for input iterators. This is a
//! a non-standard extension.
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1589,14 +1840,14 @@ class vector
iterator insert(const_iterator pos, size_type num, InIt first, InIt last)
{
BOOST_ASSERT(container_detail::is_input_iterator<InIt>::value ||
- num == static_cast<size_type>(std::distance(first, last)));
+ num == static_cast<size_type>(boost::container::iterator_distance(first, last)));
(void)last;
container_detail::insert_range_proxy<Allocator, InIt, T*> proxy(first);
- return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy, alloc_version());
+ return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy);
}
#endif
-#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
//! <b>Requires</b>: position must be a valid iterator of *this.
//!
//! <b>Effects</b>: Insert a copy of the [il.begin(), il.end()) range before position.
@@ -1606,16 +1857,16 @@ class vector
//! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
iterator insert(const_iterator position, std::initializer_list<value_type> il)
{
- return insert(position, il.begin(), il.end());
+ return this->insert(position, il.begin(), il.end());
}
-#endif
+ #endif
//! <b>Effects</b>: Removes the last element from the vector.
//!
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant time.
- void pop_back() BOOST_CONTAINER_NOEXCEPT
+ void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
{
//Destroy last element
this->priv_destroy_last();
@@ -1632,7 +1883,7 @@ class vector
const pointer p = vector_iterator_get_ptr(position);
T *const pos_ptr = container_detail::to_raw_pointer(p);
T *const beg_ptr = container_detail::to_raw_pointer(this->m_holder.start());
- T *const new_end_ptr = ::boost::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr);
+ T *const new_end_ptr = ::boost::container::move(pos_ptr + 1, beg_ptr + this->m_holder.m_size, pos_ptr);
//Move elements forward and destroy last
this->priv_destroy_last(pos_ptr == new_end_ptr);
return iterator(p);
@@ -1647,10 +1898,10 @@ class vector
iterator erase(const_iterator first, const_iterator last)
{
if (first != last){
- T* const old_end_ptr = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
+ T* const old_end_ptr = this->back_raw();
T* const first_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(first));
- T* const last_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(last));
- T* const ptr = container_detail::to_raw_pointer(boost::move(last_ptr, old_end_ptr, first_ptr));
+ T* const last_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(last));
+ T* const ptr = container_detail::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr));
this->priv_destroy_last_n(old_end_ptr - ptr, last_ptr == old_end_ptr);
}
return iterator(vector_iterator_get_ptr(first));
@@ -1661,13 +1912,12 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
- void swap(vector& x) BOOST_CONTAINER_NOEXCEPT_IF((!container_detail::is_version<Allocator, 0>::value))
+ void swap(vector& x)
+ BOOST_NOEXCEPT_IF( ((allocator_traits_type::propagate_on_container_swap::value
+ || allocator_traits_type::is_always_equal::value) &&
+ !container_detail::is_version<Allocator, 0>::value))
{
- //Just swap internals in case of !allocator_v0. Otherwise, deep swap
- this->m_holder.swap(x.m_holder);
- //And now the allocator
- container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
- container_detail::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), flag);
+ this->priv_swap(x, container_detail::bool_<container_detail::is_version<Allocator, 0>::value>());
}
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -1685,7 +1935,7 @@ class vector
< container_detail::is_version<OtherAllocator, 0>::value &&
!container_detail::is_same<OtherAllocator, allocator_type>::value >::type * = 0
)
- { this->m_holder.swap(x.m_holder); }
+ { this->m_holder.deep_swap(x.m_holder); }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -1694,28 +1944,14 @@ class vector
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
- void clear() BOOST_CONTAINER_NOEXCEPT
+ void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ this->priv_destroy_all(); }
//! <b>Effects</b>: Returns true if x and y are equal
//!
//! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator==(const vector& x, const vector& y)
- {
- if(x.size() != y.size()){
- return false;
- }
- else{
- const_iterator first1(x.cbegin()), first2(y.cbegin());
- const const_iterator last1(x.cend());
- for (; first1 != last1; ++first1, ++first2) {
- if (!(*first1 != *first2)) {
- return false;
- }
- }
- return true;
- }
- }
+ { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal
//!
@@ -1773,24 +2009,8 @@ class vector
//! <b>Note</b>: Non-standard extension.
bool stable_reserve(size_type new_cap)
{
- const bool room_enough = this->capacity() < new_cap;
- if(!room_enough && alloc_version::value < 2){
- return false;
- }
- else{
- //There is not enough memory, try to expand the old one
- size_type real_cap = 0;
- std::pair<pointer, bool> ret = this->m_holder.allocation_command
- (expand_fwd, new_cap, new_cap, real_cap, this->m_holder.start());
- //Check for forward expansion
- if(ret.second){
- #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
- ++this->num_expand_fwd;
- #endif
- this->m_holder.capacity(real_cap);
- }
- return ret.second;
- }
+ const size_type cp = this->capacity();
+ return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(new_cap - cp));
}
//Absolutely experimental. This function might change, disappear or simply crash!
@@ -1856,50 +2076,23 @@ class vector
}
}
- #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- //! <b>Effects</b>: Inserts an object of type T constructed with
- //! std::forward<Args>(args)... in the end of the vector.
- //!
- //! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
- //! T's copy/move constructor throws.
- //!
- //! <b>Complexity</b>: Amortized constant time.
- template<class ...Args>
- bool stable_emplace_back(Args &&...args)
- {
- const bool room_enough = this->m_holder.m_size < this->m_holder.capacity();
- if (BOOST_LIKELY(room_enough)){
- T* const back_pos = container_detail::to_raw_pointer(this->m_holder.start()) + 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(), back_pos, ::boost::forward<Args>(args)...);
- ++this->m_holder.m_size;
- }
- return room_enough;
- }
+ private:
- #else
+ bool room_enough() const
+ { return this->m_holder.m_size < this->m_holder.capacity(); }
- #define BOOST_PP_LOCAL_MACRO(n) \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- bool stable_emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- const bool room_enough = this->m_holder.m_size < this->m_holder.capacity(); \
- if (BOOST_LIKELY(room_enough)){ \
- T* const back_pos = container_detail::to_raw_pointer \
- (this->m_holder.start()) + this->m_holder.m_size; \
- allocator_traits_type::construct (this->m_holder.alloc() \
- , back_pos BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); \
- ++this->m_holder.m_size; \
- } \
- return room_enough; \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ pointer back_ptr() const
+ { return this->m_holder.start() + this->m_holder.m_size; }
- private:
+ T* back_raw() const
+ { return container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size; }
+
+ size_type priv_index_of(pointer p) const
+ {
+ BOOST_ASSERT(this->m_holder.start() <= p);
+ BOOST_ASSERT(p <= (this->m_holder.start()+this->size()));
+ return static_cast<size_type>(p - this->m_holder.start());
+ }
template<class OtherAllocator>
void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
@@ -1928,25 +2121,32 @@ class vector
BOOST_ASSERT(this != &x);
allocator_type &this_alloc = this->m_holder.alloc();
allocator_type &x_alloc = x.m_holder.alloc();
- const bool propagate_alloc = allocator_traits_type::
- propagate_on_container_move_assignment::value;
- container_detail::bool_<propagate_alloc> flag;
- const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
+ const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value;
+
+ const bool is_propagable_from_x = is_propagable_from(x_alloc, x.m_holder.start(), this_alloc, propagate_alloc);
+ const bool is_propagable_from_t = is_propagable_from(this_alloc, m_holder.start(), x_alloc, propagate_alloc);
+ const bool are_both_propagable = is_propagable_from_x && is_propagable_from_t;
+
//Resources can be transferred if both allocators are
//going to be equal after this function (either propagated or already equal)
- if(propagate_alloc || allocators_equal){
+ if(are_both_propagable){
//Destroy objects but retain memory in case x reuses it in the future
this->clear();
- //Move allocator if needed
- container_detail::move_alloc(this_alloc, x_alloc, flag);
- //Nothrow swap
- this->m_holder.swap(x.m_holder);
+ this->m_holder.swap_resources(x.m_holder);
+ }
+ else if(is_propagable_from_x){
+ this->clear();
+ this->m_holder.alloc().deallocate(this->m_holder.m_start, this->m_holder.m_capacity);
+ this->m_holder.steal_resources(x.m_holder);
}
//Else do a one by one move
else{
- this->assign( boost::make_move_iterator(x.begin())
- , boost::make_move_iterator(x.end()));
+ this->assign( boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.begin()))
+ , boost::make_move_iterator(container_detail::iterator_to_raw_pointer(x.end() ))
+ );
}
+ //Move allocator if needed
+ container_detail::move_alloc(this_alloc, x_alloc, container_detail::bool_<propagate_alloc>());
}
template<class OtherAllocator>
@@ -1985,7 +2185,40 @@ class vector
, container_detail::to_raw_pointer(x.m_holder.start() + x.m_holder.m_size));
}
- void priv_reserve(size_type, allocator_v0)
+ template<class Vector> //Template it to avoid it in explicit instantiations
+ void priv_swap(Vector &x, container_detail::true_type) //version_0
+ { this->m_holder.deep_swap(x.m_holder); }
+
+ template<class Vector> //Template it to avoid it in explicit instantiations
+ void priv_swap(Vector &x, container_detail::false_type) //version_N
+ {
+ const bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value;
+ if(are_swap_propagable( this->get_stored_allocator(), this->m_holder.start()
+ , x.get_stored_allocator(), this->m_holder.start(), propagate_alloc)){
+ //Just swap internals
+ this->m_holder.swap_resources(x.m_holder);
+ }
+ else{
+ //Else swap element by element...
+ bool const t_smaller = this->size() < x.size();
+ vector &sml = t_smaller ? *this : x;
+ vector &big = t_smaller ? x : *this;
+
+ size_type const common_elements = sml.size();
+ for(size_type i = 0; i != common_elements; ++i){
+ boost::adl_move_swap(sml[i], big[i]);
+ }
+ //... and move-insert the remaining range
+ sml.insert( sml.cend()
+ , boost::make_move_iterator(container_detail::iterator_to_raw_pointer(big.nth(common_elements)))
+ , boost::make_move_iterator(container_detail::iterator_to_raw_pointer(big.end()))
+ );
+ }
+ //And now swap the allocator
+ container_detail::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), container_detail::bool_<propagate_alloc>());
+ }
+
+ void priv_reserve_no_capacity(size_type, version_0)
{ throw_bad_alloc(); }
container_detail::insert_range_proxy<Allocator, boost::move_iterator<T*>, T*> priv_dummy_empty_proxy()
@@ -1994,28 +2227,27 @@ class vector
(::boost::make_move_iterator((T *)0));
}
- void priv_reserve(size_type new_cap, allocator_v1)
+ void priv_reserve_no_capacity(size_type new_cap, version_1)
{
//There is not enough memory, allocate a new buffer
- pointer p = this->m_holder.allocate(new_cap);
+ //Pass the hint so that allocators can take advantage of this.
+ pointer const p = allocator_traits_type::allocate(this->m_holder.alloc(), new_cap, this->m_holder.m_start);
//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());
+ ( container_detail::to_raw_pointer(p), new_cap, this->back_raw(), 0, this->priv_dummy_empty_proxy());
}
- void priv_reserve(size_type new_cap, allocator_v2)
+ void priv_reserve_no_capacity(size_type new_cap, version_2)
{
//There is not enough memory, allocate a new
//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());
+ pointer reuse = 0;
+ pointer const ret(this->m_holder.allocation_command(allocate_new | expand_fwd | expand_bwd, new_cap, real_cap = new_cap, reuse));
//Check for forward expansion
- same_buffer_start = ret.second && this->m_holder.start() == ret.first;
+ same_buffer_start = reuse && this->m_holder.start() == ret;
if(same_buffer_start){
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_expand_fwd;
@@ -2023,9 +2255,9 @@ class vector
this->m_holder.capacity(real_cap);
}
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
+ T * const new_mem = container_detail::to_raw_pointer(ret);
+ T * const ins_pos = this->back_raw();
+ if(reuse){ //Backwards (and possibly forward) expansion
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_expand_bwd;
#endif
@@ -2042,26 +2274,26 @@ class vector
}
}
- void priv_destroy_last() BOOST_CONTAINER_NOEXCEPT
+ void priv_destroy_last() BOOST_NOEXCEPT_OR_NOTHROW
{
if(!value_traits::trivial_dctr){
- value_type* const p = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size - 1;
+ value_type* const p = this->back_raw() - 1;
allocator_traits_type::destroy(this->get_stored_allocator(), p);
}
--this->m_holder.m_size;
}
- void priv_destroy_last(const bool moved) BOOST_CONTAINER_NOEXCEPT
+ void priv_destroy_last(const bool moved) BOOST_NOEXCEPT_OR_NOTHROW
{
(void)moved;
if(!(value_traits::trivial_dctr || (value_traits::trivial_dctr_after_move && moved))){
- value_type* const p = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size - 1;
+ value_type* const p = this->back_raw() - 1;
allocator_traits_type::destroy(this->get_stored_allocator(), p);
}
--this->m_holder.m_size;
}
- void priv_destroy_last_n(const size_type n) BOOST_CONTAINER_NOEXCEPT
+ void priv_destroy_last_n(const size_type n) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(n <= this->m_holder.m_size);
if(!value_traits::trivial_dctr){
@@ -2071,7 +2303,7 @@ class vector
this->m_holder.m_size -= n;
}
- void priv_destroy_last_n(const size_type n, const bool moved) BOOST_CONTAINER_NOEXCEPT
+ void priv_destroy_last_n(const size_type n, const bool moved) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(n <= this->m_holder.m_size);
(void)moved;
@@ -2085,12 +2317,12 @@ class vector
template<class InpIt>
void priv_uninitialized_construct_at_end(InpIt first, InpIt last)
{
- T* const old_end_pos = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
+ T* const old_end_pos = this->back_raw();
T* const new_end_pos = boost::container::uninitialized_copy_alloc(this->m_holder.alloc(), first, last, old_end_pos);
this->m_holder.m_size += new_end_pos - old_end_pos;
}
- void priv_destroy_all() BOOST_CONTAINER_NOEXCEPT
+ void priv_destroy_all() BOOST_NOEXCEPT_OR_NOTHROW
{
boost::container::destroy_alloc_n
(this->get_stored_allocator(), container_detail::to_raw_pointer(this->m_holder.start()), this->m_holder.m_size);
@@ -2101,8 +2333,7 @@ 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*, Allocator>
- (::boost::forward<U>(x)), alloc_version());
+ ( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy<T*, Allocator>(::boost::forward<U>(x)));
}
container_detail::insert_copy_proxy<Allocator, T*> priv_single_insert_proxy(const T &x)
@@ -2114,7 +2345,7 @@ class vector
template <class U>
void priv_push_back(BOOST_FWD_REF(U) u)
{
- if (BOOST_LIKELY(this->m_holder.m_size < this->m_holder.capacity())){
+ if (BOOST_LIKELY(this->room_enough())){
//There is more memory, just construct a new object at the end
allocator_traits_type::construct
( this->m_holder.alloc()
@@ -2124,7 +2355,7 @@ class vector
}
else{
this->priv_forward_range_insert_no_capacity
- ( vector_iterator_get_ptr(this->cend()), 1
+ ( this->back_ptr(), 1
, this->priv_single_insert_proxy(::boost::forward<U>(u)), alloc_version());
}
}
@@ -2152,10 +2383,10 @@ class vector
}
}
- void priv_shrink_to_fit(allocator_v0) BOOST_CONTAINER_NOEXCEPT
+ void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW
{}
- void priv_shrink_to_fit(allocator_v1)
+ void priv_shrink_to_fit(version_1)
{
const size_type cp = this->m_holder.capacity();
if(cp){
@@ -2167,7 +2398,8 @@ class vector
}
else if(sz < cp){
//Allocate a new buffer.
- pointer p = this->m_holder.allocate(sz);
+ //Pass the hint so that allocators can take advantage of this.
+ pointer const p = allocator_traits_type::allocate(this->m_holder.alloc(), sz, this->m_holder.m_start);
//We will reuse insert code, so create a dummy input iterator
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
@@ -2181,7 +2413,7 @@ class vector
}
}
- void priv_shrink_to_fit(allocator_v2) BOOST_CONTAINER_NOEXCEPT
+ void priv_shrink_to_fit(version_2) BOOST_NOEXCEPT_OR_NOTHROW
{
const size_type cp = this->m_holder.capacity();
if(cp){
@@ -2192,10 +2424,10 @@ class vector
this->m_holder.m_capacity = 0;
}
else{
- size_type received_size;
+ size_type received_size = sz;
+ pointer reuse(this->m_holder.start());
if(this->m_holder.allocation_command
- ( shrink_in_place | nothrow_allocation
- , cp, sz, received_size, this->m_holder.start()).first){
+ (shrink_in_place | nothrow_allocation, cp, received_size, reuse)){
this->m_holder.capacity(received_size);
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_shrink;
@@ -2207,7 +2439,7 @@ class vector
template <class InsertionProxy>
iterator priv_forward_range_insert_no_capacity
- (const pointer &pos, const size_type, const InsertionProxy , allocator_v0)
+ (const pointer &pos, const size_type, const InsertionProxy , version_0)
{
throw_bad_alloc();
return iterator(pos);
@@ -2215,14 +2447,15 @@ class vector
template <class InsertionProxy>
iterator priv_forward_range_insert_no_capacity
- (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
+ (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_1)
{
//Check if we have enough memory or try to expand current memory
const size_type n_pos = pos - this->m_holder.start();
T *const raw_pos = container_detail::to_raw_pointer(pos);
const size_type new_cap = this->m_holder.next_capacity(n);
- T * new_buf = container_detail::to_raw_pointer(this->m_holder.alloc().allocate(new_cap));
+ //Pass the hint so that allocators can take advantage of this.
+ T * const new_buf = container_detail::to_raw_pointer(allocator_traits_type::allocate(this->m_holder.alloc(), new_cap, this->m_holder.m_start));
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc;
#endif
@@ -2233,23 +2466,23 @@ class vector
template <class InsertionProxy>
iterator priv_forward_range_insert_no_capacity
- (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
+ (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, version_2)
{
//Check if we have enough memory or try to expand current memory
T *const raw_pos = container_detail::to_raw_pointer(pos);
const size_type n_pos = raw_pos - container_detail::to_raw_pointer(this->m_holder.start());
- size_type real_cap = 0;
//There is not enough memory, allocate a new
//buffer or expand the old one.
- std::pair<pointer, bool> ret = (this->m_holder.allocation_command
- (allocate_new | expand_fwd | expand_bwd,
- this->m_holder.m_size + n, this->m_holder.next_capacity(n), real_cap, this->m_holder.start()));
+ size_type real_cap = this->m_holder.next_capacity(n);
+ pointer reuse(this->m_holder.start());
+ pointer const ret (this->m_holder.allocation_command
+ (allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse));
//Buffer reallocated
- if(ret.second){
+ if(reuse){
//Forward expansion, delay insertion
- if(this->m_holder.start() == ret.first){
+ if(this->m_holder.start() == ret){
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_expand_fwd;
#endif
@@ -2263,8 +2496,7 @@ class vector
++this->num_expand_bwd;
#endif
this->priv_forward_range_insert_expand_backwards
- ( container_detail::to_raw_pointer(ret.first)
- , real_cap, raw_pos, n, insert_range_proxy);
+ (container_detail::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
}
}
//New buffer
@@ -2273,8 +2505,7 @@ class vector
++this->num_alloc;
#endif
this->priv_forward_range_insert_new_allocation
- ( container_detail::to_raw_pointer(ret.first)
- , real_cap, raw_pos, n, insert_range_proxy);
+ ( container_detail::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy);
}
return iterator(this->m_holder.start() + n_pos);
@@ -2282,42 +2513,7 @@ class vector
template <class InsertionProxy>
iterator priv_forward_range_insert
- (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v0)
- {
- //Check if we have enough memory or try to expand current memory
- const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
-
- if (n > remaining){
- //This will trigger an error
- throw_bad_alloc();
- }
- const size_type n_pos = pos - this->m_holder.start();
- T *const raw_pos = container_detail::to_raw_pointer(pos);
- this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy);
- return iterator(this->m_holder.start() + n_pos);
- }
-
- template <class InsertionProxy>
- iterator priv_forward_range_insert
- (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
- {
- //Check if we have enough memory or try to expand current memory
- const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
- T *const raw_pos = container_detail::to_raw_pointer(pos);
-
- 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);
- return iterator(this->m_holder.start() + n_pos);
- }
- else{
- return this->priv_forward_range_insert_no_capacity(pos, n, insert_range_proxy, alloc_version());
- }
- }
-
- template <class InsertionProxy>
- iterator priv_forward_range_insert
- (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
+ (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy)
{
BOOST_ASSERT(this->m_holder.capacity() >= this->m_holder.m_size);
//Check if we have enough memory or try to expand current memory
@@ -2338,7 +2534,7 @@ class vector
template <class InsertionProxy>
iterator priv_forward_range_insert_at_end
- (const size_type n, const InsertionProxy insert_range_proxy, allocator_v0)
+ (const size_type n, const InsertionProxy insert_range_proxy, version_0)
{
//Check if we have enough memory or try to expand current memory
const size_type remaining = this->m_holder.capacity() - this->m_holder.m_size;
@@ -2351,18 +2547,11 @@ class vector
return this->end();
}
- template <class InsertionProxy>
- iterator priv_forward_range_insert_at_end
- (const size_type n, const InsertionProxy insert_range_proxy, allocator_v1)
- {
- return this->priv_forward_range_insert(vector_iterator_get_ptr(this->cend()), n, insert_range_proxy, allocator_v1());
- }
-
- template <class InsertionProxy>
+ template <class InsertionProxy, class AllocVersion>
iterator priv_forward_range_insert_at_end
- (const size_type n, const InsertionProxy insert_range_proxy, allocator_v2)
+ (const size_type n, const InsertionProxy insert_range_proxy, AllocVersion)
{
- return this->priv_forward_range_insert(vector_iterator_get_ptr(this->cend()), n, insert_range_proxy, allocator_v2());
+ return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy);
}
//Absolutely experimental. This function might change, disappear or simply crash!
@@ -2386,7 +2575,7 @@ class vector
while(insertions_left){
if(do_skip){
size_type n = *(--last_skip_it);
- std::advance(last_value_it, -difference_type(n));
+ boost::container::iterator_advance(last_value_it, -difference_type(n));
}
const size_type pos = static_cast<size_type>(*(--last_position_it));
BOOST_ASSERT(pos <= old_size_pos);
@@ -2446,7 +2635,7 @@ class vector
//| prefix | range | suffix |raw_mem ~
//|____________|_______|__________________|_____________~
//
- //New situation in Case Allocator (hole_size == 0):
+ //New situation in Case A (hole_size == 0):
// range is moved through move assignments
//
// first_pos last_pos limit_pos
@@ -2493,7 +2682,7 @@ class vector
//Case A:
if((last_pos + shift_count) <= limit_pos){
//All move assigned
- boost::move_backward(first_ptr, last_ptr, last_ptr + shift_count);
+ boost::container::move_backward(first_ptr, last_ptr, last_ptr + shift_count);
}
//Case B:
else if((first_pos + shift_count) >= limit_pos){
@@ -2509,7 +2698,7 @@ class vector
T* const boundary_ptr = limit_ptr - shift_count;
::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), boundary_ptr, last_ptr, limit_ptr);
//The rest is move assigned
- boost::move_backward(first_ptr, boundary_ptr, limit_ptr);
+ boost::container::move_backward(first_ptr, boundary_ptr, limit_ptr);
}
return hole_size;
}
@@ -2518,7 +2707,7 @@ class vector
template <class InsertionProxy>
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;
+ T* const old_finish = this->back_raw();
insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n);
this->m_holder.m_size += n;
}
@@ -2529,7 +2718,7 @@ class vector
//n can't be 0, because there is nothing to do in that case
if(!n) return;
//There is enough memory
- T* const old_finish = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size;
+ T* const old_finish = this->back_raw();
const size_type elems_after = old_finish - pos;
if (!elems_after){
@@ -2543,7 +2732,7 @@ class vector
(this->m_holder.alloc(), old_finish - n, old_finish, old_finish);
this->m_holder.m_size += n;
//Copy previous to last objects to the initialized end
- boost::move_backward(pos, old_finish - n, old_finish);
+ boost::container::move_backward(pos, old_finish - n, old_finish);
//Insert new objects in the pos
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n);
}
@@ -2694,7 +2883,7 @@ class vector
old_values_destroyer.shrink_forward(new_size-s_before);
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);
+ ::boost::container::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();
@@ -2778,14 +2967,14 @@ class vector
}
this->m_holder.m_size = old_size + new_1st_range;
//Now copy the second part of old_begin overwriting itself
- T *const next = ::boost::move(old_start + s_before, pos, old_start);
+ T *const next = ::boost::container::move(old_start + s_before, pos, old_start);
//Now copy the new_beg elements
insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, new_1st_range);
//If there is no after work and the last old part needs to be moved to front, do it
if(!do_after && (n != s_before)){
//Now displace old_end elements
- ::boost::move(pos, old_finish, next + new_1st_range);
+ ::boost::container::move(pos, old_finish, next + new_1st_range);
}
}
else {
@@ -2835,7 +3024,7 @@ class vector
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* const move_end = ::boost::move(pos, old_finish, move_start);
+ T* const move_end = ::boost::container::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;
@@ -2887,7 +3076,7 @@ class vector
(this->m_holder.alloc(), finish_n, old_finish, old_finish);
this->m_holder.m_size += n_after;
//Displace the rest of old_end to the new position
- boost::move_backward(pos, finish_n, old_finish);
+ boost::container::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(this->m_holder.alloc(), pos, n_after);
@@ -2947,35 +3136,23 @@ class vector
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
};
-}}
+}} //namespace boost::container
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace boost {
-/*
//!has_trivial_destructor_after_move<> == true_type
//!specialization for optimizations
template <class T, class Allocator>
struct has_trivial_destructor_after_move<boost::container::vector<T, Allocator> >
- : public ::boost::has_trivial_destructor_after_move<Allocator>
-{};
-*/
-}
-
-//#define BOOST_CONTAINER_PUT_SWAP_OVERLOAD_IN_NAMESPACE_STD
-
-#ifdef BOOST_CONTAINER_PUT_SWAP_OVERLOAD_IN_NAMESPACE_STD
-
-namespace std {
-
-template <class T, class Allocator>
-inline void swap(boost::container::vector<T, Allocator>& x, boost::container::vector<T, Allocator>& y)
-{ x.swap(y); }
-
-} //namespace std {
+{
+ typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
+ static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
+ ::boost::has_trivial_destructor_after_move<pointer>::value;
+};
-#endif
+}
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED