Merge pull request #2 from boostorg/develop

Merged from origin
This commit is contained in:
Tobias Loew
2020-09-02 07:19:22 +02:00
committed by GitHub
85 changed files with 9716 additions and 1039 deletions

288
bench/bench_vectors.cpp Normal file
View File

@@ -0,0 +1,288 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <vector>
#include <deque>
#include <boost/container/vector.hpp>
#include <boost/container/devector.hpp>
#include <boost/container/deque.hpp>
#include <boost/container/small_vector.hpp>
#include <boost/container/stable_vector.hpp>
#include <memory> //std::allocator
#include <iostream> //std::cout, std::endl
#include <cstring> //std::strcmp
#include <boost/timer/timer.hpp>
#include <typeinfo>
//capacity
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME capacity
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace test {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
using boost::timer::cpu_timer;
using boost::timer::cpu_times;
using boost::timer::nanosecond_type;
namespace bc = boost::container;
class MyInt
{
int int_;
public:
BOOST_CONTAINER_FORCEINLINE explicit MyInt(int i = 0)
: int_(i)
{}
BOOST_CONTAINER_FORCEINLINE MyInt(const MyInt &other)
: int_(other.int_)
{}
BOOST_CONTAINER_FORCEINLINE MyInt & operator=(const MyInt &other)
{
int_ = other.int_;
return *this;
}
BOOST_CONTAINER_FORCEINLINE ~MyInt()
{
int_ = 0;
}
};
template<class C, bool = boost::container::test::
has_member_function_callable_with_capacity<C>::value>
struct capacity_wrapper
{
BOOST_CONTAINER_FORCEINLINE static typename C::size_type get_capacity(const C &c)
{ return c.capacity(); }
BOOST_CONTAINER_FORCEINLINE static void set_reserve(C &c, typename C::size_type cp)
{ c.reserve(cp); }
};
template<class C>
struct capacity_wrapper<C, false>
{
BOOST_CONTAINER_FORCEINLINE static typename C::size_type get_capacity(const C &)
{ return 0u; }
BOOST_CONTAINER_FORCEINLINE static void set_reserve(C &, typename C::size_type )
{ }
};
const std::size_t RangeSize = 5;
struct insert_end_range
{
BOOST_CONTAINER_FORCEINLINE std::size_t capacity_multiplier() const
{ return RangeSize; }
template<class C>
BOOST_CONTAINER_FORCEINLINE void operator()(C &c, int)
{ c.insert(c.end(), &a[0], &a[0]+RangeSize); }
const char *name() const
{ return "insert_end_range"; }
MyInt a[RangeSize];
};
struct insert_end_repeated
{
BOOST_CONTAINER_FORCEINLINE std::size_t capacity_multiplier() const
{ return RangeSize; }
template<class C>
BOOST_CONTAINER_FORCEINLINE void operator()(C &c, int i)
{ c.insert(c.end(), RangeSize, MyInt(i)); }
BOOST_CONTAINER_FORCEINLINE const char *name() const
{ return "insert_end_repeated"; }
MyInt a[RangeSize];
};
struct push_back
{
BOOST_CONTAINER_FORCEINLINE std::size_t capacity_multiplier() const
{ return 1; }
template<class C>
BOOST_CONTAINER_FORCEINLINE void operator()(C &c, int i)
{ c.push_back(MyInt(i)); }
BOOST_CONTAINER_FORCEINLINE const char *name() const
{ return "push_back"; }
};
struct insert_near_end_repeated
{
BOOST_CONTAINER_FORCEINLINE std::size_t capacity_multiplier() const
{ return RangeSize; }
template<class C>
BOOST_CONTAINER_FORCEINLINE void operator()(C &c, int i)
{ c.insert(c.size() >= 2*RangeSize ? c.end()-2*RangeSize : c.begin(), RangeSize, MyInt(i)); }
BOOST_CONTAINER_FORCEINLINE const char *name() const
{ return "insert_near_end_repeated"; }
};
struct insert_near_end_range
{
BOOST_CONTAINER_FORCEINLINE std::size_t capacity_multiplier() const
{ return RangeSize; }
template<class C>
BOOST_CONTAINER_FORCEINLINE void operator()(C &c, int)
{
c.insert(c.size() >= 2*RangeSize ? c.end()-2*RangeSize : c.begin(), &a[0], &a[0]+RangeSize);
}
BOOST_CONTAINER_FORCEINLINE const char *name() const
{ return "insert_near_end_range"; }
MyInt a[RangeSize];
};
struct insert_near_end
{
BOOST_CONTAINER_FORCEINLINE std::size_t capacity_multiplier() const
{ return 1; }
template<class C>
BOOST_CONTAINER_FORCEINLINE void operator()(C &c, int i)
{
typedef typename C::iterator it_t;
it_t it (c.end());
it -= static_cast<typename C::size_type>(c.size() >= 2)*2;
c.insert(it, MyInt(i));
}
BOOST_CONTAINER_FORCEINLINE const char *name() const
{ return "insert_near_end"; }
};
template<class Container, class Operation>
void vector_test_template(std::size_t num_iterations, std::size_t num_elements, const char *cont_name)
{
typedef capacity_wrapper<Container> cpw_t;
Container c;
cpw_t::set_reserve(c, num_elements);
Operation op;
const typename Container::size_type multiplier = op.capacity_multiplier();
//Warm-up operation
for(std::size_t e = 0, max = num_elements/multiplier; e != max; ++e){
op(c, static_cast<int>(e));
}
c.clear();
cpu_timer timer;
const std::size_t max = num_elements/multiplier;
for(std::size_t r = 0; r != num_iterations; ++r){
//Unrolll the loop to avoid noise from loop code
int i = 0;
timer.resume();
for(std::size_t e = 0; e < max/16; ++e){
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
op(c, static_cast<int>(i++));
}
timer.stop();
c.clear();
}
timer.stop();
std::size_t capacity = cpw_t::get_capacity(c);
nanosecond_type nseconds = timer.elapsed().wall;
std::cout << cont_name << "->" << op.name() <<" ns: "
<< float(nseconds)/(num_iterations*num_elements)
<< '\t'
<< "Capacity: " << capacity
<< "\n";
}
template<class Operation>
void test_vectors()
{
//#define SINGLE_TEST
#define SIMPLE_IT
#ifdef SINGLE_TEST
#ifdef NDEBUG
std::size_t numit [] = { 100 };
#else
std::size_t numit [] = { 20 };
#endif
std::size_t numele [] = { 10000 };
#elif defined SIMPLE_IT
std::size_t numit [] = { 100 };
std::size_t numele [] = { 10000 };
#else
#ifdef NDEBUG
unsigned int numit [] = { 1000, 10000, 100000, 1000000 };
#else
unsigned int numit [] = { 100, 1000, 10000, 100000 };
#endif
unsigned int numele [] = { 10000, 1000, 100, 10 };
#endif
for(unsigned int i = 0; i < sizeof(numele)/sizeof(numele[0]); ++i){
vector_test_template< std::vector<MyInt, std::allocator<MyInt> >, Operation >(numit[i], numele[i] , "std::vector ");
vector_test_template< bc::vector<MyInt, std::allocator<MyInt> >, Operation >(numit[i], numele[i] , "vector ");
vector_test_template< bc::devector<MyInt, std::allocator<MyInt> >, Operation >(numit[i], numele[i] , "devector ");
vector_test_template< bc::small_vector<MyInt, 0, std::allocator<MyInt> >, Operation >(numit[i], numele[i] , "small_vector ");
vector_test_template< std::deque<MyInt, std::allocator<MyInt> >, Operation >(numit[i], numele[i] , "std::deque ");
vector_test_template< bc::deque<MyInt, std::allocator<MyInt> >, Operation >(numit[i], numele[i] , "deque ");
}
std::cout << "---------------------------------\n---------------------------------\n";
}
int main()
{
//end
test_vectors<push_back>();
test_vectors<insert_end_range>();
test_vectors<insert_end_repeated>();
//near end
test_vectors<insert_near_end>();
test_vectors<insert_near_end_range>();
test_vectors<insert_near_end_repeated>();
return 0;
}

View File

@@ -47,12 +47,14 @@ In short, what does [*Boost.Container] offer?
searches.
* [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid
container: vector-like random-access iterators and list-like iterator stability in insertions and erasures.
* [classref boost::container::static_vector static_vector ]: a vector-like container that internally embeds
* [classref boost::container::static_vector static_vector]: a vector-like container that internally embeds
(statically allocates) all needed memory up to the maximum capacity. Maximum capacity can't be increased and
it's specified at compile time.
* [classref boost::container::small_vector small_vector ]: a vector-like container that internally embeds
* [classref boost::container::small_vector small_vector]: a vector-like container that internally embeds
(statically allocates) a minimum amount of memory, but dynamically allocates elements when capacity
has to be increased. This minimum capacity is specified at compile time.
* [classref boost::container::devector devector]: is a hybrid of the standard vector and deque containers.
It offers cheap (amortized constant time) insertion at both the front and back ends.
* [classref boost::container::slist slist]: the classic pre-standard singly linked list implementation
offering constant-time `size()`. Note that C++11 `forward_list` has no `size()`.
@@ -73,12 +75,10 @@ instructions, that's already been done for you.
[section:tested_compilers Tested compilers]
[*Boost.Container] requires a decent C++98 compatibility. Some compilers known to work are:
[*Boost.Container] requires a decent C++03 compatibility. Some compilers known to work are:
* Visual C++ >= 7.1.
* GCC >= 4.1.
[warning GCC < 4.3 and MSVC < 9.0 are deprecated and will be removed in the next version.]
* Visual C++ >= 10.0
* GCC >= 4.8
[endsect]
@@ -168,7 +168,7 @@ is used as a template argument when instantiating a template component,
unless specifically allowed for that component]].
Finally C++17 added support for incomplete types in `std::vector`, `std::list` and `std::forward_list`
(see [@https://wg21.link/n4569 ['N4569: Minimal incomplete type support for standard containers, revision 4]]
(see [@https://wg21.link/n4510 ['N4510: Minimal incomplete type support for standard containers, revision 4]]
for details), but no other containers like `std::set/map/unordered_set/unordered_map`,
Fortunately all [*Boost.Container] containers except
@@ -460,6 +460,21 @@ erasure times considerably. Flat associative containers have the following attri
[endsect]
[section:devector ['devector]]
`devector` is a hybrid of the standard vector and deque containers originally written by Thaler Benedek.
It offers cheap (amortized constant time) insertion at both the front and back ends,
while also providing the regular features of `vector`, in particular the contiguous underlying memory.
Unlike `vector`, devector can have free capacity both before and after the elements. This enables efficient
implementation of methods that modify the devector at the front. In general, `devector`'s available methods
are a superset of those of `vector` with identical behaviour, barring a couple of iterator invalidation
guarantees that differ.
The overhead for devector is one extra `size_t` per container: Usually sizeof(devector) == 4*sizeof(T*).
[endsect]
[section:slist ['slist]]
When the standard template library was designed, it contained a singly linked list called `slist`.
@@ -1308,6 +1323,10 @@ use [*Boost.Container]? There are several reasons for that:
* `static_vector` was based on Andrew Hundt's and Adam Wulkiewicz's high-performance `varray` class.
Many performance improvements of `vector` were also inspired by their implementation. Thanks!
* `devector` is based on Thaler Benedek's high-performance `devector` implementation, then
adapted for [*Boost.Container]. Also inspired by similar implemenations by Orson Peters and Lars Hagen.
Thanks for such a great code and documentation!
* Howard Hinnant's help and advices were essential when implementing move semantics,
improving allocator support or implementing small string optimization. Thanks Howard
for your wonderful standard library implementations.
@@ -1319,6 +1338,45 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes Release Notes]
[section:release_notes_boost_1_75_00 Boost 1.75 Release]
* New [classref boost::container::devector devector] container.
* Fixed bugs/issues:
* [@https://github.com/boostorg/container/pull/157 GitHub #157: ['"Add missing include"]].
* [@https://github.com/boostorg/container/issues/160 GitHub #160: ['"Usage of uses_allocator needs a remove_cvref_t"]].
* [@https://github.com/boostorg/container/issues/161 GitHub #161: ['"polymorphic_allocator(memory_resource*) non-standard extension causes headache"]].
[endsect]
[section:release_notes_boost_1_74_00 Boost 1.74 Release]
* Fixed bugs/issues:
* [@https://github.com/boostorg/container/issues/125 GitHub #125: ['"flat_map doc misleading complexity"]].
* [@https://github.com/boostorg/container/issues/126 GitHub #126: ['"flat_set.hpp and set.hpp in pmr have the same header guard"]].
* [@https://github.com/boostorg/container/issues/128 GitHub #128: ['"moved from small_vector and static_vector calls destructor on elements in static part"]].
* [@https://github.com/boostorg/container/issues/129 GitHub #129: ['"Alias templates for small_flat_[multi]{set|map} using small_vector as container"]].
* [@https://github.com/boostorg/container/pull/135 GitHub #135: ['"Missing BOOST_NORETURN for user defined functions"]].
* [@https://github.com/boostorg/container/pull/137 GitHub #137: ['"RandomAccessIterator + 0"]].
* [@https://github.com/boostorg/container/pull/138 GitHub #138: ['"Remove Classes from Global Namespace"]].
* [@https://github.com/boostorg/container/issues/142 GitHub #142: ['"memset called with null pointer"]].
* [@https://github.com/boostorg/container/issues/144 GitHub #144: ['"GCC suggest-override warnings"]].
* [@https://github.com/boostorg/container/issues/145 GitHub #145: ['"Allocations not handled correctly in some cases of vector move with unequal allocators"]].
* [@https://github.com/boostorg/container/pull/146 GitHub #146: ['"Changes for Embarcadero C++ clang-based compilers, targeting Boost 1.74. Addition needed for Embarcardero clang-based compilers"]].
* [@https://github.com/boostorg/container/pull/148 GitHub #148: ['"Fix static initialization issues in pmr global resources"]].
* [@https://github.com/boostorg/container/pull/149 GitHub #149: ['"InitializeCriticalSectionEx returns "BOOL" (int)"]].
* [@https://github.com/boostorg/container/issues/151 GitHub #151: ['"Buffer overflow in monotonic_buffer_resource::do_allocate"]].
[endsect]
[section:release_notes_boost_1_72_00 Boost 1.72 Release]
* Fixed bugs:
* [@https://github.com/boostorg/container/issues/127 GitHub #127: ['"Fix docs for static_vector::max_size() and capacity()"]].
* [@https://github.com/boostorg/container/issues/132 GitHub #132: ['"flat_map::lower_bound and upper_bound have wrong/misleading docs"]].
* [@https://github.com/boostorg/container/issues/133 GitHub #133: ['"basic_string move constructor with allocator argument has incorrect allocator check"]].
[endsect]
[section:release_notes_boost_1_71_00 Boost 1.71 Release]
* Fixed bugs:
@@ -1341,7 +1399,7 @@ use [*Boost.Container]? There are several reasons for that:
* [classref boost::container::static_vector static_vector] can now have options, using [classref boost::container::static_vector_options static_vector_options].
Alignment and throwing behaviour can be be specified.
* [classref boost::container::small_vector small_vector] can now have options, using [classref boost::container::small_vector_options small_vector_options].
* [classref boost::container::small_vector small_vector] can now have options, using [classref boost::container::small_vector_options small_vector_options].
Alignment and growth factor can be be specified.
[endsect]

View File

@@ -132,6 +132,10 @@ class adaptive_pool
adaptive_pool(const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Copy assignment from other adaptive_pool.
adaptive_pool & operator=(const adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{ return *this; }
//!Copy constructor from related adaptive_pool.
template<class T2>
adaptive_pool
@@ -251,7 +255,7 @@ class adaptive_pool
BOOST_STATIC_ASSERT(( Version > 1 ));/*
dlmalloc_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after(chain.before_begin()
@@ -259,7 +263,7 @@ class adaptive_pool
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes
(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
boost::container::throw_bad_alloc();
}
}
@@ -271,7 +275,7 @@ class adaptive_pool
BOOST_STATIC_ASSERT(( Version > 1 ));/*
dlmalloc_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after(chain.before_begin()
@@ -279,7 +283,7 @@ class adaptive_pool
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );*/
if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays
(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
boost::container::throw_bad_alloc();
}
}
@@ -442,6 +446,10 @@ class private_adaptive_pool
private_adaptive_pool(const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{}
//!Copy assignment from other adaptive_pool.
private_adaptive_pool & operator=(const private_adaptive_pool &) BOOST_NOEXCEPT_OR_NOTHROW
{ return *this; }
//!Copy constructor from related private_adaptive_pool.
template<class T2>
private_adaptive_pool
@@ -536,7 +544,7 @@ class private_adaptive_pool
{
BOOST_STATIC_ASSERT(( Version > 1 ));
if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes
(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
boost::container::throw_bad_alloc();
}
}
@@ -547,7 +555,7 @@ class private_adaptive_pool
{
BOOST_STATIC_ASSERT(( Version > 1 ));
if(BOOST_UNLIKELY(!dlmalloc_multialloc_arrays
(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain)))){
boost::container::throw_bad_alloc();
}
}

View File

@@ -287,7 +287,7 @@ class allocator
BOOST_STATIC_ASSERT(( Version > 1 ));
dlmalloc_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
if(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
if(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
boost::container::throw_bad_alloc();
}
chain.incorporate_after(chain.before_begin()
@@ -295,7 +295,7 @@ class allocator
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );
/*
if(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain))){
if(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain))){
boost::container::throw_bad_alloc();
}*/
}
@@ -308,7 +308,7 @@ class allocator
BOOST_STATIC_ASSERT(( Version > 1 ));
dlmalloc_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
if(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
if(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch)){
boost::container::throw_bad_alloc();
}
chain.incorporate_after(chain.before_begin()
@@ -316,7 +316,7 @@ class allocator
,(T*)BOOST_CONTAINER_MEMCHAIN_LASTMEM(&ch)
,BOOST_CONTAINER_MEMCHAIN_SIZE(&ch) );
/*
if(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain))){
if(!dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, reinterpret_cast<dlmalloc_memchain *>(&chain))){
boost::container::throw_bad_alloc();
}*/
}

View File

@@ -26,6 +26,7 @@
//! - boost::container::static_vector
//! - boost::container::small_vector_base
//! - boost::container::small_vector
//! - boost::container::devector
//! - boost::container::slist
//! - boost::container::list
//! - boost::container::set
@@ -122,6 +123,11 @@ template < class T
, class Options = void >
class small_vector;
template <class T
,class Allocator = void
,class Options = void>
class devector;
template <class T
,class Allocator = void
,class Options = void>
@@ -220,6 +226,52 @@ using small_flat_multimap = flat_multimap<Key, T, Compare, small_vector<std::pai
#endif // #ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
//! A portable metafunction to obtain a small_flat_set
template < class Key
, std::size_t N
, class Compare = std::less<Key>
, class SmallVectorAllocator = void
, class SmallVectorOptions = void >
struct small_flat_set_of
{
typedef flat_set<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions> > type;
};
//! A portable metafunction to obtain a small_flat_multiset
template < class Key
, std::size_t N
, class Compare = std::less<Key>
, class SmallVectorAllocator = void
, class SmallVectorOptions = void >
struct small_flat_multiset_of
{
typedef flat_multiset<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions> > type;
};
//! A portable metafunction to obtain a small_flat_map
template < class Key
, class T
, std::size_t N
, class Compare = std::less<Key>
, class SmallVectorAllocator = void
, class SmallVectorOptions = void >
struct small_flat_map_of
{
typedef flat_map<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions> > type;
};
//! A portable metafunction to obtain a small_flat_multimap
template < class Key
, class T
, std::size_t N
, class Compare = std::less<Key>
, class SmallVectorAllocator = void
, class SmallVectorOptions = void >
struct small_flat_multimap_of
{
typedef flat_multimap<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions> > type;
};
template <class CharT
,class Traits = std::char_traits<CharT>
,class Allocator = void >

View File

@@ -234,6 +234,8 @@ class deque_iterator
deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
{
if (!n)
return *this;
BOOST_ASSERT(!!m_cur);
difference_type offset = n + (this->m_cur - this->m_first);
const difference_type block_size = this->m_last - this->m_first;

View File

@@ -49,17 +49,17 @@ struct move_insert_range_proxy
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)
BOOST_CONTAINER_FORCEINLINE explicit move_insert_range_proxy(FwdIt first)
: first_(first)
{}
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
BOOST_CONTAINER_FORCEINLINE 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(Allocator &, Iterator p, size_type n)
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n)
{
this->first_ = ::boost::container::move_n_source(this->first_, n, p);
}
@@ -74,16 +74,16 @@ struct insert_range_proxy
typedef typename allocator_traits<Allocator>::size_type size_type;
typedef typename allocator_traits<Allocator>::value_type value_type;
explicit insert_range_proxy(FwdIt first)
BOOST_CONTAINER_FORCEINLINE explicit insert_range_proxy(FwdIt first)
: first_(first)
{}
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
BOOST_CONTAINER_FORCEINLINE 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(Allocator &, Iterator p, size_type n)
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n)
{
this->first_ = ::boost::container::copy_n_source(this->first_, n, p);
}
@@ -98,17 +98,19 @@ struct insert_n_copies_proxy
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)
BOOST_CONTAINER_FORCEINLINE explicit insert_n_copies_proxy(const value_type &v)
: v_(v)
{}
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
BOOST_CONTAINER_FORCEINLINE 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(Allocator &, Iterator p, size_type n) const
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const
{
for (; 0 < n; --n, ++p){
while (n){
--n;
*p = v_;
++p;
}
}
@@ -121,18 +123,21 @@ struct insert_value_initialized_n_proxy
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;
typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t;
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
BOOST_CONTAINER_FORCEINLINE 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(Allocator &a, Iterator p, size_type n) const
{
for (; 0 < n; --n, ++p){
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
while (n){
--n;
storage_t v;
value_type *vp = reinterpret_cast<value_type *>(v.data);
alloc_traits::construct(a, vp);
value_destructor<Allocator> on_exit(a, *vp); (void)on_exit;
*p = ::boost::move(*vp);
++p;
}
}
};
@@ -143,19 +148,22 @@ struct insert_default_initialized_n_proxy
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;
typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t;
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
BOOST_CONTAINER_FORCEINLINE 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(Allocator &a, Iterator p, size_type n) const
{
if(!is_pod<value_type>::value){
for (; 0 < n; --n, ++p){
while (n){
--n;
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
value_type *vp = reinterpret_cast<value_type *>(v.data);
alloc_traits::construct(a, vp, default_init);
value_destructor<Allocator> on_exit(a, *vp); (void)on_exit;
*p = ::boost::move(*vp);
++p;
}
}
}
@@ -168,17 +176,19 @@ struct insert_copy_proxy
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
explicit insert_copy_proxy(const value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_copy_proxy(const value_type &v)
: v_(v)
{}
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_);
}
void copy_n_and_update(Allocator &, Iterator p, size_type n) const
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const
{
BOOST_ASSERT(n == 1); (void)n;
*p = v_;
@@ -195,6 +205,8 @@ struct insert_move_proxy
typedef typename alloc_traits::size_type size_type;
typedef typename alloc_traits::value_type value_type;
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_move_proxy(value_type &v)
: v_(v)
{}
@@ -215,13 +227,13 @@ struct insert_move_proxy
};
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)
BOOST_CONTAINER_FORCEINLINE 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<Allocator, It>(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)
BOOST_CONTAINER_FORCEINLINE insert_copy_proxy<Allocator, It> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v)
{
return insert_copy_proxy<Allocator, It>(v);
}
@@ -243,19 +255,20 @@ struct insert_nonmovable_emplace_proxy
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_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args)
: args_(args...)
{}
void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)
BOOST_CONTAINER_FORCEINLINE 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<std::size_t ...IdxPack>
void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
BOOST_CONTAINER_FORCEINLINE 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, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... );
@@ -275,23 +288,24 @@ struct insert_emplace_proxy
typedef typename base_t::size_type size_type;
typedef typename base_t::index_tuple_t index_tuple_t;
explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args)
: base_t(::boost::forward<Args>(args)...)
{}
void copy_n_and_update(Allocator &a, Iterator p, size_type n)
BOOST_CONTAINER_FORCEINLINE 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<std::size_t ...IdxPack>
void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
BOOST_CONTAINER_FORCEINLINE void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, size_type n)
{
BOOST_ASSERT(n ==1); (void)n;
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;
value_type *vp = reinterpret_cast<value_type *>(v.data);
alloc_traits::construct(a, vp,
::boost::forward<Args>(get<IdxPack>(this->args_))...);
alloc_traits::construct(a, vp, ::boost::forward<Args>(get<IdxPack>(this->args_))...);
BOOST_TRY{
*p = ::boost::move(*vp);
}
@@ -309,7 +323,9 @@ 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<Allocator>::value_type &&v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v)
: insert_move_proxy<Allocator, Iterator>(v)
{}
};
@@ -323,7 +339,10 @@ struct insert_emplace_proxy<Allocator, Iterator
>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -332,7 +351,9 @@ 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<Allocator>::value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -343,7 +364,9 @@ struct insert_emplace_proxy<Allocator, Iterator
>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -366,16 +389,18 @@ struct insert_nonmovable_emplace_proxy##N\
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)\
static const bool single_value = true;\
\
BOOST_CONTAINER_FORCEINLINE 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_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\
{\
BOOST_ASSERT(n == 1); (void)n;\
alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\
}\
\
void copy_n_and_update(Allocator &, Iterator, size_type)\
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator, size_type)\
{ BOOST_ASSERT(false); }\
\
protected:\
@@ -392,10 +417,12 @@ struct insert_emplace_proxy_arg##N\
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)\
static const bool single_value = true;\
\
BOOST_CONTAINER_FORCEINLINE 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_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, size_type n)\
{\
BOOST_ASSERT(n == 1); (void)n;\
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\
@@ -424,7 +451,9 @@ 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<Allocator>::value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_move_proxy<Allocator, Iterator>(v)
{}
};
@@ -433,7 +462,9 @@ 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<Allocator>::value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -445,7 +476,9 @@ 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<Allocator>::value_type &&v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v)
: insert_move_proxy<Allocator, Iterator>(v)
{}
};
@@ -459,7 +492,9 @@ struct insert_emplace_proxy_arg1<Allocator, Iterator
>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -468,7 +503,9 @@ 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<Allocator>::value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -479,7 +516,9 @@ struct insert_emplace_proxy_arg1<Allocator, Iterator
>
: public insert_copy_proxy<Allocator, Iterator>
{
explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
static const bool single_value = true;
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v)
: insert_copy_proxy<Allocator, Iterator>(v)
{}
};
@@ -490,6 +529,40 @@ struct insert_emplace_proxy_arg1<Allocator, Iterator
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
namespace boost { namespace container { namespace dtl {
template <class T>
struct has_single_value
{
private:
struct two {char array_[2];};
template<bool Arg> struct wrapper;
template <class U> static two test(int, ...);
template <class U> static char test(int, const wrapper<U::single_value>*);
public:
static const bool value = sizeof(test<T>(0, 0)) == 1;
void dummy(){}
};
template<class InsertionProxy, bool = has_single_value<InsertionProxy>::value>
struct is_single_value_proxy_impl
{
static const bool value = InsertionProxy::single_value;
};
template<class InsertionProxy>
struct is_single_value_proxy_impl<InsertionProxy, false>
{
static const bool value = false;
};
template<class InsertionProxy>
struct is_single_value_proxy
: is_single_value_proxy_impl<InsertionProxy>
{};
}}} //namespace boost { namespace container { namespace dtl {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP

View File

@@ -27,30 +27,30 @@ namespace container {
namespace dtl {
template<class AllocatorType>
inline void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type)
BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type)
BOOST_NOEXCEPT_OR_NOTHROW
{}
template<class AllocatorType>
inline void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type)
BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type)
{ boost::adl_move_swap(l, r); }
template<class AllocatorType>
inline void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type)
BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type)
BOOST_NOEXCEPT_OR_NOTHROW
{}
template<class AllocatorType>
inline void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type)
BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type)
{ l = r; }
template<class AllocatorType>
inline void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type)
BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type)
BOOST_NOEXCEPT_OR_NOTHROW
{}
template<class AllocatorType>
inline void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type)
BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type)
{ l = ::boost::move(r); }
} //namespace dtl {

View File

@@ -196,11 +196,11 @@ typedef struct boost_cont_memchain_impl
/*!Indicates the all elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
must be contiguous.*/
#define DL_MULTIALLOC_ALL_CONTIGUOUS ((size_t)(-1))
#define BOOST_CONTAINER_DL_MULTIALLOC_ALL_CONTIGUOUS ((size_t)(-1))
/*!Indicates the number of contiguous elements allocated by boost_cont_multialloc_nodes or boost_cont_multialloc_arrays
should be selected by those functions.*/
#define DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0))
#define BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS ((size_t)(0))
typedef struct boost_cont_malloc_stats_impl
{
@@ -225,8 +225,8 @@ enum
BOOST_CONTAINER_EXPAND_OR_NEW = BOOST_CONTAINER_ALLOCATE_NEW | BOOST_CONTAINER_EXPAND_BOTH
};
//#define BOOST_CONTAINERDLMALLOC__FOOTERS
#ifndef BOOST_CONTAINERDLMALLOC__FOOTERS
//#define BOOST_CONTAINER_DLMALLOC_FOOTERS
#ifndef BOOST_CONTAINER_DLMALLOC_FOOTERS
enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t) };
#else
enum { BOOST_CONTAINER_ALLOCATION_PAYLOAD = sizeof(size_t)*2 };

View File

@@ -20,6 +20,7 @@
#endif
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/container/detail/workaround.hpp>
namespace boost {
namespace container {

View File

@@ -20,9 +20,7 @@
#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 : 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 : 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
@@ -42,7 +40,6 @@
#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 : 4714) // "function": marked as __forceinline not inlined

View File

@@ -171,7 +171,7 @@ struct disable_if_memtransfer_copy_assignable
template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
value_type *const dest_raw = boost::movelib::iterator_to_raw_pointer(r);
@@ -189,7 +189,7 @@ template
<typename I, // I models InputIterator
typename U, // U models unsigned integral constant
typename F> // F models ForwardIterator
F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
if(BOOST_LIKELY(n)){
@@ -204,7 +204,7 @@ template
<typename I, // I models InputIterator
typename U, // U models unsigned integral constant
typename F> // F models ForwardIterator
I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{
if(BOOST_LIKELY(n)){
typedef typename boost::container::iterator_traits<I>::value_type value_type;
@@ -218,7 +218,7 @@ template
<typename I, // I models InputIterator
typename U, // U models unsigned integral constant
typename F> // F models ForwardIterator
I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
{
typedef typename boost::container::iterator_traits<I>::value_type value_type;
if(BOOST_LIKELY(n)){
@@ -315,7 +315,7 @@ template
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove(f, l, r); }
@@ -341,7 +341,8 @@ inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, F>::type
{
F back = r;
BOOST_TRY{
while (n--) {
while (n) {
--n;
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
@@ -360,7 +361,7 @@ template
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n(f, n, r); }
@@ -386,7 +387,8 @@ inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, I>::type
{
F back = r;
BOOST_TRY{
while (n--) {
while (n) {
--n;
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f));
++f; ++r;
}
@@ -405,7 +407,7 @@ template
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type
uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n_source(f, n, r); }
@@ -450,7 +452,7 @@ template
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove(f, l, r); }
@@ -476,7 +478,8 @@ inline typename dtl::disable_if_memtransfer_copy_constructible<I, F, F>::type
{
F back = r;
BOOST_TRY{
while (n--) {
while (n) {
--n;
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f);
++f; ++r;
}
@@ -495,7 +498,7 @@ template
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, F>::type
uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n(f, n, r); }
@@ -540,7 +543,7 @@ template
<typename Allocator,
typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible<I, F, I>::type
uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits<Allocator>::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n_source(f, n, r); }
@@ -565,7 +568,8 @@ inline typename dtl::disable_if_memzero_initializable<F, F>::type
{
F back = r;
BOOST_TRY{
while (n--) {
while (n) {
--n;
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r));
++r;
}
@@ -583,12 +587,14 @@ inline typename dtl::disable_if_memzero_initializable<F, F>::type
template
<typename Allocator,
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memzero_initializable<F, F>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memzero_initializable<F, F>::type
uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits<Allocator>::size_type n, F r)
{
typedef typename boost::container::iterator_traits<F>::value_type value_type;
std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
boost::container::iterator_advance(r, n);
if (BOOST_LIKELY(n)){
std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n);
boost::container::iterator_advance(r, n);
}
return r;
}
@@ -612,7 +618,8 @@ inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::contai
{
F back = r;
BOOST_TRY{
while (n--) {
while (n) {
--n;
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init);
++r;
}
@@ -684,7 +691,8 @@ inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::co
{
F back = r;
BOOST_TRY{
while (n--) {
while (n) {
--n;
allocator_traits<Allocator>::construct(a, boost::movelib::iterator_to_raw_pointer(r), v);
++r;
}
@@ -750,7 +758,7 @@ template
<typename I, // I models InputIterator
typename U, // U models unsigned integral constant
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
copy_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n(f, n, r); }
@@ -767,7 +775,8 @@ typename F> // F models ForwardIterator
inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type
copy_n_source(I f, U n, F r)
{
while (n--) {
while (n) {
--n;
boost::container::assign_in_place(r, f);
++f; ++r;
}
@@ -778,7 +787,7 @@ template
<typename I, // I models InputIterator
typename U, // U models unsigned integral constant
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
copy_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n_source(f, n, r); }
@@ -795,7 +804,8 @@ typename F> // F models ForwardIterator
inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type
copy_n_source_dest(I f, U n, F &r)
{
while (n--) {
while (n) {
--n;
*r = *f;
++f; ++r;
}
@@ -806,7 +816,7 @@ template
<typename I, // I models InputIterator
typename U, // U models unsigned integral constant
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
copy_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n_source_dest(f, n, r); }
@@ -849,7 +859,8 @@ typename F> // F models ForwardIterator
inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type
move_n(I f, U n, F r)
{
while (n--) {
while (n) {
--n;
*r = ::boost::move(*f);
++f; ++r;
}
@@ -860,7 +871,7 @@ template
<typename I, // I models InputIterator
typename U, // U models unsigned integral constant
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
move_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n(f, n, r); }
@@ -887,13 +898,15 @@ inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, F>::type
template
<typename I, // I models InputIterator
typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, F>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::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((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
if (BOOST_LIKELY(n)){
r -= n;
std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n);
}
return r;
}
@@ -910,7 +923,8 @@ template
inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type
move_n_source_dest(I f, U n, F &r)
{
while (n--) {
while (n) {
--n;
*r = ::boost::move(*f);
++f; ++r;
}
@@ -921,7 +935,7 @@ template
<typename I // I models InputIterator
,typename U // U models unsigned integral constant
,typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
move_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n_source_dest(f, n, r); }
@@ -938,7 +952,8 @@ template
inline typename dtl::disable_if_memtransfer_copy_assignable<I, F, I>::type
move_n_source(I f, U n, F r)
{
while (n--) {
while (n) {
--n;
*r = ::boost::move(*f);
++f; ++r;
}
@@ -949,7 +964,7 @@ template
<typename I // I models InputIterator
,typename U // U models unsigned integral constant
,typename F> // F models ForwardIterator
inline typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable<I, F, I>::type
move_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW
{ return dtl::memmove_n_source(f, n, r); }
@@ -977,7 +992,7 @@ template
<typename Allocator
,typename I // I models InputIterator
,typename U> // U models unsigned integral constant
inline typename dtl::enable_if_trivially_destructible<I, void>::type
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_trivially_destructible<I, void>::type
destroy_alloc_n(Allocator &, I, U)
{}

View File

@@ -183,28 +183,31 @@ struct scoped_destructor_n
typedef typename AllocTraits::value_type value_type;
typedef typename AllocTraits::size_type size_type;
scoped_destructor_n(pointer p, Allocator& a, size_type n)
BOOST_CONTAINER_FORCEINLINE scoped_destructor_n(pointer p, Allocator& a, size_type n)
: m_p(p), m_a(a), m_n(n)
{}
void release()
{ m_p = 0; }
BOOST_CONTAINER_FORCEINLINE void release()
{ m_p = 0; m_n = 0; }
void increment_size(size_type inc)
BOOST_CONTAINER_FORCEINLINE void increment_size(size_type inc)
{ m_n += inc; }
void increment_size_backwards(size_type inc)
BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(size_type inc)
{ m_n += inc; m_p -= inc; }
void shrink_forward(size_type inc)
BOOST_CONTAINER_FORCEINLINE void shrink_forward(size_type inc)
{ m_n -= inc; m_p += inc; }
~scoped_destructor_n()
{
if(!m_p) return;
value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
while(m_n--){
AllocTraits::destroy(m_a, raw_ptr++);
if(m_n){
value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p);
do {
--m_n;
AllocTraits::destroy(m_a, raw_ptr);
++raw_ptr;
} while(m_n);
}
}
@@ -223,19 +226,19 @@ struct null_scoped_destructor_n
typedef typename AllocTraits::pointer pointer;
typedef typename AllocTraits::size_type size_type;
null_scoped_destructor_n(pointer, Allocator&, size_type)
BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_n(pointer, Allocator&, size_type)
{}
void increment_size(size_type)
BOOST_CONTAINER_FORCEINLINE void increment_size(size_type)
{}
void increment_size_backwards(size_type)
BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(size_type)
{}
void shrink_forward(size_type)
BOOST_CONTAINER_FORCEINLINE void shrink_forward(size_type)
{}
void release()
BOOST_CONTAINER_FORCEINLINE void release()
{}
};
@@ -245,24 +248,24 @@ class scoped_destructor
typedef boost::container::allocator_traits<Allocator> AllocTraits;
public:
typedef typename Allocator::value_type value_type;
scoped_destructor(Allocator &a, value_type *pv)
BOOST_CONTAINER_FORCEINLINE scoped_destructor(Allocator &a, value_type *pv)
: pv_(pv), a_(a)
{}
~scoped_destructor()
BOOST_CONTAINER_FORCEINLINE ~scoped_destructor()
{
if(pv_){
AllocTraits::destroy(a_, pv_);
}
}
void release()
BOOST_CONTAINER_FORCEINLINE void release()
{ pv_ = 0; }
void set(value_type *ptr) { pv_ = ptr; }
BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; }
value_type *get() const { return pv_; }
BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; }
private:
value_type *pv_;
@@ -276,11 +279,11 @@ class value_destructor
typedef boost::container::allocator_traits<Allocator> AllocTraits;
public:
typedef Value value_type;
value_destructor(Allocator &a, value_type &rv)
BOOST_CONTAINER_FORCEINLINE value_destructor(Allocator &a, value_type &rv)
: rv_(rv), a_(a)
{}
~value_destructor()
BOOST_CONTAINER_FORCEINLINE ~value_destructor()
{
AllocTraits::destroy(a_, &rv_);
}
@@ -304,18 +307,18 @@ class allocator_destroyer
Allocator & a_;
private:
void priv_deallocate(const pointer &p, version_1)
BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_1)
{ AllocTraits::deallocate(a_,p, 1); }
void priv_deallocate(const pointer &p, version_2)
BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_2)
{ a_.deallocate_one(p); }
public:
explicit allocator_destroyer(Allocator &a)
BOOST_CONTAINER_FORCEINLINE explicit allocator_destroyer(Allocator &a)
: a_(a)
{}
void operator()(const pointer &p)
BOOST_CONTAINER_FORCEINLINE void operator()(const pointer &p)
{
AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p));
this->priv_deallocate(p, alloc_version());
@@ -333,11 +336,11 @@ class allocator_destroyer_and_chain_builder
multiallocation_chain &c_;
public:
allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
BOOST_CONTAINER_FORCEINLINE allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c)
: a_(a), c_(c)
{}
void operator()(const typename Allocator::pointer &p)
BOOST_CONTAINER_FORCEINLINE void operator()(const typename Allocator::pointer &p)
{
allocator_traits<Allocator>::destroy(a_, boost::movelib::to_raw_pointer(p));
c_.push_back(p);
@@ -356,14 +359,14 @@ class allocator_multialloc_chain_node_deallocator
multiallocation_chain c_;
public:
allocator_multialloc_chain_node_deallocator(Allocator &a)
BOOST_CONTAINER_FORCEINLINE allocator_multialloc_chain_node_deallocator(Allocator &a)
: a_(a), c_()
{}
chain_builder get_chain_builder()
BOOST_CONTAINER_FORCEINLINE chain_builder get_chain_builder()
{ return chain_builder(a_, c_); }
~allocator_multialloc_chain_node_deallocator()
BOOST_CONTAINER_FORCEINLINE ~allocator_multialloc_chain_node_deallocator()
{
a_.deallocate_individual(c_);
}

View File

@@ -110,10 +110,10 @@ template < typename ConstructAlloc
, typename T
, class ...Args
>
inline typename dtl::enable_if_and
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
< void
, dtl::is_not_pair<T>
, dtl::not_< uses_allocator<T, ArgAlloc> >
, dtl::not_< uses_allocator<T, typename remove_cvref<ArgAlloc>::type > >
>::type dispatch_uses_allocator
( ConstructAlloc & construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
{
@@ -127,10 +127,10 @@ template < typename ConstructAlloc
, typename T
, class ...Args
>
inline typename dtl::enable_if_and
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
< void
, dtl::is_not_pair<T>
, uses_allocator<T, ArgAlloc>
, uses_allocator<T, typename remove_cvref<ArgAlloc>::type>
, is_constructible_with_allocator_prefix<T, ArgAlloc, Args...>
>::type dispatch_uses_allocator
( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args) ...args)
@@ -146,10 +146,10 @@ template < typename ConstructAlloc
, typename T
, class ...Args
>
inline typename dtl::enable_if_and
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and
< void
, dtl::is_not_pair<T>
, uses_allocator<T, ArgAlloc>
, uses_allocator<T, typename remove_cvref<ArgAlloc>::type>
, dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc, Args...> >
>::type dispatch_uses_allocator
( ConstructAlloc& construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p, BOOST_FWD_REF(Args)...args)
@@ -162,10 +162,10 @@ inline typename dtl::enable_if_and
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
template <typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
inline typename dtl::enable_if_and\
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
< void\
, dtl::is_not_pair<T>\
, dtl::not_<uses_allocator<T, ArgAlloc> >\
, dtl::not_<uses_allocator<T, typename remove_cvref<ArgAlloc>::type> >\
>::type\
dispatch_uses_allocator\
(ConstructAlloc &construct_alloc, BOOST_FWD_REF(ArgAlloc) arg_alloc, T* p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
@@ -179,10 +179,10 @@ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
inline typename dtl::enable_if_and\
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
< void\
, dtl::is_not_pair<T>\
, uses_allocator<T, ArgAlloc>\
, uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\
, is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N>\
>::type\
dispatch_uses_allocator\
@@ -197,10 +197,10 @@ BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_DISPATCH_USES_ALLOCATOR_CODE(N) \
template < typename ConstructAlloc, typename ArgAlloc, typename T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\
inline typename dtl::enable_if_and\
BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and\
< void\
, dtl::is_not_pair<T>\
, uses_allocator<T, ArgAlloc>\
, uses_allocator<T, typename remove_cvref<ArgAlloc>::type>\
, dtl::not_<is_constructible_with_allocator_prefix<T, ArgAlloc BOOST_MOVE_I##N BOOST_MOVE_TARG##N> >\
>::type\
dispatch_uses_allocator\

View File

@@ -123,18 +123,19 @@ BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(stored_allocator_type)
//
///////////////////////////////////////
template<class SequenceContainer, class Compare>
void flat_tree_container_inplace_merge //is_contiguous_container == true
BOOST_CONTAINER_FORCEINLINE void flat_tree_container_inplace_merge //is_contiguous_container == true
(SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp , dtl::true_)
{
typedef typename SequenceContainer::value_type value_type;
value_type *const braw = boost::movelib::iterator_to_raw_pointer(dest.begin());
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end());
boost::movelib::adaptive_merge(braw, iraw, eraw, comp, eraw, dest.capacity()- dest.size());
boost::movelib::adaptive_merge
(braw, iraw, eraw, comp, eraw, back_free_capacity<SequenceContainer>::get(dest));
}
template<class SequenceContainer, class Compare>
void flat_tree_container_inplace_merge //is_contiguous_container == false
BOOST_CONTAINER_FORCEINLINE void flat_tree_container_inplace_merge //is_contiguous_container == false
(SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp, dtl::false_)
{
boost::movelib::adaptive_merge(dest.begin(), it, dest.end(), comp);
@@ -146,17 +147,18 @@ void flat_tree_container_inplace_merge //is_contiguous_container == false
//
///////////////////////////////////////
template<class SequenceContainer, class Compare>
void flat_tree_container_inplace_sort_ending //is_contiguous_container == true
BOOST_CONTAINER_FORCEINLINE void flat_tree_container_inplace_sort_ending //is_contiguous_container == true
(SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp, dtl::true_)
{
typedef typename SequenceContainer::value_type value_type;
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end());
boost::movelib::adaptive_sort(iraw, eraw, comp, eraw, dest.capacity()- dest.size());
boost::movelib::adaptive_sort
(iraw, eraw, comp, eraw, back_free_capacity<SequenceContainer>::get(dest));
}
template<class SequenceContainer, class Compare>
void flat_tree_container_inplace_sort_ending //is_contiguous_container == false
BOOST_CONTAINER_FORCEINLINE void flat_tree_container_inplace_sort_ending //is_contiguous_container == false
(SequenceContainer& dest, typename SequenceContainer::iterator it, Compare comp , dtl::false_)
{
boost::movelib::adaptive_sort(it, dest.end(), comp);
@@ -312,7 +314,7 @@ void flat_tree_sort_contiguous_to_adopt // is_contiguous_container == true
}
template<class SequenceContainer, class Compare>
void flat_tree_adopt_sequence_equal // is_contiguous_container == true
BOOST_CONTAINER_FORCEINLINE void flat_tree_adopt_sequence_equal // is_contiguous_container == true
(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::true_)
{
flat_tree_sort_contiguous_to_adopt(tseq, boost::move(seq), comp);
@@ -320,7 +322,7 @@ void flat_tree_adopt_sequence_equal // is_contiguous_container == true
}
template<class SequenceContainer, class Compare>
void flat_tree_adopt_sequence_equal // is_contiguous_container == false
BOOST_CONTAINER_FORCEINLINE void flat_tree_adopt_sequence_equal // is_contiguous_container == false
(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::false_)
{
boost::movelib::adaptive_sort(seq.begin(), seq.end(), comp);
@@ -406,24 +408,24 @@ class flat_tree_value_compare
typedef Value second_argument_type;
typedef bool return_type;
public:
flat_tree_value_compare()
BOOST_CONTAINER_FORCEINLINE flat_tree_value_compare()
: Compare()
{}
flat_tree_value_compare(const Compare &pred)
BOOST_CONTAINER_FORCEINLINE flat_tree_value_compare(const Compare &pred)
: Compare(pred)
{}
bool operator()(const Value& lhs, const Value& rhs) const
BOOST_CONTAINER_FORCEINLINE bool operator()(const Value& lhs, const Value& rhs) const
{
KeyOfValue key_extract;
return Compare::operator()(key_extract(lhs), key_extract(rhs));
}
const Compare &get_comp() const
BOOST_CONTAINER_FORCEINLINE const Compare &get_comp() const
{ return *this; }
Compare &get_comp()
BOOST_CONTAINER_FORCEINLINE Compare &get_comp()
{ return *this; }
};
@@ -477,35 +479,35 @@ class flat_tree
BOOST_COPYABLE_AND_MOVABLE(Data)
public:
Data()
BOOST_CONTAINER_FORCEINLINE Data()
: value_compare(), m_seq()
{}
explicit Data(const allocator_t &alloc)
BOOST_CONTAINER_FORCEINLINE explicit Data(const allocator_t &alloc)
: value_compare(), m_seq(alloc)
{}
explicit Data(const Compare &comp)
BOOST_CONTAINER_FORCEINLINE explicit Data(const Compare &comp)
: value_compare(comp), m_seq()
{}
Data(const Compare &comp, const allocator_t &alloc)
BOOST_CONTAINER_FORCEINLINE Data(const Compare &comp, const allocator_t &alloc)
: value_compare(comp), m_seq(alloc)
{}
explicit Data(const Data &d)
BOOST_CONTAINER_FORCEINLINE explicit Data(const Data &d)
: value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq)
{}
Data(BOOST_RV_REF(Data) d)
BOOST_CONTAINER_FORCEINLINE Data(BOOST_RV_REF(Data) d)
: value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq))
{}
Data(const Data &d, const allocator_t &a)
BOOST_CONTAINER_FORCEINLINE Data(const Data &d, const allocator_t &a)
: value_compare(static_cast<const value_compare&>(d)), m_seq(d.m_seq, a)
{}
Data(BOOST_RV_REF(Data) d, const allocator_t &a)
BOOST_CONTAINER_FORCEINLINE Data(BOOST_RV_REF(Data) d, const allocator_t &a)
: value_compare(boost::move(static_cast<value_compare&>(d))), m_seq(boost::move(d.m_seq), a)
{}
@@ -984,10 +986,7 @@ class flat_tree
ret.first = this->nth(data.position - this->cbegin());
}
else{
typedef typename emplace_functor_type<try_emplace_t, KeyType, Args...>::type func_t;
typedef emplace_iterator<value_type, func_t, difference_type> it_t;
func_t func(try_emplace_t(), ::boost::forward<KeyType>(key), ::boost::forward<Args>(args)...);
ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());
ret.first = this->m_data.m_seq.emplace(data.position, try_emplace_t(), ::boost::forward<KeyType>(key), ::boost::forward<Args>(args)...);
}
return ret;
}
@@ -1053,10 +1052,7 @@ class flat_tree
ret.first = this->nth(data.position - this->cbegin());\
}\
else{\
typedef typename emplace_functor_type<try_emplace_t, KeyType BOOST_MOVE_I##N BOOST_MOVE_TARG##N>::type func_t;\
typedef emplace_iterator<value_type, func_t, difference_type> it_t;\
func_t func(try_emplace_t(), ::boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());\
ret.first = this->m_data.m_seq.emplace(data.position, try_emplace_t(), ::boost::forward<KeyType>(key) BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\
}\
return ret;\
}\
@@ -1080,10 +1076,7 @@ class flat_tree
ret.first->second = boost::forward<M>(obj);
}
else{
typedef typename emplace_functor_type<KeyType, M>::type func_t;
typedef emplace_iterator<value_type, func_t, difference_type> it_t;
func_t func(boost::forward<KeyType>(key), boost::forward<M>(obj));
ret.first = this->m_data.m_seq.insert(data.position, it_t(func), it_t());
ret.first = this->m_data.m_seq.emplace(data.position, boost::forward<KeyType>(key), boost::forward<M>(obj));
}
return ret;
}

View File

@@ -0,0 +1,198 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Benedek Thaler 2015-2016
// (C) Copyright Ion Gaztanaga 2019-2020. 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://erenon.hu/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_DETAIL_GUARDS_HPP
#define BOOST_CONTAINER_DETAIL_GUARDS_HPP
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/move/core.hpp> // BOOST_MOVABLE_BUT_NOT_COPYABLE
// move/detail
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#include <boost/move/detail/fwd_macros.hpp>
#endif
#include <boost/container/allocator_traits.hpp>
namespace boost {
namespace container {
namespace detail {
class null_construction_guard
{
public:
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <typename... Args>
null_construction_guard(Args&&...) {}
#else
#define NULL_CONSTRUCTION_GUARD_CODE(N) \
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
BOOST_CONTAINER_FORCEINLINE null_construction_guard(BOOST_MOVE_UREFANON##N)\
{}\
//
BOOST_MOVE_ITERATE_0TO9(NULL_CONSTRUCTION_GUARD_CODE)
#undef NULL_CONSTRUCTION_GUARD_CODE
#endif
void release() {}
void extend() {}
};
template <typename Allocator>
class construction_guard
{
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(construction_guard)
public:
construction_guard()
: _alloc_ptr()
, _elem_count()
, _allocator()
{}
construction_guard(pointer alloc_ptr, Allocator& allocator)
:_alloc_ptr(alloc_ptr)
, _elem_count(0)
, _allocator(&allocator)
{}
construction_guard(BOOST_RV_REF(construction_guard) rhs)
:_alloc_ptr(rhs._alloc_ptr)
, _elem_count(rhs._elem_count)
, _allocator(rhs._allocator)
{
rhs._elem_count = 0;
}
~construction_guard()
{
while (_elem_count) {
--_elem_count;
boost::container::allocator_traits<Allocator>::destroy(*_allocator, _alloc_ptr++);
}
}
void release()
{
_elem_count = 0;
}
void extend()
{
++_elem_count;
}
private:
pointer _alloc_ptr;
size_type _elem_count;
Allocator* _allocator;
};
/**
* Has two ranges
*
* On success, destroys the first range (src),
* on failure, destroys the second range (dst).
*
* Can be used when copying/moving a range
*/
template <class Allocator>
class nand_construction_guard
{
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
construction_guard<Allocator> _src;
construction_guard<Allocator> _dst;
bool _dst_released;
public:
nand_construction_guard()
: _src()
, _dst()
, _dst_released(false)
{}
nand_construction_guard( pointer src, Allocator& src_alloc
, pointer dst, Allocator& dst_alloc)
:_src(src, src_alloc),
_dst(dst, dst_alloc),
_dst_released(false)
{}
void extend()
{
_src.extend();
_dst.extend();
}
void release() // on success
{
_dst.release();
_dst_released = true;
}
~nand_construction_guard()
{
if (! _dst_released) { _src.release(); }
}
};
template <typename Allocator>
class allocation_guard
{
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(allocation_guard)
public:
allocation_guard(pointer alloc_ptr, size_type alloc_size, Allocator& allocator)
:_alloc_ptr(alloc_ptr),
_alloc_size(alloc_size),
_allocator(allocator)
{}
~allocation_guard()
{
if (_alloc_ptr)
{
boost::container::allocator_traits<Allocator>::deallocate(_allocator, _alloc_ptr, _alloc_size);
}
}
void release()
{
_alloc_ptr = 0;
}
private:
pointer _alloc_ptr;
size_type _alloc_size;
Allocator& _allocator;
};
}}} // namespace boost::container::detail
#include <boost/container/detail/config_end.hpp>
#endif // BOOST_CONTAINER_DETAIL_GUARDS_HPP

View File

@@ -26,6 +26,14 @@
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
//back_free_capacity
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME back_free_capacity
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace back_free_capacity_detail {
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
namespace boost {
namespace container {
namespace dtl {
@@ -40,6 +48,23 @@ struct is_contiguous_container
has_member_function_callable_with_data<const Container>::value;
};
template < class Container
, bool = boost::container::back_free_capacity_detail::
has_member_function_callable_with_back_free_capacity<const Container>::value>
struct back_free_capacity
{
static typename Container::size_type get(const Container &c)
{ return c.back_free_capacity(); }
};
template < class Container>
struct back_free_capacity<Container, false>
{
static typename Container::size_type get(const Container &c)
{ return c.capacity() - c.size(); }
};
} //namespace dtl {
} //namespace container {
} //namespace boost {

View File

@@ -18,6 +18,9 @@
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
// container
#include <boost/container/throw_exception.hpp>
// container/detail
@@ -71,7 +74,20 @@ struct growth_factor_100
: dtl::grow_factor_ratio<0, 2, 1>
{};
template<class SizeType>
BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &, SizeType)
{}
template<class SizeType, class SomeStoredSizeType>
BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &s, SomeStoredSizeType)
{
if (s >= SomeStoredSizeType(-1) )
s = SomeStoredSizeType(-1);
}
} //namespace container {
} //namespace boost {
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP

View File

@@ -104,7 +104,7 @@ namespace container {
namespace dtl {
#ifdef BOOST_PLAT_WINDOWS_UWP
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long);
extern "C" __declspec(dllimport) int __stdcall InitializeCriticalSectionEx(::_RTL_CRITICAL_SECTION *, unsigned long, unsigned long);
#else
extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(::_RTL_CRITICAL_SECTION *);
#endif

View File

@@ -40,6 +40,7 @@ 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::remove_cvref;
using ::boost::move_detail::make_unsigned;
using ::boost::move_detail::is_floating_point;
using ::boost::move_detail::is_integral;

View File

@@ -18,6 +18,9 @@
# pragma once
#endif
namespace boost {
namespace container {
//Functors for member algorithm defaults
template<class ValueType>
struct value_less
@@ -33,4 +36,7 @@ struct value_equal
{ return a == b; }
};
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP

View File

@@ -108,6 +108,15 @@
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
#endif
//#define BOOST_CONTAINER_DISABLE_NOINLINE
#if defined(BOOST_CONTAINER_DISABLE_NOINLINE)
#define BOOST_CONTAINER_NOINLINE
#else
#define BOOST_CONTAINER_NOINLINE BOOST_NOINLINE
#endif
#if !defined(__has_feature)
#define BOOST_CONTAINER_HAS_FEATURE(feature) 0
#else

File diff suppressed because it is too large Load Diff

View File

@@ -713,7 +713,7 @@ class flat_map
//!
//! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
//! Complexity: Logarithmic search time plus linear insertion time in case no equivalent key is present.
mapped_type &operator[](const key_type& k);
//! Effects: If there is no key equivalent to x in the flat_map, inserts
@@ -721,8 +721,8 @@ class flat_map
//!
//! Returns: A reference to the mapped_type corresponding to x in *this.
//!
//! Complexity: Logarithmic.
mapped_type &operator[](key_type &&k) ;
//! Complexity: Logarithmic search time plus linear insertion time in case no equivalent key is present.
mapped_type &operator[](key_type &&k);
#elif defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
//in compilers like GCC 3.4, we can't catch temporaries
BOOST_CONTAINER_FORCEINLINE mapped_type& operator[](const key_type &k) { return this->priv_subscript(k); }
@@ -742,7 +742,7 @@ class flat_map
//! Returns: The bool component is true if the insertion took place and false if the assignment
//! took place. The iterator component is pointing at the element that was inserted or updated.
//!
//! Complexity: Logarithmic in the size of the container.
//! Complexity: Logarithmic search time plus linear insertion time in case no equivalent key is present.
template <class M>
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> insert_or_assign(const key_type& k, BOOST_FWD_REF(M) obj)
{
@@ -955,7 +955,7 @@ class flat_map
//! <b>Returns</b>: The bool component of the returned pair is true if and only if the
//! insertion took place. The returned iterator points to the map element whose key is equivalent to k.
//!
//! <b>Complexity</b>: Logarithmic.
//! <b>Complexity</b>: Logarithmic search time plus linear insertion time in case the key is not present.
template <class... Args>
BOOST_CONTAINER_FORCEINLINE std::pair<iterator, bool> try_emplace(BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
{
@@ -973,7 +973,7 @@ class flat_map
//! <b>Returns</b>: The returned iterator points to the map element whose key is equivalent to k.
//!
//! <b>Complexity</b>: Logarithmic in general, but amortized constant if value
//! is inserted right before p.
//! is inserted right before p. Linear insertion time in case no equivalent key is present.
template <class... Args>
BOOST_CONTAINER_FORCEINLINE iterator try_emplace(const_iterator hint, BOOST_RV_REF(key_type) k, BOOST_FWD_REF(Args)... args)
{
@@ -1199,7 +1199,7 @@ class flat_map
//!
//! <b>Throws</b>: Nothing unless the comparison object throws.
//!
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
//! <b>Complexity</b>: N log(size() + N) (N has the value source.size())
template<class C2>
BOOST_CONTAINER_FORCEINLINE void merge(flat_map<Key, T, C2, AllocatorOrContainer>& source)
{ m_flat_tree.merge_unique(source.tree()); }
@@ -1269,7 +1269,7 @@ class flat_map
&& boost::container::dtl::is_nothrow_swappable<Compare>::value )
{ m_flat_tree.swap(x.m_flat_tree); }
//! <b>Effects</b>: erase(a.begin(),a.end()).
//! <b>Effects</b>: erase(begin(),end()).
//!
//! <b>Postcondition</b>: size() == 0.
//!
@@ -1376,14 +1376,14 @@ class flat_map
{ return m_flat_tree.find(x) != m_flat_tree.end(); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& x)
{ return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& x) const
@@ -1393,7 +1393,7 @@ class flat_map
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
template<class K>
@@ -1404,22 +1404,22 @@ class flat_map
//! key_compare::is_transparent exists.
//!
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
template<class K>
BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const K& x) const
{ return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
BOOST_CONTAINER_FORCEINLINE iterator upper_bound(const key_type& x)
{ return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& x) const
@@ -1428,7 +1428,7 @@ class flat_map
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
@@ -1439,8 +1439,8 @@ class flat_map
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic.
template<class K>
@@ -2539,7 +2539,7 @@ class flat_multimap
//!
//! <b>Throws</b>: Nothing unless the comparison object throws.
//!
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
//! <b>Complexity</b>: N log(size() + N) (N has the value source.size())
template<class C2>
BOOST_CONTAINER_FORCEINLINE void merge(flat_multimap<Key, T, C2, AllocatorOrContainer>& source)
{ m_flat_tree.merge_equal(source.tree()); }
@@ -2609,7 +2609,7 @@ class flat_multimap
&& boost::container::dtl::is_nothrow_swappable<Compare>::value )
{ m_flat_tree.swap(x.m_flat_tree); }
//! <b>Effects</b>: erase(a.begin(),a.end()).
//! <b>Effects</b>: erase(begin(),end()).
//!
//! <b>Postcondition</b>: size() == 0.
//!
@@ -2714,14 +2714,14 @@ class flat_multimap
{ return m_flat_tree.find(x) != m_flat_tree.end(); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
BOOST_CONTAINER_FORCEINLINE iterator lower_bound(const key_type& x)
{ return dtl::force_copy<iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const key_type& x) const
@@ -2731,7 +2731,7 @@ class flat_multimap
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<class K>
@@ -2742,14 +2742,14 @@ class flat_multimap
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<class K>
BOOST_CONTAINER_FORCEINLINE const_iterator lower_bound(const K& x) const
{ return dtl::force_copy<const_iterator>(m_flat_tree.lower_bound(x)); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -2757,7 +2757,7 @@ class flat_multimap
{return dtl::force_copy<iterator>(m_flat_tree.upper_bound(x)); }
//! <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.
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
BOOST_CONTAINER_FORCEINLINE const_iterator upper_bound(const key_type& x) const
@@ -2766,7 +2766,7 @@ class flat_multimap
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -2778,7 +2778,7 @@ class flat_multimap
//! key_compare::is_transparent exists.
//!
//! <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.
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<class K>

View File

@@ -808,7 +808,7 @@ class flat_set
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
&& boost::container::dtl::is_nothrow_swappable<Compare>::value );
//! <b>Effects</b>: erase(a.begin(),a.end()).
//! <b>Effects</b>: erase(begin(),end()).
//!
//! <b>Postcondition</b>: size() == 0.
//!
@@ -948,13 +948,13 @@ class flat_set
bool contains(const K& x) const;
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x);
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator lower_bound(const key_type& x) const;
@@ -963,7 +963,7 @@ class flat_set
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
@@ -973,20 +973,20 @@ class flat_set
//! key_compare::is_transparent exists.
//!
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
const_iterator lower_bound(const K& x) const;
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x);
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const;
@@ -994,7 +994,7 @@ class flat_set
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -1004,8 +1004,8 @@ class flat_set
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>

View File

@@ -354,7 +354,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements.
~list() BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE ~list() BOOST_NOEXCEPT_OR_NOTHROW
{} //AllocHolder clears the list
//! <b>Effects</b>: Makes *this contain the same elements as x.
@@ -430,9 +430,9 @@ class list
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to the number of elements in x.
list& operator=(std::initializer_list<value_type> il)
BOOST_CONTAINER_FORCEINLINE list& operator=(std::initializer_list<value_type> il)
{
assign(il.begin(), il.end());
this->assign(il.begin(), il.end());
return *this;
}
#endif
@@ -442,7 +442,7 @@ class list
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
//!
//! <b>Complexity</b>: Linear to n.
void assign(size_type n, const T& val)
BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& val)
{
typedef constant_iterator<value_type, difference_type> cvalue_iterator;
return this->assign(cvalue_iterator(val, n), cvalue_iterator());
@@ -479,8 +479,8 @@ class list
//! T's constructor from dereferencing std::initializer_list iterator throws.
//!
//! <b>Complexity</b>: Linear to n.
void assign(std::initializer_list<value_type> il)
{ assign(il.begin(), il.end()); }
BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<value_type> il)
{ this->assign(il.begin(), il.end()); }
#endif
//! <b>Effects</b>: Returns a copy of the internal allocator.
@@ -488,7 +488,7 @@ class list
//! <b>Throws</b>: If allocator's copy constructor throws.
//!
//! <b>Complexity</b>: Constant.
allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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.
@@ -498,7 +498,7 @@ class list
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return this->node_alloc(); }
//! <b>Effects</b>: Returns a reference to the internal allocator.
@@ -508,7 +508,7 @@ class list
//! <b>Complexity</b>: Constant.
//!
//! <b>Note</b>: Non-standard extension.
const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->node_alloc(); }
//////////////////////////////////////////////
@@ -522,7 +522,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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.
@@ -530,7 +530,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cbegin(); }
//! <b>Effects</b>: Returns an iterator to the end of the list.
@@ -538,7 +538,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
iterator end() BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW
{ return iterator(this->icont().end()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
@@ -546,7 +546,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->cend(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
@@ -555,7 +555,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(end()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
@@ -564,7 +564,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->crbegin(); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the end
@@ -573,7 +573,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
{ return reverse_iterator(begin()); }
//! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
@@ -582,7 +582,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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.
@@ -590,7 +590,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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.
@@ -598,7 +598,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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
@@ -607,7 +607,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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
@@ -616,7 +616,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
{ return const_reverse_iterator(this->cbegin()); }
//////////////////////////////////////////////
@@ -630,7 +630,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
{ return !this->size(); }
//! <b>Effects</b>: Returns the number of the elements contained in the list.
@@ -638,7 +638,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->icont().size(); }
//! <b>Effects</b>: Returns the largest possible size of the list.
@@ -646,7 +646,7 @@ class list
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Constant.
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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

View File

@@ -993,7 +993,7 @@ class map
//!
//! <b>Returns</b>: A node_type owning the element if found, otherwise an empty node_type.
//!
//! <b>Complexity</b>: log(a.size()).
//! <b>Complexity</b>: log(size()).
node_type extract(const key_type& k)
{
typename base_t::node_type base_nh(this->base_t::extract(k));
@@ -1026,7 +1026,7 @@ class map
//!
//! <b>Throws</b>: Nothing unless the comparison object throws.
//!
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
//! <b>Complexity</b>: N log(size() + N) (N has the value source.size())
template<class C2>
BOOST_CONTAINER_FORCEINLINE void merge(map<Key, T, C2, Allocator, Options>& source)
{
@@ -1064,7 +1064,7 @@ class map
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
&& boost::container::dtl::is_nothrow_swappable<Compare>::value )
//! <b>Effects</b>: erase(a.begin(),a.end()).
//! <b>Effects</b>: erase(begin(),end()).
//!
//! <b>Postcondition</b>: size() == 0.
//!
@@ -1152,13 +1152,13 @@ class map
bool contains(const K& x) const;
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x);
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator lower_bound(const key_type& x) const;
@@ -1167,7 +1167,7 @@ class map
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
@@ -1177,20 +1177,20 @@ class map
//! key_compare::is_transparent exists.
//!
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
const_iterator lower_bound(const K& x) const;
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x);
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const;
@@ -1198,7 +1198,7 @@ class map
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -1208,8 +1208,8 @@ class map
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
@@ -1981,7 +1981,7 @@ class multimap
//!
//! <b>Throws</b>: Nothing unless the comparison object throws.
//!
//! <b>Complexity</b>: N log(a.size() + N) (N has the value source.size())
//! <b>Complexity</b>: N log(size() + N) (N has the value source.size())
template<class C2>
BOOST_CONTAINER_FORCEINLINE void merge(multimap<Key, T, C2, Allocator, Options>& source)
{
@@ -2087,13 +2087,13 @@ class multimap
bool contains(const K& x) const;
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x);
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator lower_bound(const key_type& x) const;
@@ -2102,7 +2102,7 @@ class multimap
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
@@ -2112,20 +2112,20 @@ class multimap
//! key_compare::is_transparent exists.
//!
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
const_iterator lower_bound(const K& x) const;
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x);
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const;
@@ -2133,7 +2133,7 @@ class multimap
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -2143,8 +2143,8 @@ class multimap
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>

View File

@@ -258,7 +258,7 @@ class node_allocator
BOOST_STATIC_ASSERT(( Version > 1 ));
dlmalloc_memchain ch;
BOOST_CONTAINER_MEMCHAIN_INIT(&ch);
if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
if(BOOST_UNLIKELY(!dlmalloc_multialloc_nodes(n_elements, elem_size*sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch))){
boost::container::throw_bad_alloc();
}
chain.incorporate_after( chain.before_begin()
@@ -273,7 +273,7 @@ class node_allocator
{
BOOST_STATIC_ASSERT(( Version > 1 ));
dlmalloc_memchain ch;
dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch);
dlmalloc_multialloc_arrays(n_elements, elem_sizes, sizeof(T), BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &ch);
if(BOOST_UNLIKELY(BOOST_CONTAINER_MEMCHAIN_EMPTY(&ch))){
boost::container::throw_bad_alloc();
}

View File

@@ -215,6 +215,13 @@ class default_next_capacity;
typedef vector_opt<void, void> vector_null_opt;
template<class GrowthType, class StoredSizeType>
struct devector_opt
: vector_opt<GrowthType, StoredSizeType>
{};
typedef devector_opt<void, void> devector_null_opt;
#else //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!This growth factor argument specifies that the container should increase it's
@@ -442,6 +449,40 @@ using static_vector_options_t = typename boost::container::static_vector_options
#endif
//! Helper metafunction to combine options into a single type to be used
//! by \c boost::container::devector.
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
#endif
struct devector_options
{
/// @cond
typedef typename ::boost::intrusive::pack_options
< devector_null_opt,
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::type packed_options;
typedef devector_opt< typename packed_options::growth_factor_type
, typename packed_options::stored_size_type> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//! Helper alias metafunction to combine options into a single type to be used
//! by \c boost::container::devector.
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
template<class ...Options>
using devector_options_t = typename boost::container::devector_options<Options...>::type;
#endif
////////////////////////////////////////////////////////////////
//

View File

@@ -0,0 +1,51 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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_PMR_VECTOR_HPP
#define BOOST_CONTAINER_PMR_VECTOR_HPP
#if defined (_MSC_VER)
# pragma once
#endif
#include <boost/container/devector.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>
namespace boost {
namespace container {
namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <
typename T,
typename GrowthPolicy = growth_factor_60
>
using devector = boost::container::devector<T, GrowthPolicy, polymorphic_allocator<T> >;
#endif
//! A portable metafunction to obtain a vector
//! that uses a polymorphic allocator
template <
typename T,
typename GrowthPolicy = growth_factor_60
>
struct devector_of
{
typedef boost::container::devector
< T, GrowthPolicy, polymorphic_allocator<T> > type;
};
} //namespace pmr {
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_VECTOR_HPP

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_PMR_SET_HPP
#define BOOST_CONTAINER_PMR_SET_HPP
#ifndef BOOST_CONTAINER_PMR_FLAT_SET_HPP
#define BOOST_CONTAINER_PMR_FLAT_SET_HPP
#if defined (_MSC_VER)
# pragma once
@@ -56,4 +56,4 @@ struct flat_multiset_of
} //namespace container {
} //namespace boost {
#endif //BOOST_CONTAINER_PMR_SET_HPP
#endif //BOOST_CONTAINER_PMR_FLAT_SET_HPP

View File

@@ -53,6 +53,8 @@ class BOOST_CONTAINER_DECL memory_resource
bool is_equal(const memory_resource& other) const BOOST_NOEXCEPT
{ return this->do_is_equal(other); }
#if !defined(BOOST_EMBTC)
//! <b>Returns</b>:
//! `&a == &b || a.is_equal(b)`.
friend bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
@@ -63,6 +65,18 @@ class BOOST_CONTAINER_DECL memory_resource
friend bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return !(a == b); }
#else
//! <b>Returns</b>:
//! `&a == &b || a.is_equal(b)`.
friend bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT;
//! <b>Returns</b>:
//! !(a == b).
friend bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT;
#endif
protected:
//! <b>Requires</b>: Alignment shall be a power of two.
//!
@@ -93,6 +107,20 @@ class BOOST_CONTAINER_DECL memory_resource
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT = 0;
};
#if defined(BOOST_EMBTC)
//! <b>Returns</b>:
//! `&a == &b || a.is_equal(b)`.
inline bool operator==(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return &a == &b || a.is_equal(b); }
//! <b>Returns</b>:
//! !(a == b).
inline bool operator!=(const memory_resource& a, const memory_resource& b) BOOST_NOEXCEPT
{ return !(a == b); }
#endif
} //namespace pmr {
} //namespace container {
} //namespace boost {

View File

@@ -109,7 +109,7 @@ class BOOST_CONTAINER_DECL monotonic_buffer_resource
//! <b>Effects</b>: Calls
//! `this->release()`.
virtual ~monotonic_buffer_resource();
~monotonic_buffer_resource() BOOST_OVERRIDE;
//! <b>Effects</b>: `upstream_resource()->deallocate()` as necessary to release all allocated memory.
//! [Note: memory is released back to `upstream_resource()` even if some blocks that were allocated
@@ -160,18 +160,18 @@ class BOOST_CONTAINER_DECL monotonic_buffer_resource
//! then allocate the return block from the newly-allocated internal `current_buffer`.
//!
//! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws.
virtual void* do_allocate(std::size_t bytes, std::size_t alignment);
void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! <b>Effects</b>: None
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Remarks</b>: Memory used by this resource increases monotonically until its destruction.
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_NOEXCEPT;
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_NOEXCEPT BOOST_OVERRIDE;
//! <b>Returns</b>:
//! `this == dynamic_cast<const monotonic_buffer_resource*>(&other)`.
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT;
bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE;
};
} //namespace pmr {

View File

@@ -53,10 +53,9 @@ class polymorphic_allocator
//! <b>Throws</b>: Nothing
//!
//! <b>Notes</b>: This constructor provides an implicit conversion from memory_resource*.
//! Non-standard extension: if r is null m_resource is set to get_default_resource().
polymorphic_allocator(memory_resource* r)
: m_resource(r ? r : ::boost::container::pmr::get_default_resource())
{}
: m_resource(r)
{ BOOST_ASSERT(r != 0); }
//! <b>Effects</b>: Sets m_resource to
//! other.resource().

View File

@@ -89,7 +89,7 @@ class BOOST_CONTAINER_DECL synchronized_pool_resource
#endif
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::~unsynchronized_pool_resource()
virtual ~synchronized_pool_resource();
~synchronized_pool_resource() BOOST_OVERRIDE;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::release()
void release();
@@ -103,13 +103,13 @@ class BOOST_CONTAINER_DECL synchronized_pool_resource
protected:
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_allocate()
virtual void* do_allocate(std::size_t bytes, std::size_t alignment);
void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_deallocate(void*,std::size_t,std::size_t)
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment);
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_is_equal(const memory_resource&)const
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT;
bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE;
//Non-standard observers
public:

View File

@@ -103,7 +103,7 @@ class BOOST_CONTAINER_DECL unsynchronized_pool_resource
//! <b>Effects</b>: Calls
//! `this->release()`.
virtual ~unsynchronized_pool_resource();
~unsynchronized_pool_resource() BOOST_OVERRIDE;
//! <b>Effects</b>: Calls Calls `upstream_resource()->deallocate()` as necessary
//! to release all allocated memory. [ Note: memory is released back to
@@ -134,18 +134,18 @@ class BOOST_CONTAINER_DECL unsynchronized_pool_resource
//! using `upstream_resource()->allocate()`.
//!
//! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws.
virtual void* do_allocate(std::size_t bytes, std::size_t alignment);
void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! <b>Effects</b>: Return the memory at p to the pool. It is unspecified if or under
//! what circumstances this operation will result in a call to
//! `upstream_resource()->deallocate()`.
//!
//! <b>Throws</b>: Nothing.
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment);
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE;
//! <b>Returns</b>:
//! `this == dynamic_cast<const unsynchronized_pool_resource*>(&other)`.
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT;
bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE;
//Non-standard observers
public:

View File

@@ -79,10 +79,10 @@ struct outermost_allocator_imp
{
typedef MaybeScopedAlloc type;
static type &get(MaybeScopedAlloc &a)
BOOST_CONTAINER_FORCEINLINE static type &get(MaybeScopedAlloc &a)
{ return a; }
static const type &get(const MaybeScopedAlloc &a)
BOOST_CONTAINER_FORCEINLINE static const type &get(const MaybeScopedAlloc &a)
{ return a; }
};
@@ -92,10 +92,10 @@ struct outermost_allocator_imp<MaybeScopedAlloc, true>
typedef typename MaybeScopedAlloc::outer_allocator_type outer_type;
typedef typename outermost_allocator_type_impl<outer_type>::type type;
static type &get(MaybeScopedAlloc &a)
BOOST_CONTAINER_FORCEINLINE static type &get(MaybeScopedAlloc &a)
{ return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
static const type &get(const MaybeScopedAlloc &a)
BOOST_CONTAINER_FORCEINLINE static const type &get(const MaybeScopedAlloc &a)
{ return outermost_allocator_imp<outer_type>::get(a.outer_allocator()); }
};
@@ -112,12 +112,12 @@ struct outermost_allocator
{};
template <typename Allocator>
typename outermost_allocator<Allocator>::type &
BOOST_CONTAINER_FORCEINLINE typename outermost_allocator<Allocator>::type &
get_outermost_allocator(Allocator &a)
{ return outermost_allocator<Allocator>::get(a); }
template <typename Allocator>
const typename outermost_allocator<Allocator>::type &
BOOST_CONTAINER_FORCEINLINE const typename outermost_allocator<Allocator>::type &
get_outermost_allocator(const Allocator &a)
{ return outermost_allocator<Allocator>::get(a); }
@@ -161,34 +161,34 @@ class scoped_allocator_adaptor_base
inner_allocator_type::is_always_equal::value
> is_always_equal;
scoped_allocator_adaptor_base()
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base()
{}
template <class OuterA2>
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs &...args)
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
, m_inner(args...)
{}
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
BOOST_CONTAINER_FORCEINLINE 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)
BOOST_CONTAINER_FORCEINLINE 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
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
(const scoped_allocator_adaptor_base<OuterA2, InnerAllocs...>& other)
: outer_allocator_type(other.outer_allocator())
, m_inner(other.inner_allocator())
{}
template <class OuterA2>
scoped_allocator_adaptor_base
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base
<OuterA2, InnerAllocs...> BOOST_RV_REF_END other)
: outer_allocator_type(other.outer_allocator())
@@ -199,7 +199,7 @@ class scoped_allocator_adaptor_base
struct internal_type_t{};
template <class OuterA2>
scoped_allocator_adaptor_base
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
( internal_type_t
, BOOST_FWD_REF(OuterA2) outerAlloc
, const inner_allocator_type &inner)
@@ -209,7 +209,7 @@ class scoped_allocator_adaptor_base
public:
scoped_allocator_adaptor_base &operator=
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
{
outer_allocator_type::operator=(other.outer_allocator());
@@ -217,35 +217,35 @@ class scoped_allocator_adaptor_base
return *this;
}
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
BOOST_CONTAINER_FORCEINLINE 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_FORCEINLINE 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)
BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
{ l.swap(r); }
inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return m_inner; }
inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
{ return m_inner; }
outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator() BOOST_NOEXCEPT_OR_NOTHROW
{ return static_cast<outer_allocator_type&>(*this); }
const outer_allocator_type &outer_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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
BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const
{
return scoped_allocator_type
(internal_type_t()
@@ -304,33 +304,33 @@ class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
inner_allocator_type::is_always_equal::value\
> is_always_equal;\
\
scoped_allocator_adaptor_base(){}\
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(){}\
\
template <class OuterA2>\
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc, BOOST_MOVE_CREF##N)\
BOOST_CONTAINER_FORCEINLINE 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)\
BOOST_CONTAINER_FORCEINLINE 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)\
BOOST_CONTAINER_FORCEINLINE 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\
BOOST_CONTAINER_FORCEINLINE 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_CONTAINER_FORCEINLINE 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())\
@@ -340,14 +340,14 @@ class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
struct internal_type_t{};\
\
template <class OuterA2>\
scoped_allocator_adaptor_base\
BOOST_CONTAINER_FORCEINLINE 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_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=\
(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)\
{\
outer_allocator_type::operator=(other.outer_allocator());\
@@ -355,35 +355,35 @@ class scoped_allocator_adaptor_base<OuterAlloc, true, BOOST_MOVE_TARG##N>\
return *this;\
}\
\
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)\
BOOST_CONTAINER_FORCEINLINE 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_FORCEINLINE 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)\
BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)\
{ l.swap(r); }\
\
inner_allocator_type& inner_allocator()\
BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator()\
{ return m_inner; }\
\
inner_allocator_type const& inner_allocator() const\
BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const\
{ return m_inner; }\
\
outer_allocator_type & outer_allocator()\
BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator()\
{ return static_cast<outer_allocator_type&>(*this); }\
\
const outer_allocator_type &outer_allocator() const\
BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const\
{ return static_cast<const outer_allocator_type&>(*this); }\
\
scoped_allocator_type select_on_container_copy_construction() const\
BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const\
{\
return scoped_allocator_type\
(internal_type_t()\
@@ -440,30 +440,30 @@ class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMM
typedef typename outer_traits_type::
is_always_equal is_always_equal;
scoped_allocator_adaptor_base()
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base()
{}
template <class OuterA2>
scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_FWD_REF(OuterA2) outerAlloc)
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
{}
scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(const scoped_allocator_adaptor_base& other)
: outer_allocator_type(other.outer_allocator())
{}
scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
: outer_allocator_type(::boost::move(other.outer_allocator()))
{}
template <class OuterA2>
scoped_allocator_adaptor_base
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
(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_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base
(BOOST_RV_REF_BEG scoped_allocator_adaptor_base<OuterA2 BOOST_CONTAINER_SCOPEDALLOC_DUMMYTRUE> BOOST_RV_REF_END other)
: outer_allocator_type(other.outer_allocator())
{}
@@ -472,44 +472,44 @@ class scoped_allocator_adaptor_base< OuterAlloc BOOST_CONTAINER_SCOPEDALLOC_DUMM
struct internal_type_t{};
template <class OuterA2>
scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base(internal_type_t, BOOST_FWD_REF(OuterA2) outerAlloc, const inner_allocator_type &)
: outer_allocator_type(::boost::forward<OuterA2>(outerAlloc))
{}
public:
scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor_base) other)
{
outer_allocator_type::operator=(other.outer_allocator());
return *this;
}
scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor_base &operator=(BOOST_RV_REF(scoped_allocator_adaptor_base) other)
{
outer_allocator_type::operator=(boost::move(other.outer_allocator()));
return *this;
}
void swap(scoped_allocator_adaptor_base &r)
BOOST_CONTAINER_FORCEINLINE void swap(scoped_allocator_adaptor_base &r)
{
boost::adl_move_swap(this->outer_allocator(), r.outer_allocator());
}
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
BOOST_CONTAINER_FORCEINLINE friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
{ l.swap(r); }
inner_allocator_type& inner_allocator()
BOOST_CONTAINER_FORCEINLINE inner_allocator_type& inner_allocator()
{ return static_cast<inner_allocator_type&>(*this); }
inner_allocator_type const& inner_allocator() const
BOOST_CONTAINER_FORCEINLINE inner_allocator_type const& inner_allocator() const
{ return static_cast<const inner_allocator_type&>(*this); }
outer_allocator_type & outer_allocator()
BOOST_CONTAINER_FORCEINLINE outer_allocator_type & outer_allocator()
{ return static_cast<outer_allocator_type&>(*this); }
const outer_allocator_type &outer_allocator() const
BOOST_CONTAINER_FORCEINLINE const outer_allocator_type &outer_allocator() const
{ return static_cast<const outer_allocator_type&>(*this); }
scoped_allocator_type select_on_container_copy_construction() const
BOOST_CONTAINER_FORCEINLINE scoped_allocator_type select_on_container_copy_construction() const
{
return scoped_allocator_type
(internal_type_t()
@@ -641,21 +641,21 @@ class scoped_allocator_adaptor
//! <b>Effects</b>: value-initializes the OuterAlloc base class
//! and the inner allocator object.
scoped_allocator_adaptor()
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor()
{}
~scoped_allocator_adaptor()
BOOST_CONTAINER_FORCEINLINE ~scoped_allocator_adaptor()
{}
//! <b>Effects</b>: initializes each allocator within the adaptor with
//! the corresponding allocator from other.
scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
: base_type(other.base())
{}
//! <b>Effects</b>: move constructs each allocator within the adaptor with
//! the corresponding allocator from other.
scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_RV_REF(scoped_allocator_adaptor) other)
: base_type(::boost::move(other.base()))
{}
@@ -667,14 +667,14 @@ class scoped_allocator_adaptor
//! with innerAllocs...(hence recursively initializing each allocator within the adaptor with the
//! corresponding allocator from the argument list).
template <class OuterA2>
scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(BOOST_FWD_REF(OuterA2) outerAlloc, const InnerAllocs & ...innerAllocs)
: base_type(::boost::forward<OuterA2>(outerAlloc), innerAllocs...)
{}
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
#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)\
BOOST_CONTAINER_FORCEINLINE 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)\
{}\
//
@@ -687,7 +687,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, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER> &other)
: base_type(other.base())
{}
@@ -696,15 +696,15 @@ 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
BOOST_CONTAINER_FORCEINLINE 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()))
{}
scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
{ 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)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
{ return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(other.base()))); }
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -736,13 +736,13 @@ class scoped_allocator_adaptor
//! <b>Returns</b>:
//! <code>allocator_traits<OuterAlloc>:: max_size(outer_allocator())</code>.
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE 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_NOEXCEPT_OR_NOTHROW
BOOST_CONTAINER_FORCEINLINE void destroy(T* p) BOOST_NOEXCEPT_OR_NOTHROW
{
allocator_traits<typename outermost_allocator<OuterAlloc>::type>
::destroy(get_outermost_allocator(this->outer_allocator()), p);
@@ -750,17 +750,17 @@ class scoped_allocator_adaptor
//! <b>Returns</b>:
//! <code>allocator_traits<OuterAlloc>::allocate(outer_allocator(), n)</code>.
pointer allocate(size_type n)
BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type 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)
BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n, const_void_pointer 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)
BOOST_CONTAINER_FORCEINLINE void deallocate(pointer p, size_type n)
{ outer_traits_type::deallocate(this->outer_allocator(), p, n); }
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -772,9 +772,9 @@ class scoped_allocator_adaptor
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
base_type &base() { return *this; }
BOOST_CONTAINER_FORCEINLINE base_type &base() { return *this; }
const base_type &base() const { return *this; }
BOOST_CONTAINER_FORCEINLINE const base_type &base() const { return *this; }
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -808,7 +808,7 @@ class scoped_allocator_adaptor
//! to true but the specific constructor does not take an allocator. This definition prevents a silent
//! failure to pass an inner allocator to a contained element. -end note]
template < typename T, class ...Args>
void construct(T* p, BOOST_FWD_REF(Args)...args)
BOOST_CONTAINER_FORCEINLINE void construct(T* p, BOOST_FWD_REF(Args)...args)
{
dtl::dispatch_uses_allocator
( (get_outermost_allocator)(this->outer_allocator())
@@ -821,7 +821,7 @@ class scoped_allocator_adaptor
//overload selection problems when the first parameter is a pair.
#define BOOST_CONTAINER_SCOPED_ALLOCATOR_CONSTRUCT_CODE(N) \
template < typename T BOOST_MOVE_I##N BOOST_MOVE_CLASSQ##N >\
void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
BOOST_CONTAINER_FORCEINLINE void construct(T* p BOOST_MOVE_I##N BOOST_MOVE_UREFQ##N)\
{\
dtl::dispatch_uses_allocator\
( (get_outermost_allocator)(this->outer_allocator())\
@@ -838,7 +838,7 @@ class scoped_allocator_adaptor
public:
//Internal function
template <class OuterA2>
scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
BOOST_CONTAINER_FORCEINLINE scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
: base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)
{}
@@ -853,17 +853,17 @@ struct scoped_allocator_operator_equal
//Optimize equal outer allocator types with
//allocator_traits::equal which uses is_always_equal
template<class IA>
static bool equal_outer(const IA &l, const IA &r)
BOOST_CONTAINER_FORCEINLINE static bool equal_outer(const IA &l, const IA &r)
{ return allocator_traits<IA>::equal(l, r); }
//Otherwise compare it normally
template<class IA1, class IA2>
static bool equal_outer(const IA1 &l, const IA2 &r)
BOOST_CONTAINER_FORCEINLINE static bool equal_outer(const IA1 &l, const IA2 &r)
{ return l == r; }
//Otherwise compare it normally
template<class IA>
static bool equal_inner(const IA &l, const IA &r)
BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA &l, const IA &r)
{ return allocator_traits<IA>::equal(l, r); }
};
@@ -875,14 +875,14 @@ struct scoped_allocator_operator_equal<true>
//inner_allocator_type is the same as outer_allocator_type
//so both types can be different in operator==
template<class IA1, class IA2>
static bool equal_inner(const IA1 &, const IA2 &)
BOOST_CONTAINER_FORCEINLINE static bool equal_inner(const IA1 &, const IA2 &)
{ return true; }
};
/// @endcond
template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
BOOST_CONTAINER_FORCEINLINE 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)
@@ -896,7 +896,7 @@ inline bool operator==(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_S
}
template <typename OuterA1, typename OuterA2, BOOST_CONTAINER_SCOPEDALLOC_ALLINNERCLASS>
inline bool operator!=(const scoped_allocator_adaptor<OuterA1, BOOST_CONTAINER_SCOPEDALLOC_ALLINNER>& a
BOOST_CONTAINER_FORCEINLINE 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); }

View File

@@ -718,7 +718,7 @@ class set
BOOST_NOEXCEPT_IF( allocator_traits_type::is_always_equal::value
&& boost::container::dtl::is_nothrow_swappable<Compare>::value );
//! <b>Effects</b>: erase(a.begin(),a.end()).
//! <b>Effects</b>: erase(begin(),end()).
//!
//! <b>Postcondition</b>: size() == 0.
//!
@@ -806,13 +806,13 @@ class set
bool contains(const K& x) const;
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator lower_bound(const key_type& x);
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator lower_bound(const key_type& x) const;
@@ -821,7 +821,7 @@ class set
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found.
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
@@ -831,20 +831,20 @@ class set
//! key_compare::is_transparent exists.
//!
//! <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.
//! less than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>
const_iterator lower_bound(const K& x) const;
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
iterator upper_bound(const key_type& x);
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
const_iterator upper_bound(const key_type& x) const;
@@ -852,7 +852,7 @@ class set
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <b>Returns</b>: An iterator pointing to the first element with key not less
//! <b>Returns</b>: An iterator pointing to the first element with key greater
//! than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
@@ -862,8 +862,8 @@ class set
//! <b>Requires</b>: This overload is available only if
//! key_compare::is_transparent exists.
//!
//! <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>Returns</b>: A const iterator pointing to the first element with key
//! greater than x, or end() if such an element is not found.
//!
//! <b>Complexity</b>: Logarithmic
template<typename K>

View File

@@ -460,6 +460,7 @@ class small_vector_base
this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin()))
, boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end ()))
);
x.clear();
}
}
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED

View File

@@ -434,13 +434,13 @@ class stable_vector_iterator
#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
#define STABLE_VECTOR_CHECK_INVARIANT \
#define BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT \
invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \
BOOST_JOIN(check_invariant_,__LINE__).touch();
#else //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
#define STABLE_VECTOR_CHECK_INVARIANT
#define BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT
#endif //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
@@ -604,7 +604,7 @@ class stable_vector
BOOST_CONTAINER_FORCEINLINE stable_vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<ValueAllocator>::value)
: internal_data(), index()
{
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
}
//! <b>Effects</b>: Constructs a stable_vector taking the allocator as parameter.
@@ -615,7 +615,7 @@ class stable_vector
BOOST_CONTAINER_FORCEINLINE explicit stable_vector(const allocator_type& al) BOOST_NOEXCEPT_OR_NOTHROW
: internal_data(al), index(al)
{
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
}
//! <b>Effects</b>: Constructs a stable_vector
@@ -630,7 +630,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n);
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -648,7 +648,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n, default_init);
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -664,7 +664,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n);
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -682,7 +682,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->resize(n, default_init);
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -698,7 +698,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cend(), n, t);
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -715,7 +715,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cend(), first, last);
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -732,7 +732,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cend(), x.begin(), x.end());
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -749,7 +749,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
insert(cend(), il.begin(), il.end());
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
#endif
@@ -775,7 +775,7 @@ class stable_vector
{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cend(), x.begin(), x.end());
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
@@ -795,7 +795,7 @@ class stable_vector
else{
stable_vector_detail::clear_on_destroy<stable_vector> cod(*this);
this->insert(this->cend(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
cod.release();
}
}
@@ -822,7 +822,7 @@ class stable_vector
//! <b>Complexity</b>: Linear to the number of elements in x.
stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
{
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
if (BOOST_LIKELY(this != &x)) {
node_allocator_type &this_alloc = this->priv_node_alloc();
const node_allocator_type &x_alloc = x.priv_node_alloc();
@@ -865,7 +865,7 @@ class stable_vector
//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){
STABLE_VECTOR_CHECK_INVARIANT
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT
//Destroy objects but retain memory in case x reuses it in the future
this->clear();
//Move allocator if needed
@@ -889,7 +889,7 @@ class stable_vector
//! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
stable_vector& operator=(std::initializer_list<value_type> il)
{
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
assign(il.begin(), il.end());
return *this;
}
@@ -920,7 +920,7 @@ class stable_vector
#endif
assign(InputIterator first,InputIterator last)
{
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
iterator first1 = this->begin();
iterator last1 = this->end();
for ( ; first1 != last1 && first != last; ++first1, ++first)
@@ -941,7 +941,7 @@ class stable_vector
//!
BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list<value_type> il)
{
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
assign(il.begin(), il.end());
}
#endif
@@ -1124,7 +1124,7 @@ class stable_vector
void resize(size_type n)
{
typedef value_init_construct_iterator<value_type, difference_type> value_init_iterator;
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
if(n > this->size())
this->insert(this->cend(), value_init_iterator(n - this->size()), value_init_iterator());
else if(n < this->size())
@@ -1142,7 +1142,7 @@ class stable_vector
void resize(size_type n, default_init_t)
{
typedef default_init_construct_iterator<value_type, difference_type> default_init_iterator;
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
if(n > this->size())
this->insert(this->cend(), default_init_iterator(n - this->size()), default_init_iterator());
else if(n < this->size())
@@ -1157,7 +1157,7 @@ class stable_vector
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
void resize(size_type n, const T& t)
{
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
if(n > this->size())
this->insert(this->cend(), n - this->size(), t);
else if(n < this->size())
@@ -1190,7 +1190,7 @@ class stable_vector
//! <b>Throws</b>: If memory allocation allocation throws.
void reserve(size_type n)
{
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
if(n > this->max_size()){
throw_length_error("stable_vector::reserve max_size() exceeded");
}
@@ -1562,7 +1562,7 @@ class stable_vector
iterator insert(const_iterator p, size_type n, const T& t)
{
BOOST_ASSERT(this->priv_in_range_or_end(p));
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
typedef constant_iterator<value_type, difference_type> cvalue_iterator;
return this->insert(p, cvalue_iterator(t, n), cvalue_iterator());
}
@@ -1579,7 +1579,7 @@ class stable_vector
BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, std::initializer_list<value_type> il)
{
//Position checks done by insert()
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
return insert(p, il.begin(), il.end());
}
#endif
@@ -1608,7 +1608,7 @@ class stable_vector
)
{
BOOST_ASSERT(this->priv_in_range_or_end(p));
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
const size_type pos_n = p - this->cbegin();
for(; first != last; ++first){
this->emplace(p, *first);
@@ -1678,7 +1678,7 @@ class stable_vector
BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{
BOOST_ASSERT(this->priv_in_range(p));
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
const size_type d = p - this->cbegin();
index_iterator it = this->index.begin() + d;
this->priv_delete_node(p.node_pointer());
@@ -1697,7 +1697,7 @@ class stable_vector
{
BOOST_ASSERT(first == last ||
(first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last)));
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
const const_iterator cbeg(this->cbegin());
const size_type d1 = static_cast<size_type>(first - cbeg),
d2 = static_cast<size_type>(last - cbeg);
@@ -1733,7 +1733,7 @@ class stable_vector
BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
allocator_traits_type::is_always_equal::value ||
this->get_stored_allocator() == x.get_stored_allocator());
STABLE_VECTOR_CHECK_INVARIANT;
BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT;
dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
dtl::swap_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
//vector's allocator is swapped here
@@ -2174,7 +2174,7 @@ stable_vector(InputIterator, InputIterator, Allocator const&) ->
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
#undef STABLE_VECTOR_CHECK_INVARIANT
#undef BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT
} //namespace container {

View File

@@ -1116,27 +1116,33 @@ public:
//! Constant O(1).
const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns container's capacity.
//!
//! @return container's capacity.
//!
//! @par Throws
//! Nothing.
//!
//! @par Complexity
//! Constant O(1).
static size_type capacity() BOOST_NOEXCEPT_OR_NOTHROW;
#endif //#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
//! @brief Returns container's capacity.
//!
//! @return container's capacity.
//!
//! @par Throws
//! Nothing.
//!
//! @par Complexity
//! Constant O(1).
static size_type max_size() BOOST_NOEXCEPT_OR_NOTHROW;
//! @brief Returns container's capacity.
//!
//! @return container's capacity.
//!
//! @par Throws
//! Nothing.
//!
//! @par Complexity
//! Constant O(1).
BOOST_CONTAINER_FORCEINLINE static size_type capacity() BOOST_NOEXCEPT_OR_NOTHROW
{ return static_capacity; }
//! @brief Returns container's capacity.
//!
//! @return container's capacity.
//!
//! @par Throws
//! Nothing.
//!
//! @par Complexity
//! Constant O(1).
BOOST_CONTAINER_FORCEINLINE static size_type max_size() BOOST_NOEXCEPT_OR_NOTHROW
{ return static_capacity; }
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
//! @brief Returns the number of stored elements.
//!

View File

@@ -712,7 +712,7 @@ class basic_string
: base_t(a)
{
this->priv_terminate_string();
if(a == this->alloc()){
if(s.alloc() == this->alloc()){
this->swap_data(s);
}
else{

View File

@@ -37,15 +37,15 @@ namespace container {
#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS)
//The user must provide definitions for the following functions
void throw_bad_alloc();
BOOST_NORETURN void throw_bad_alloc();
void throw_out_of_range(const char* str);
BOOST_NORETURN void throw_out_of_range(const char* str);
void throw_length_error(const char* str);
BOOST_NORETURN void throw_length_error(const char* str);
void throw_logic_error(const char* str);
BOOST_NORETURN void throw_logic_error(const char* str);
void throw_runtime_error(const char* str);
BOOST_NORETURN void throw_runtime_error(const char* str);
#elif defined(BOOST_NO_EXCEPTIONS)

File diff suppressed because it is too large Load Diff

View File

@@ -39,10 +39,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_set_test", "flat_set_t
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hash_table_test", "hash_table_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_test", "list_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792632}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@@ -383,10 +379,6 @@ Global
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792637}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.ActiveCfg = Release|Win32

View File

@@ -1515,7 +1515,7 @@ LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);
#pragma intrinsic (_InterlockedExchange)
#define interlockedcompareexchange _InterlockedCompareExchange
#define interlockedexchange _InterlockedExchange
#elif defined(WIN32) && defined(__GNUC__)
#elif defined(WIN32) && (defined(__GNUC__) || defined(__clang__))
#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)
#define interlockedexchange __sync_lock_test_and_set
#endif /* Win32 */

View File

@@ -791,21 +791,21 @@ static int internal_node_multialloc
/*Error if wrong element_size parameter */
if (!element_size ||
/*OR Error if n_elements less than contiguous_elements */
((contiguous_elements + 1) > (DL_MULTIALLOC_DEFAULT_CONTIGUOUS + 1) && n_elements < contiguous_elements) ||
((contiguous_elements + 1) > (BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS + 1) && n_elements < contiguous_elements) ||
/* OR Error if integer overflow */
(SQRT_MAX_SIZE_T < (element_req_size | contiguous_elements) &&
(MAX_SIZE_T / element_req_size) < contiguous_elements)) {
return 0;
}
switch (contiguous_elements) {
case DL_MULTIALLOC_DEFAULT_CONTIGUOUS:
case BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS:
{
/* Default contiguous, just check that we can store at least one element */
elements_per_segment = INTERNAL_MULTIALLOC_DEFAULT_CONTIGUOUS_MEM / element_req_size;
elements_per_segment += (size_t)(!elements_per_segment);
}
break;
case DL_MULTIALLOC_ALL_CONTIGUOUS:
case BOOST_CONTAINER_DL_MULTIALLOC_ALL_CONTIGUOUS:
/* All elements should be allocated in a single call */
elements_per_segment = n_elements;
break;
@@ -1002,11 +1002,11 @@ static int internal_multialloc_arrays
max_size = MAX_REQUEST/element_size;
/* Different sizes*/
switch(contiguous_elements){
case DL_MULTIALLOC_DEFAULT_CONTIGUOUS:
case BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS:
/* Use default contiguous mem */
boost_cont_multialloc_segmented_malloc_size = INTERNAL_MULTIALLOC_DEFAULT_CONTIGUOUS_MEM;
break;
case DL_MULTIALLOC_ALL_CONTIGUOUS:
case BOOST_CONTAINER_DL_MULTIALLOC_ALL_CONTIGUOUS:
boost_cont_multialloc_segmented_malloc_size = MAX_REQUEST + CHUNK_OVERHEAD;
break;
default:

View File

@@ -14,6 +14,7 @@
#include <boost/core/no_exceptions_support.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/container/detail/dlmalloc.hpp> //For global lock
#include <boost/container/detail/singleton.hpp>
#include <cstddef>
#include <new>
@@ -27,58 +28,63 @@ class new_delete_resource_imp
{
public:
virtual ~new_delete_resource_imp()
~new_delete_resource_imp() BOOST_OVERRIDE
{}
virtual void* do_allocate(std::size_t bytes, std::size_t alignment)
void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
{ (void)bytes; (void)alignment; return new char[bytes]; }
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment)
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
{ (void)bytes; (void)alignment; delete[]((char*)p); }
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT
bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE
{ return &other == this; }
} new_delete_resource_instance;
};
struct null_memory_resource_imp
: public memory_resource
{
public:
virtual ~null_memory_resource_imp()
~null_memory_resource_imp() BOOST_OVERRIDE
{}
virtual void* do_allocate(std::size_t bytes, std::size_t alignment)
void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
{
(void)bytes; (void)alignment;
throw_bad_alloc();
return 0;
}
virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment)
void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE
{ (void)p; (void)bytes; (void)alignment; }
virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT
bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE
{ return &other == this; }
} null_memory_resource_instance;
};
BOOST_CONTAINER_DECL memory_resource* new_delete_resource() BOOST_NOEXCEPT
{
return &new_delete_resource_instance;
return &boost::container::dtl::singleton_default<new_delete_resource_imp>::instance();
}
BOOST_CONTAINER_DECL memory_resource* null_memory_resource() BOOST_NOEXCEPT
{
return &null_memory_resource_instance;
return &boost::container::dtl::singleton_default<null_memory_resource_imp>::instance();
}
static memory_resource *default_memory_resource = &new_delete_resource_instance;
static memory_resource *default_memory_resource =
&boost::container::dtl::singleton_default<new_delete_resource_imp>::instance();
BOOST_CONTAINER_DECL memory_resource* set_default_resource(memory_resource* r) BOOST_NOEXCEPT
{
//TO-DO: synchronizes-with part using atomics
if(dlmalloc_global_sync_lock()){
memory_resource *previous = default_memory_resource;
if(!previous){
//function called before main, default_memory_resource is not initialized yet
previous = new_delete_resource();
}
default_memory_resource = r ? r : new_delete_resource();
dlmalloc_global_sync_unlock();
return previous;
@@ -93,6 +99,10 @@ BOOST_CONTAINER_DECL memory_resource* get_default_resource() BOOST_NOEXCEPT
//TO-DO: synchronizes-with part using atomics
if(dlmalloc_global_sync_lock()){
memory_resource *current = default_memory_resource;
if(!current){
//function called before main, default_memory_resource is not initialized yet
current = new_delete_resource();
}
dlmalloc_global_sync_unlock();
return current;
}

View File

@@ -141,6 +141,9 @@ void* monotonic_buffer_resource::do_allocate(std::size_t bytes, std::size_t alig
//See if there is room in current buffer
std::size_t aligner = 0u;
if(this->remaining_storage(alignment, aligner) < bytes){
//The new buffer will be aligned to the strictest alignment so reset
//the aligner, which was needed for the old buffer.
aligner = 0u;
//Update next_buffer_size to at least bytes
this->increase_next_buffer_at_least_to(bytes);
//Now allocate and update internal data

View File

@@ -512,7 +512,7 @@ bool test_many_equal_allocation()
for(int i = 0; i != NumIt/10; ++i){
dlmalloc_memchain chain;
BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
dlmalloc_multialloc_nodes((i+1)*2, i+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
dlmalloc_multialloc_nodes((i+1)*2, i+1, BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
break;
@@ -624,7 +624,7 @@ bool test_many_different_allocation()
for(int i = 0; i != NumIt; ++i){
dlmalloc_memchain chain;
BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
dlmalloc_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
dlmalloc_multialloc_arrays(ArraySize, requested_sizes, 1, BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
break;
@@ -702,7 +702,7 @@ bool test_many_deallocation()
for(int i = 0; i != NumIt; ++i){
dlmalloc_memchain chain;
BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
dlmalloc_multialloc_arrays(ArraySize, requested_sizes, 1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
dlmalloc_multialloc_arrays(ArraySize, requested_sizes, 1, BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
return false;
@@ -720,7 +720,7 @@ bool test_many_deallocation()
for(int i = 0; i != NumIt; ++i){
dlmalloc_memchain chain;
BOOST_CONTAINER_MEMCHAIN_INIT(&chain);
dlmalloc_multialloc_nodes(ArraySize, i*4+1, DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
dlmalloc_multialloc_nodes(ArraySize, i*4+1, BOOST_CONTAINER_DL_MULTIALLOC_DEFAULT_CONTIGUOUS, &chain);
dlmalloc_memchain_it it = BOOST_CONTAINER_MEMCHAIN_BEGIN_IT(&chain);
if(BOOST_CONTAINER_MEMCHAIN_IS_END_IT(chain, it))
return false;

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <cstddef>
#include <boost/container/allocator_traits.hpp>
#include <boost/static_assert.hpp>
@@ -444,4 +443,3 @@ int main()
return ::boost::report_errors();
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -8,7 +8,6 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/deque.hpp>
#include <boost/container/allocator.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::container;

View File

@@ -7,8 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <memory>
#include <deque>
#include <iostream>
@@ -100,6 +98,10 @@ class recursive_deque
{
public:
recursive_deque (const recursive_deque &x)
: deque_(x.deque_)
{}
recursive_deque & operator=(const recursive_deque &x)
{ this->deque_ = x.deque_; return *this; }
@@ -420,27 +422,21 @@ int main ()
typedef boost::container::deque<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value)
, "has_trivial_destructor_after_move(std::allocator) test failed");
}
// std::allocator
{
typedef boost::container::deque<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value)
, "has_trivial_destructor_after_move(std::allocator) test failed");
}
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,121 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/devector.hpp>
#include <boost/container/allocator.hpp>
#include <boost/container/detail/next_capacity.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::container;
template<class Unsigned, class DevectorType>
void test_stored_size_type_impl()
{
DevectorType v;
typedef typename DevectorType::size_type size_type;
typedef typename DevectorType::value_type value_type;
size_type const max = Unsigned(-1);
v.resize(5);
v.resize(max);
BOOST_TEST_THROWS(v.resize(max+1), std::exception);
BOOST_TEST_THROWS(v.push_back(value_type(1)), std::exception);
BOOST_TEST_THROWS(v.insert(v.begin(), value_type(1)), std::exception);
BOOST_TEST_THROWS(v.emplace(v.begin(), value_type(1)),std::exception);
BOOST_TEST_THROWS(v.reserve(max+1), std::exception);
BOOST_TEST_THROWS(DevectorType v2(max+1), std::exception);
}
template<class Unsigned>
void test_stored_size_type()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = devector_options_t< stored_size<Unsigned> >;
#else
typedef typename devector_options
< stored_size<Unsigned> >::type options_t;
#endif
//Test first with a typical allocator
{
typedef devector<unsigned char, new_allocator<unsigned char>, options_t> devector_t;
test_stored_size_type_impl<Unsigned, devector_t>();
}
//Test with a V2 allocator
{
typedef devector<unsigned char, allocator<unsigned char>, options_t> devector_t;
test_stored_size_type_impl<Unsigned, devector_t>();
}
}
void test_growth_factor_50()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = devector_options_t< growth_factor<growth_factor_50> >;
#else
typedef devector_options
< growth_factor<growth_factor_50> >::type options_t;
#endif
devector<int, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == old_capacity + old_capacity/2);
}
void test_growth_factor_60()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = devector_options_t< growth_factor<growth_factor_60> >;
#else
typedef devector_options
< growth_factor<growth_factor_60> >::type options_t;
#endif
devector<int, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == old_capacity + 3*old_capacity/5);
}
void test_growth_factor_100()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = devector_options_t< growth_factor<growth_factor_100> >;
#else
typedef devector_options
< growth_factor<growth_factor_100> >::type options_t;
#endif
devector<int, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == 2*old_capacity);
}
int main()
{
test_growth_factor_50();
test_growth_factor_60();
test_growth_factor_100();
test_stored_size_type<unsigned char>();
test_stored_size_type<unsigned short>();
return ::boost::report_errors();
}

3932
test/devector_test.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -78,6 +78,7 @@ template< class T
, bool PropagateOnContMoveAssign
, bool PropagateOnContSwap
, bool CopyOnPropagateOnContSwap
, bool EqualIfEqualIds
>
class propagation_test_allocator
{
@@ -99,7 +100,8 @@ class propagation_test_allocator
, PropagateOnContCopyAssign
, PropagateOnContMoveAssign
, PropagateOnContSwap
, CopyOnPropagateOnContSwap> other;
, CopyOnPropagateOnContSwap
, EqualIfEqualIds> other;
};
propagation_test_allocator select_on_container_copy_construction() const
@@ -129,7 +131,8 @@ class propagation_test_allocator
, PropagateOnContCopyAssign
, PropagateOnContMoveAssign
, PropagateOnContSwap
, CopyOnPropagateOnContSwap> &x)
, CopyOnPropagateOnContSwap
, EqualIfEqualIds> &x)
: id_(x.id_)
, ctr_copies_(x.ctr_copies_+1)
, ctr_moves_(0)
@@ -178,11 +181,11 @@ class propagation_test_allocator
void deallocate(T*p, std::size_t)
{ delete[] ((char*)p);}
friend bool operator==(const propagation_test_allocator &, const propagation_test_allocator &)
{ return true; }
friend bool operator==(const propagation_test_allocator &a, const propagation_test_allocator &b)
{ return EqualIfEqualIds ? a.id_ == b.id_ : true; }
friend bool operator!=(const propagation_test_allocator &, const propagation_test_allocator &)
{ return false; }
friend bool operator!=(const propagation_test_allocator &a, const propagation_test_allocator &b)
{ return EqualIfEqualIds ? a.id_ != b.id_ : false; }
void swap(propagation_test_allocator &r)
{
@@ -214,12 +217,15 @@ template< class T
, bool PropagateOnContMoveAssign
, bool PropagateOnContSwap
, bool CopyOnPropagateOnContSwap
, bool EqualIfEqualIds
>
unsigned int propagation_test_allocator< T
, PropagateOnContCopyAssign
, PropagateOnContMoveAssign
, PropagateOnContSwap
, CopyOnPropagateOnContSwap>::unique_id_ = 0;
, CopyOnPropagateOnContSwap
, EqualIfEqualIds
>::unique_id_ = 0;
} //namespace test {

View File

@@ -142,15 +142,12 @@ class expand_bwd_test_allocator
reuse = 0;
return (mp_buffer + m_offset);
}
else if(m_allocations == 1){
if(limit_size > m_size){
assert(0);
}
++m_allocations;
return mp_buffer;
}
else{
throw_bad_alloc();
if(m_allocations != 1){
throw_bad_alloc();
}
assert(limit_size <= m_size);
++m_allocations;
return mp_buffer;
}
}

View File

@@ -0,0 +1,41 @@
//////////////////////////////////////////////////////////////////////////////
//
// \(C\) Copyright Benedek Thaler 2015-2016
// \(C\) Copyright Ion Gaztanaga 2019-2020. 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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/devector.hpp>
#include "movable_int.hpp"
struct empty
{
friend bool operator == (const empty &, const empty &){ return true; }
friend bool operator < (const empty &, const empty &){ return true; }
};
template class ::boost::container::devector<empty>;
namespace boost {
namespace container {
//Test stored_size option
template class devector< test::movable_and_copyable_int
, new_allocator<test::movable_and_copyable_int>
, devector_options< stored_size<unsigned short> >::type
>;
} //namespace container {
} //namespace boost {
int main()
{
::boost::container::devector<empty> dummy;
(void)dummy;
return 0;
}

View File

@@ -38,6 +38,12 @@ template class boost::container::vector
template class vec_iterator<int*, true >;
template class vec_iterator<int*, false>;
//Test stored_size option
template class boost::container::vector< test::movable_and_copyable_int
, new_allocator<test::movable_and_copyable_int>
, vector_options< stored_size<unsigned short> >::type
>;
} //namespace boost {
} //namespace container {

View File

@@ -12,7 +12,9 @@
#include <boost/container/static_vector.hpp>
#include <boost/container/stable_vector.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/devector.hpp>
#include <boost/container/deque.hpp>
#include <boost/static_assert.hpp>
#include <boost/container/detail/container_or_allocator_rebind.hpp>
@@ -98,6 +100,29 @@ int main()
std::cout << "Error in map_test<deque<std::pair<int, int> > >" << std::endl;
return 1;
}
if (0 != test::map_test
< GetMapContainer<devector<std::pair<int, int> > >::apply<int>::map_type
, MyStdMap
, GetMapContainer<devector<std::pair<int, int> > >::apply<int>::multimap_type
, MyStdMultiMap>()) {
std::cout << "Error in map_test<vector<std::pair<int, int> > >" << std::endl;
return 1;
}
}
{
using namespace boost::container;
using boost::container::dtl::is_same;
typedef flat_map<int, float, std::less<int>, small_vector<std::pair<int, float>, 10> > map_container_t;
typedef flat_multimap<int, float, std::less<int>, small_vector<std::pair<int, float>, 10> > multimap_container_t;
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
BOOST_STATIC_ASSERT(( is_same<map_container_t, small_flat_map<int, float, 10> >::value ));
BOOST_STATIC_ASSERT(( is_same<multimap_container_t, small_flat_multimap<int, float, 10> >::value ));
#endif
BOOST_STATIC_ASSERT(( is_same<map_container_t, small_flat_map_of<int, float, 10>::type >::value ));
BOOST_STATIC_ASSERT(( is_same<multimap_container_t, small_flat_multimap_of<int, float, 10>::type >::value ));
}
return 0;

View File

@@ -7,8 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <vector>
#include <boost/container/flat_map.hpp>
@@ -834,5 +832,3 @@ int main()
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -13,6 +13,8 @@
#include <boost/container/stable_vector.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/deque.hpp>
#include <boost/container/devector.hpp>
#include <boost/static_assert.hpp>
#include <boost/container/detail/container_or_allocator_rebind.hpp>
@@ -95,6 +97,27 @@ int main()
std::cout << "Error in set_test<deque<int> >" << std::endl;
return 1;
}
if (0 != test::set_test
< GetSetContainer<devector<int> >::apply<int>::set_type
, MyStdSet
, GetSetContainer<devector<int> >::apply<int>::multiset_type
, MyStdMultiSet>()) {
std::cout << "Error in set_test<deque<int> >" << std::endl;
return 1;
}
}
{
using namespace boost::container;
using boost::container::dtl::is_same;
typedef flat_set<int, std::less<int>, small_vector<int, 10> > set_container_t;
typedef flat_multiset<int, std::less<int>, small_vector<int, 10> > multiset_container_t;
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
BOOST_STATIC_ASSERT(( is_same<set_container_t, small_flat_set<int, 10> >::value ));
BOOST_STATIC_ASSERT(( is_same<multiset_container_t, small_flat_multiset<int, 10> >::value ));
#endif
BOOST_STATIC_ASSERT(( is_same<set_container_t, small_flat_set_of<int, 10>::type >::value ));
BOOST_STATIC_ASSERT(( is_same<multiset_container_t, small_flat_multiset_of<int, 10>::type >::value ));
}
return 0;

119
test/input_iterator.hpp Normal file
View File

@@ -0,0 +1,119 @@
//////////////////////////////////////////////////////////////////////////////
//
// \(C\) Copyright Benedek Thaler 2015-2016
// \(C\) Copyright Ion Gaztanaga 2019-2020. 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://erenon.hu/double_ended for documentation.
//
//////////////////////////////////////////////////////////////////////////////
/**
* Emulates input iterator, validates algorithm
* does a single pass only, removes visited elements.
*
* Container::erase(front_iterator) must not invalidate other iterators.
*
* The hack around `_erase_on_destroy` is required to make `*it++` work.
*/
template <typename Container>
class input_iterator
{
typedef typename Container::iterator iterator;
public:
typedef std::input_iterator_tag iterator_category;
typedef typename Container::value_type value_type;
typedef typename Container::pointer pointer;
typedef typename Container::reference reference;
typedef typename Container::difference_type difference_type;
struct erase_on_destroy {};
public:
input_iterator()
: _container()
, _it()
, _erase_on_destroy()
{}
input_iterator(Container& c, iterator it)
:_container(&c)
, _it(it)
, _erase_on_destroy()
{}
input_iterator(const input_iterator& rhs)
:_container(rhs._container),
_it(rhs._it),
_erase_on_destroy(rhs._erase_on_destroy)
{
rhs._erase_on_destroy = false;
}
input_iterator & operator=(const input_iterator& rhs)
{
_container = rhs._container;
_it = rhs._it;
_erase_on_destroy = rhs._erase_on_destroy;
rhs._erase_on_destroy = false;
return *this;
}
input_iterator(const input_iterator& rhs, erase_on_destroy)
:_container(rhs._container),
_it(rhs._it),
_erase_on_destroy(true)
{}
~input_iterator()
{
if (_erase_on_destroy)
{
_container->erase(_it); // must not invalidate other iterators
}
}
const value_type& operator*()
{
return *_it;
}
input_iterator operator++()
{
_container->erase(_it);
++_it;
return *this;
}
input_iterator operator++(int)
{
input_iterator old(*this, erase_on_destroy());
++_it;
return old;
}
friend bool operator==(const input_iterator a, const input_iterator b)
{
return a._it == b._it;
}
friend bool operator!=(const input_iterator a, const input_iterator b)
{
return !(a == b);
}
private:
Container* _container;
iterator _it;
mutable bool _erase_on_destroy;
};
template <typename Container>
input_iterator<Container> make_input_iterator(Container& c, typename Container::iterator it)
{
return input_iterator<Container>(c, it);
}

View File

@@ -8,7 +8,6 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/list.hpp>
#include <boost/container/adaptive_pool.hpp>
@@ -55,6 +54,10 @@ public:
list<recursive_list>::reverse_iterator rit_;
list<recursive_list>::const_reverse_iterator crit_;
recursive_list(const recursive_list &o)
: list_(o.list_)
{}
recursive_list &operator=(const recursive_list &o)
{ list_ = o.list_; return *this; }
};
@@ -260,27 +263,23 @@ int main ()
typedef boost::container::list<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
boost::has_trivial_destructor_after_move<pointer>::value)
, "has_trivial_destructor_after_move(default allocator) test failed");
}
// std::allocator
{
typedef boost::container::list<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
boost::has_trivial_destructor_after_move<pointer>::value)
, "has_trivial_destructor_after_move(std::allocator) test failed");
}
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/map.hpp>
#include <boost/container/adaptive_pool.hpp>
@@ -28,6 +27,13 @@ typedef std::pair<const test::movable_and_copyable_int, test::movable_and_copyab
class recursive_map
{
public:
recursive_map()
{}
recursive_map(const recursive_map &x)
: map_(x.map_)
{}
recursive_map & operator=(const recursive_map &x)
{ id_ = x.id_; map_ = x.map_; return *this; }
@@ -45,6 +51,13 @@ class recursive_map
class recursive_multimap
{
public:
recursive_multimap()
{}
recursive_multimap(const recursive_multimap &x)
: multimap_(x.multimap_)
{}
recursive_multimap & operator=(const recursive_multimap &x)
{ id_ = x.id_; multimap_ = x.multimap_; return *this; }
@@ -645,21 +658,19 @@ int main ()
{
typedef boost::container::map<int, int> cont;
typedef boost::container::dtl::tree<value_type, int, std::less<int>, void, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(map, default allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value)
, "has_trivial_destructor_after_move(map, default allocator) test failed");
}
// std::allocator
{
typedef boost::container::map<int, int, std::less<int>, std::allocator<value_type> > cont;
typedef boost::container::dtl::tree<value_type, int, std::less<int>, std::allocator<value_type>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(map, std::allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value)
, "has_trivial_destructor_after_move(map, std::allocator) test failed");
}
//
// multimap
@@ -669,25 +680,21 @@ int main ()
// default allocator
typedef boost::container::multimap<int, int> cont;
typedef boost::container::dtl::tree<value_type, int, std::less<int>, void, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(multimap, default allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value)
, "has_trivial_destructor_after_move(multimap, default allocator) test failed");
}
// std::allocator
{
typedef boost::container::multimap<int, int, std::less<int>, std::allocator<value_type> > cont;
typedef boost::container::dtl::tree<value_type, int, std::less<int>, std::allocator<value_type>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(multimap, std::allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value)
, "has_trivial_destructor_after_move(multimap, std::allocator) test failed");
}
}
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -24,6 +24,7 @@
#include <boost/core/lightweight_test.hpp>
#include <boost/static_assert.hpp>
#include <cstring>
#include <iterator>
#include <new>
using namespace boost::container;
@@ -56,6 +57,40 @@ BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reverse_iterator)
}}} //namespace boost::container::test {
template<class RandomAccessIterator>
void check_plus_zero_impl(RandomAccessIterator it)
{
RandomAccessIterator cpy(it + 0);
BOOST_TEST(cpy == it);
}
template<class Container, class Category>
void check_plus_zero(const Category&)
{}
template<class Container>
void check_plus_zero(const std::random_access_iterator_tag&)
{
check_plus_zero_impl(typename Container::iterator());
check_plus_zero_impl(typename Container::const_iterator());
check_plus_zero_impl(typename Container::reverse_iterator());
check_plus_zero_impl(typename Container::const_reverse_iterator());
Container c;
check_plus_zero_impl(c.begin());
check_plus_zero_impl(c.cbegin());
check_plus_zero_impl(c.rbegin());
check_plus_zero_impl(c.crbegin());
}
template<class Container>
void check_plus_zero()
{
typedef typename Container::iterator iterator;
typedef typename std::iterator_traits<iterator>::iterator_category category;
category tag;
check_plus_zero<Container>(tag);
}
template<class Container>
void check_null_iterators()
{
@@ -77,20 +112,35 @@ void check_null_iterators()
int main()
{
check_null_iterators< vector<int> >();
check_plus_zero< vector<int> >();
check_null_iterators< deque<int> >();
check_plus_zero< deque<int> >();
check_null_iterators< stable_vector<int> >();
check_plus_zero< stable_vector<int> >();
check_null_iterators< static_vector<int, 1> >();
check_plus_zero< static_vector<int, 1> >();
check_null_iterators< string >();
check_plus_zero< string >();
check_null_iterators< list<int> >();
check_plus_zero< list<int> >();
check_null_iterators< slist<int> >();
check_plus_zero< slist<int> >();
check_null_iterators< map<int, int> >();
check_plus_zero< map<int, int> >();
check_null_iterators< multimap<int, int> >();
check_plus_zero< multimap<int, int> >();
check_null_iterators< set<int> >();
check_plus_zero< set<int> >();
check_null_iterators< multiset<int> >();
check_plus_zero< multiset<int> >();
check_null_iterators< flat_set<int> >();
check_plus_zero< flat_set<int> >();
check_null_iterators< flat_multiset<int> >();
check_plus_zero< flat_multiset<int> >();
check_null_iterators< flat_map<int, int> >();
check_plus_zero< flat_map<int, int> >();
check_null_iterators< flat_multimap<int, int> >();
check_plus_zero< flat_multimap<int, int> >();
return boost::report_errors();
}

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/pair.hpp>
#include "movable_int.hpp"
#include "emplace_test.hpp"
@@ -152,5 +151,3 @@ int main ()
#endif //#!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
return ::boost::report_errors();
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,26 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/pmr/devector.hpp>
#include <boost/static_assert.hpp>
#include <boost/container/detail/type_traits.hpp>
int main()
{
using namespace boost::container;
using boost::container::dtl::is_same;
typedef devector<int, growth_factor_60, pmr::polymorphic_allocator<int> > intcontainer_t;
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::devector_of<int>::type >::value ));
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
BOOST_STATIC_ASSERT(( is_same<intcontainer_t, pmr::devector<int> >::value ));
#endif
return 0;
}

View File

@@ -25,9 +25,6 @@ void test_default_constructor()
void test_resource_constructor()
{
polymorphic_allocator<int> a(0);
BOOST_TEST(a.resource() == get_default_resource());
derived_from_memory_resource d;
polymorphic_allocator<int> b(&d);
BOOST_TEST(&d == b.resource());

View File

@@ -110,7 +110,7 @@ template<class Selector>
bool test_propagate_allocator()
{
{
typedef propagation_test_allocator<char, true, true, true, true> AlwaysPropagate;
typedef propagation_test_allocator<char, true, true, true, true, true> AlwaysPropagate;
typedef alloc_propagate_wrapper<char, AlwaysPropagate, Selector> PropagateCont;
typedef typename get_real_stored_allocator<typename PropagateCont::Base>::type StoredAllocator;
{
@@ -213,7 +213,7 @@ bool test_propagate_allocator()
//Test NeverPropagate allocator propagation
//////////////////////////////////////////
{
typedef propagation_test_allocator<char, false, false, false, false> NeverPropagate;
typedef propagation_test_allocator<char, false, false, false, false, true> NeverPropagate;
typedef alloc_propagate_wrapper<char, NeverPropagate, Selector> NoPropagateCont;
typedef typename get_real_stored_allocator<typename NoPropagateCont::Base>::type StoredAllocator;
{
@@ -281,6 +281,15 @@ bool test_propagate_allocator()
BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);
}
//And now allocator argument constructors
test_propagate_allocator_allocator_arg<NoPropagateCont>();
}
{
//Don't use unequal ids as unequal allocators -------------------------|,
//because swap requires equal allocators v
typedef propagation_test_allocator<char, false, false, false, false, false> NeverPropagate;
typedef alloc_propagate_wrapper<char, NeverPropagate, Selector> NoPropagateCont;
typedef typename get_real_stored_allocator<typename NoPropagateCont::Base>::type StoredAllocator;
{
//swap
StoredAllocator::reset_unique_id(666);
@@ -302,8 +311,6 @@ bool test_propagate_allocator()
BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c.get_stored_allocator().swaps_ == 0);
}
//And now allocator argument constructors
test_propagate_allocator_allocator_arg<NoPropagateCont>();
}
return report_errors() == 0;

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/scoped_allocator_fwd.hpp>
// container/detail
@@ -1374,4 +1373,3 @@ int main()
return ::boost::report_errors();
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <memory>
#include <boost/move/utility_core.hpp>
@@ -59,18 +58,18 @@ public:
template <typename T> friend class SimpleAllocator;
friend bool operator == (const SimpleAllocator &, const SimpleAllocator &)
{ return true; }
friend bool operator == (const SimpleAllocator &a, const SimpleAllocator &b)
{ return a.m_state == b.m_state; }
friend bool operator != (const SimpleAllocator &, const SimpleAllocator &)
{ return false; }
friend bool operator != (const SimpleAllocator &a, const SimpleAllocator &b)
{ return a.m_state != b.m_state; }
};
class alloc_int
{
private: // Not copyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(alloc_int)
BOOST_COPYABLE_AND_MOVABLE(alloc_int)
public:
typedef SimpleAllocator<int> allocator_type;
@@ -87,13 +86,30 @@ class alloc_int
other.m_value = -1;
}
alloc_int(const alloc_int &other)
: m_value(other.m_value), m_allocator(boost::move(other.m_allocator))
{
}
alloc_int(const alloc_int &other, const allocator_type &allocator)
: m_value(other.m_value), m_allocator(allocator)
{
}
alloc_int(int value, const allocator_type &allocator)
: m_value(value), m_allocator(allocator)
{}
alloc_int & operator=(BOOST_RV_REF(alloc_int)other)
{
other.m_value = other.m_value;
m_value = other.m_value;
other.m_value = -1;
return *this;
}
alloc_int & operator=(const alloc_int &other)
{
m_value = other.m_value;
return *this;
}
@@ -368,24 +384,47 @@ bool one_level_allocator_propagation_test()
{
allocator_type al(SimpleAllocator<value_type>(4));
ContainerWrapper c2(al);
{
iterator it = c2.emplace(c2.cbegin(), 41);
if(!test_value_and_state_equals(*it, 41, 4))
return false;
}
ContainerWrapper c(::boost::move(c2), allocator_type(SimpleAllocator<value_type>(5)));
c.clear();
iterator it = c.emplace(c.cbegin(), 42);
if(!test_value_and_state_equals(*it, 42, 5))
if(!test_value_and_state_equals(*c.begin(), 41, 5))
return false;
}/*
{
c.clear();
iterator it = c.emplace(c.cbegin(), 42);
if(!test_value_and_state_equals(*it, 42, 5))
return false;
}
}
{
ContainerWrapper c2(allocator_type(SimpleAllocator<value_type>(3)));
allocator_type al(SimpleAllocator<value_type>(4));
ContainerWrapper c2(al);
{
iterator it = c2.emplace(c2.cbegin(), 41);
if(!test_value_and_state_equals(*it, 41, 4))
return false;
}
ContainerWrapper c(c2, allocator_type(SimpleAllocator<value_type>(5)));
c.clear();
iterator it = c.emplace(c.cbegin(), 42);
if(!test_value_and_state_equals(*it, 42, 5))
if(!test_value_and_state_equals(*c.begin(), 41, 5))
return false;
}*/
{
c.clear();
iterator it = c.emplace(c.cbegin(), 42);
if(!test_value_and_state_equals(*it, 42, 5))
return false;
}
}
return true;
}
@@ -424,5 +463,3 @@ int main()
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <set>
#include <boost/container/set.hpp>
#include <boost/container/adaptive_pool.hpp>
@@ -26,6 +25,13 @@ using namespace boost::container;
class recursive_set
{
public:
recursive_set()
{}
recursive_set(const recursive_set &x)
: set_(x.set_)
{}
recursive_set & operator=(const recursive_set &x)
{ id_ = x.id_; set_ = x.set_; return *this; }
@@ -44,6 +50,13 @@ public:
class recursive_multiset
{
public:
recursive_multiset()
{}
recursive_multiset(const recursive_multiset &x)
: multiset_(x.multiset_)
{}
recursive_multiset & operator=(const recursive_multiset &x)
{ id_ = x.id_; multiset_ = x.multiset_; return *this; }
@@ -612,44 +625,38 @@ int main ()
{
typedef boost::container::set<int> cont;
typedef boost::container::dtl::tree<int, void, std::less<int>, void, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(set, default allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value)
, "has_trivial_destructor_after_move(set, default allocator) test failed");
}
// set, std::allocator
{
typedef boost::container::set<int, std::less<int>, std::allocator<int> > cont;
typedef boost::container::dtl::tree<int, void, std::less<int>, std::allocator<int>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(set, std::allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value)
, "has_trivial_destructor_after_move(set, std::allocator) test failed");
}
// multiset, default allocator
{
typedef boost::container::multiset<int> cont;
typedef boost::container::dtl::tree<int, void, std::less<int>, void, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(multiset, default allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value)
, "has_trivial_destructor_after_move(multiset, default allocator) test failed");
}
// multiset, std::allocator
{
typedef boost::container::multiset<int, std::less<int>, std::allocator<int> > cont;
typedef boost::container::dtl::tree<int, void, std::less<int>, std::allocator<int>, void> tree;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value) {
std::cerr << "has_trivial_destructor_after_move(multiset, std::allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<tree>::value)
, "has_trivial_destructor_after_move(multiset, std::allocator) test failed");
}
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/slist.hpp>
#include <boost/container/node_allocator.hpp>
@@ -31,6 +30,10 @@ public:
recursive_slist &operator=(const recursive_slist &o)
{ slist_ = o.slist_; return *this; }
recursive_slist (const recursive_slist &o)
: slist_(o.slist_)
{}
};
void recursive_slist_test()//Test for recursive types
@@ -263,28 +266,23 @@ int main ()
typedef boost::container::slist<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
boost::has_trivial_destructor_after_move<pointer>::value)
, "has_trivial_destructor_after_move(default allocator) test failed");
}
// std::allocator
{
typedef boost::container::slist<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
boost::has_trivial_destructor_after_move<pointer>::value)
, "has_trivial_destructor_after_move(std::allocator) test failed");
}
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -8,7 +8,6 @@
//
//////////////////////////////////////////////////////////////////////////////
#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
#include <boost/container/detail/config_begin.hpp>
#include <memory>
#include <boost/container/stable_vector.hpp>
@@ -36,6 +35,10 @@ class recursive_vector
stable_vector<recursive_vector>::reverse_iterator rit_;
stable_vector<recursive_vector>::const_reverse_iterator crit_;
recursive_vector (const recursive_vector &o)
: vector_(o.vector_)
{}
recursive_vector &operator=(const recursive_vector &o)
{ vector_ = o.vector_; return *this; }
};
@@ -201,27 +204,23 @@ int main()
typedef boost::container::stable_vector<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
boost::has_trivial_destructor_after_move<pointer>::value)
, "has_trivial_destructor_after_move(default allocator) test failed");
}
// std::allocator
{
typedef boost::container::stable_vector<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
BOOST_STATIC_ASSERT_MSG(
!(boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
boost::has_trivial_destructor_after_move<pointer>::value)
, "has_trivial_destructor_after_move(std::allocator) test failed");
}
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -7,17 +7,13 @@
// Use, modification and distribution is subject to 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)
#include <boost/container/detail/config_begin.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/stable_vector.hpp>
#include <boost/container/list.hpp>
#include <boost/container/detail/iterator.hpp>
#include "../../intrusive/test/iterator_test.hpp"
#include <vector>
#include <list>
#include "static_vector_test.hpp"
@@ -43,12 +39,10 @@ void test_ctor_nc(size_t n)
BOOST_TEST_THROWS( s.at(n), std::out_of_range );
if ( 1 < n )
{
T val10(10);
s[0] = val10;
s[0] = 10;
BOOST_TEST(T(10) == s[0]);
BOOST_TEST(T(10) == s.at(0));
T val20(20);
s.at(1) = val20;
s.at(1) = 20;
BOOST_TEST(T(20) == s[1]);
BOOST_TEST(T(20) == s.at(1));
}
@@ -123,12 +117,10 @@ void test_resize_nc(size_t n)
BOOST_TEST_THROWS( s.at(n), std::out_of_range );
if ( 1 < n )
{
T val10(10);
s[0] = val10;
s[0] = 10;
BOOST_TEST(T(10) == s[0]);
BOOST_TEST(T(10) == s.at(0));
T val20(20);
s.at(1) = val20;
s.at(1) = 20;
BOOST_TEST(T(20) == s[1]);
BOOST_TEST(T(20) == s.at(1));
}
@@ -232,8 +224,8 @@ template <typename T, size_t N>
void test_copy_and_assign_nd(T const& val)
{
static_vector<T, N> s;
std::vector<T> v;
std::list<T> l;
vector<T> v;
list<T> l;
for ( size_t i = 0 ; i < N ; ++i )
{
@@ -266,22 +258,17 @@ void test_copy_and_assign_nd(T const& val)
{
static_vector<T, N> s1(s);
test_compare_ranges(s.begin(), s.end(), s1.begin(), s1.end());
std::vector<T> a(N, val);
vector<T> a(N, val);
s1.assign(N, val);
test_compare_ranges(a.begin(), a.end(), s1.begin(), s1.end());
}
stable_vector<T> bsv(s.begin(), s.end());
vector<T> bv(s.begin(), s.end());
test_copy_and_assign<T, N>(bsv);
test_copy_and_assign<T, N>(bv);
}
template <typename T, size_t N>
void test_iterators_nd()
{
static_vector<T, N> s;
std::vector<T> v;
vector<T> v;
for ( size_t i = 0 ; i < N ; ++i )
{
@@ -371,8 +358,8 @@ void test_insert_nd(T const& val)
size_t h = N/2;
static_vector<T, N> s, ss;
std::vector<T> v;
std::list<T> l;
vector<T> v;
list<T> l;
typedef typename static_vector<T, N>::iterator It;
@@ -420,11 +407,6 @@ void test_insert_nd(T const& val)
test_insert<T, N>(s, ss);
test_insert<T, N>(s, v);
test_insert<T, N>(s, l);
stable_vector<T> bsv(ss.begin(), ss.end());
vector<T> bv(ss.begin(), ss.end());
test_insert<T, N>(s, bv);
test_insert<T, N>(s, bsv);
}
template <typename T>
@@ -496,11 +478,9 @@ void test_swap_and_move_nd()
BOOST_TEST(v1.size() == N/2);
BOOST_TEST(s1.size() == N);
//iG moving does not imply emptying source
//BOOST_TEST(v2.size() == 0);
BOOST_TEST(v2.size() == 0);
BOOST_TEST(s2.size() == N);
//iG moving does not imply emptying source
//BOOST_TEST(v3.size() == 0);
BOOST_TEST(v3.size() == 0);
BOOST_TEST(s3.size() == N);
BOOST_TEST(v4.size() == N/2);
BOOST_TEST(s4.size() == N);
@@ -824,4 +804,45 @@ int main(int, char* [])
return boost::report_errors();
}
#include <boost/container/detail/config_end.hpp>
/*
#include <boost/container/small_vector.hpp>
#include <type_traits>
struct S_trivial {
int i;
};
static_assert(std::is_nothrow_move_constructible<S_trivial>::value, "");
static_assert(std::is_nothrow_move_assignable<S_trivial>::value, "");
struct S1 {
int i = 0;
};
static_assert(std::is_nothrow_move_constructible<S1>::value, "");
static_assert(std::is_nothrow_move_assignable<S1>::value, "");
struct S2 {
int i = 0;
S2(S2&&) noexcept;
S2& operator=(S2&&) noexcept;
};
static_assert(std::is_nothrow_move_constructible<S2>::value, "");
static_assert(std::is_nothrow_move_assignable<S2>::value, "");
// Succeed
static_assert(std::is_nothrow_move_constructible<boost::container::small_vector<S_trivial, 1>>::value, "");
static_assert(std::is_nothrow_move_assignable<boost::container::small_vector<S_trivial, 1>>::value, "");
// Fail
static_assert(std::is_nothrow_move_constructible<boost::container::small_vector<S1, 1>>::value, "");
static_assert(std::is_nothrow_move_assignable<boost::container::small_vector<S1, 1>>::value, "");
// Fail
static_assert(std::is_nothrow_move_constructible<boost::container::small_vector<S2, 1>>::value, "");
static_assert(std::is_nothrow_move_assignable<boost::container::small_vector<S2, 1>>::value, "");
int main()
{
return 0;
}
*/

View File

@@ -48,11 +48,12 @@ class value_nc
public:
explicit value_nc(int a = 0) : aa(a) {}
~value_nc() {}
value_nc & operator=(int a){ aa = a; return *this; }
bool operator==(value_nc const& v) const { return aa == v.aa; }
bool operator<(value_nc const& v) const { return aa < v.aa; }
private:
value_nc(value_nc const&) {}
value_nc & operator=(value_ndc const&) { return *this; }
value_nc & operator=(value_nc const&) { return *this; }
int aa;
};
@@ -66,6 +67,7 @@ public:
counting_value(BOOST_RV_REF(counting_value) p) : aa(p.aa), bb(p.bb) { p.aa = 0; p.bb = 0; ++c(); } // Move constructor
counting_value& operator=(BOOST_RV_REF(counting_value) p) { aa = p.aa; p.aa = 0; bb = p.bb; p.bb = 0; return *this; } // Move assignment
counting_value& operator=(BOOST_COPY_ASSIGN_REF(counting_value) p) { aa = p.aa; bb = p.bb; return *this; } // Copy assignment
counting_value& operator=(int a) { aa =a; return *this; } // Copy assignment
~counting_value() { --c(); }
bool operator==(counting_value const& v) const { return aa == v.aa && bb == v.bb; }
bool operator<(counting_value const& v) const { return aa < v.aa || ( aa == v.aa && bb < v.bb ); }
@@ -94,6 +96,9 @@ class shptr_value
typedef boost::shared_ptr<int> Ptr;
public:
explicit shptr_value(int a = 0) : m_ptr(new int(a)) {}
shptr_value & operator=(int a)
{ m_ptr.reset(new int(a)); return *this; }
bool operator==(shptr_value const& v) const { return *m_ptr == *(v.m_ptr); }
bool operator<(shptr_value const& v) const { return *m_ptr < *(v.m_ptr); }
private:

View File

@@ -8,7 +8,6 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/string.hpp>
#include <string>
@@ -592,5 +591,3 @@ int main()
return boost::report_errors();
}
#include <boost/container/detail/config_end.hpp>

319
test/test_elem.hpp Normal file
View File

@@ -0,0 +1,319 @@
//////////////////////////////////////////////////////////////////////////////
//
// \(C\) Copyright Benedek Thaler 2015-2016
// \(C\) Copyright Ion Gaztanaga 2019-2020. 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://erenon.hu/double_ended for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_TEST_ELEM_HPP
#define BOOST_CONTAINER_TEST_TEST_ELEM_HPP
#include <boost/utility/compare_pointees.hpp>
namespace boost {
namespace container {
struct test_exception {};
struct test_elem_throw
{
private:
static int throw_on_ctor_after /*= -1*/;
static int throw_on_copy_after /*= -1*/;
static int throw_on_move_after /*= -1*/;
public:
static void on_ctor_after(int x) { throw_on_ctor_after = x; }
static void on_copy_after(int x) { throw_on_copy_after = x; }
static void on_move_after(int x) { throw_on_move_after = x; }
static void do_not_throw()
{
throw_on_ctor_after = -1;
throw_on_copy_after = -1;
throw_on_move_after = -1;
}
static void in_constructor() { maybe_throw(throw_on_ctor_after); }
static void in_copy() { maybe_throw(throw_on_copy_after); }
static void in_move() { maybe_throw(throw_on_move_after); }
private:
static void maybe_throw(int& counter)
{
if (counter > 0)
{
--counter;
if (counter == 0)
{
--counter;
throw test_exception();
}
}
}
};
int test_elem_throw::throw_on_ctor_after = -1;
int test_elem_throw::throw_on_copy_after = -1;
int test_elem_throw::throw_on_move_after = -1;
struct test_elem_base
{
private:
BOOST_COPYABLE_AND_MOVABLE(test_elem_base)
public:
test_elem_base()
{
test_elem_throw::in_constructor();
_index = new int(0);
++_live_count;
}
test_elem_base(int index)
{
test_elem_throw::in_constructor();
_index = new int(index);
++_live_count;
}
explicit test_elem_base(const test_elem_base& rhs)
{
test_elem_throw::in_copy();
_index = new int(*rhs._index);
++_live_count;
}
test_elem_base(BOOST_RV_REF(test_elem_base) rhs)
{
test_elem_throw::in_move();
_index = rhs._index;
rhs._index = 0;
++_live_count;
}
test_elem_base &operator=(BOOST_COPY_ASSIGN_REF(test_elem_base) rhs)
{
test_elem_throw::in_copy();
if (_index) { delete _index; }
_index = new int(*rhs._index);
return *this;
}
test_elem_base &operator=(BOOST_RV_REF(test_elem_base) rhs)
{
test_elem_throw::in_move();
if (_index) { delete _index; }
_index = rhs._index;
rhs._index = 0;
return *this;
}
~test_elem_base()
{
if (_index) { delete _index; }
--_live_count;
}
friend bool operator==(const test_elem_base& a, const test_elem_base& b)
{
return a._index && b._index && *(a._index) == *(b._index);
}
friend bool operator==(int a, const test_elem_base& b)
{
return b._index != 0 && a == *(b._index);
}
friend bool operator==(const test_elem_base& a, int b)
{
return a._index != 0 && *(a._index) == b;
}
friend bool operator<(const test_elem_base& a, const test_elem_base& b)
{
return boost::less_pointees(a._index, b._index);
}
friend std::ostream& operator<<(std::ostream& out, const test_elem_base& elem)
{
if (elem._index) { out << *elem._index; }
else { out << "null"; }
return out;
}
template <typename Archive>
void serialize(Archive& ar, unsigned /* version */)
{
ar & *_index;
}
static bool no_living_elem()
{
return _live_count == 0;
}
private:
int* _index;
static int _live_count;
};
int test_elem_base::_live_count = 0;
struct regular_elem : test_elem_base
{
private:
BOOST_COPYABLE_AND_MOVABLE(regular_elem)
public:
regular_elem()
{}
regular_elem(int index) : test_elem_base(index) {}
regular_elem(const regular_elem& rhs)
:test_elem_base(rhs)
{}
regular_elem(BOOST_RV_REF(regular_elem) rhs)
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
{}
regular_elem &operator=(BOOST_COPY_ASSIGN_REF(regular_elem) rhs)
{
static_cast<test_elem_base&>(*this) = rhs;
return *this;
}
regular_elem &operator=(BOOST_RV_REF(regular_elem) rhs)
{
regular_elem &r = rhs;
static_cast<test_elem_base&>(*this) = boost::move(r);
return *this;
}
};
struct noex_move : test_elem_base
{
private:
BOOST_COPYABLE_AND_MOVABLE(noex_move)
public:
noex_move()
{}
noex_move(int index) : test_elem_base(index) {}
noex_move(const noex_move& rhs)
:test_elem_base(rhs)
{}
noex_move(BOOST_RV_REF(noex_move) rhs) BOOST_NOEXCEPT
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
{}
noex_move &operator=(BOOST_COPY_ASSIGN_REF(noex_move) rhs)
{
static_cast<test_elem_base&>(*this) = rhs;
return *this;
}
noex_move &operator=(BOOST_RV_REF(noex_move) rhs) BOOST_NOEXCEPT
{
noex_move & r = rhs;
static_cast<test_elem_base&>(*this) = boost::move(r);
return *this;
}
};
struct noex_copy : test_elem_base
{
private:
BOOST_COPYABLE_AND_MOVABLE(noex_copy)
public:
noex_copy(){}
noex_copy(int index) : test_elem_base(index) {}
noex_copy(const noex_copy& rhs) BOOST_NOEXCEPT
:test_elem_base(rhs)
{}
noex_copy(BOOST_RV_REF(noex_copy) rhs)
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
{}
noex_copy &operator=(BOOST_COPY_ASSIGN_REF(noex_copy) rhs) BOOST_NOEXCEPT
{
static_cast<test_elem_base&>(*this) = rhs;
return *this;
}
noex_copy &operator=(BOOST_RV_REF(noex_copy) rhs)
{
noex_copy &r = rhs;
static_cast<test_elem_base&>(*this) = boost::move(r);
return *this;
}
};
struct only_movable : test_elem_base
{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(only_movable)
public:
only_movable(){};
only_movable(int index) : test_elem_base(index) {}
only_movable(BOOST_RV_REF(only_movable) rhs)
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
{}
only_movable &operator=(BOOST_RV_REF(only_movable) rhs)
{
static_cast<test_elem_base&>(*this) = boost::move(rhs);
return *this;
}
};
struct no_default_ctor : test_elem_base
{
private:
BOOST_COPYABLE_AND_MOVABLE(no_default_ctor)
public:
no_default_ctor(int index) : test_elem_base(index) {}
no_default_ctor(const no_default_ctor& rhs)
:test_elem_base(rhs)
{}
no_default_ctor(BOOST_RV_REF(no_default_ctor) rhs)
:test_elem_base(BOOST_MOVE_BASE(test_elem_base, rhs))
{}
no_default_ctor &operator=(BOOST_RV_REF(no_default_ctor) rhs)
{
static_cast<test_elem_base&>(*this) = boost::move(rhs);
return *this;
}
no_default_ctor &operator=(BOOST_COPY_ASSIGN_REF(no_default_ctor) rhs)
{
static_cast<test_elem_base&>(*this) = rhs;
return *this;
}
};
}}
#endif //BOOST_CONTAINER_TEST_TEST_ELEM_HPP

139
test/test_util.hpp Normal file
View File

@@ -0,0 +1,139 @@
//////////////////////////////////////////////////////////////////////////////
//
// \(C\) Copyright Benedek Thaler 2015-2016
// \(C\) Copyright Ion Gaztanaga 2019-2020. 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://erenon.hu/double_ended for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_TEST_UTIL_HPP
#define BOOST_CONTAINER_TEST_TEST_UTIL_HPP
#include "test_elem.hpp"
// get_range
template <typename DeVector>
void get_range(int fbeg, int fend, int bbeg, int bend, DeVector &c)
{
c.clear();
for (int i = fend; i > fbeg ;)
{
c.emplace_front(--i);
}
for (int i = bbeg; i < bend; ++i)
{
c.emplace_back(i);
}
}
template <typename Container>
void get_range(int count, Container &c)
{
c.clear();
for (int i = 1; i <= count; ++i)
{
c.emplace_back(i);
}
}
template <typename Container>
void get_range(Container &c)
{
get_range<Container>(1, 13, 13, 25, c);
}
template <typename C1>
void test_equal_range(const C1& a)
{
BOOST_TEST(a.empty());
}
template <typename Iterator>
void print_range(std::ostream& out, Iterator b, Iterator e)
{
out << '[';
bool first = true;
for (; b != e; ++b)
{
if (first) { first = false; }
else { out << ','; }
out << *b;
}
out << ']';
}
template <typename Range>
void print_range(std::ostream& out, const Range& range)
{
print_range(out, range.cbegin(), range.cend());
}
template <typename Array, std::size_t N>
void print_range(std::ostream& out, Array (&range)[N])
{
print_range(out, range, range + N);
}
template <typename C1, typename C2, unsigned N>
void test_equal_range(const C1& a, const C2 (&b)[N])
{
bool equals = boost::algorithm::equal
(a.begin(), a.end(), b, b+N);
BOOST_TEST(equals);
if (!equals)
{
print_range(std::cerr, a);
std::cerr << "\n";
print_range(std::cerr, b);
std::cerr << "\n";
}
}
template <typename C1, typename C2>
void test_equal_range(const C1& a, const C2&b)
{
bool equals = boost::algorithm::equal
(a.begin(), a.end(), b.begin(), b.end());
BOOST_TEST(equals);
if (!equals)
{
print_range(std::cerr, a);
std::cerr << "\n";
print_range(std::cerr, b);
std::cerr << "\n";
}
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
// support initializer_list
template <typename C>
void test_equal_range(const C& a, std::initializer_list<unsigned> il)
{
typedef typename C::value_type T;
boost::container::vector<T> b;
for (auto&& elem : il)
{
b.emplace_back(elem);
}
test_equal_range(a, b);
}
#endif //#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
#endif //BOOST_CONTAINER_TEST_TEST_UTIL_HPP

View File

@@ -9,8 +9,6 @@
//////////////////////////////////////////////////////////////////////////////
#define BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/throw_exception.hpp>
#include <boost/core/lightweight_test.hpp>
@@ -22,24 +20,50 @@ static bool length_error_called = false;
static bool logic_error_called = false;
static bool runtime_error_called = false;
BOOST_NORETURN static void validate_and_never_return()
{
BOOST_TEST(bad_alloc_called == true);
BOOST_TEST(out_of_range_called == true);
BOOST_TEST(length_error_called == true);
BOOST_TEST(logic_error_called == true);
BOOST_TEST(runtime_error_called == true);
std::exit(::boost::report_errors());
}
//User defined throw implementations
namespace boost {
namespace container {
void throw_bad_alloc()
{ bad_alloc_called = true; }
BOOST_NORETURN void throw_bad_alloc()
{
bad_alloc_called = true;
throw_out_of_range("dummy");
}
void throw_out_of_range(const char* str)
{ (void)str; out_of_range_called = true; }
BOOST_NORETURN void throw_out_of_range(const char* str)
{
out_of_range_called = true;
throw_length_error(str);
}
void throw_length_error(const char* str)
{ (void)str; length_error_called = true; }
BOOST_NORETURN void throw_length_error(const char* str)
{
length_error_called = true;
throw_logic_error(str);
}
void throw_logic_error(const char* str)
{ (void)str; logic_error_called = true; }
BOOST_NORETURN void throw_logic_error(const char* str)
{
logic_error_called = true;
throw_runtime_error(str);
}
void throw_runtime_error(const char* str)
{ (void)str; runtime_error_called = true; }
BOOST_NORETURN void throw_runtime_error(const char* str)
{
(void)str;
runtime_error_called = true;
validate_and_never_return();
}
}} //boost::container
@@ -47,16 +71,6 @@ int main()
{
//Check user-defined throw callbacks are called
throw_bad_alloc();
BOOST_TEST(bad_alloc_called == true);
throw_out_of_range("dummy");
BOOST_TEST(out_of_range_called == true);
throw_length_error("dummy");
BOOST_TEST(length_error_called == true);
throw_logic_error("dummy");
BOOST_TEST(logic_error_called == true);
throw_runtime_error("dummy");
BOOST_TEST(runtime_error_called == true);
return ::boost::report_errors();
//Never reached
return 33;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -7,9 +7,7 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/uses_allocator_fwd.hpp>
#include <boost/container/uses_allocator.hpp>
#include "propagation_test_allocator.hpp"
@@ -23,7 +21,7 @@ struct uses_allocator_and_not_convertible_to_int
struct uses_allocator_and_convertible_to_int
{
typedef char allocator_type;
typedef long allocator_type;
};
struct uses_erased_type_allocator

View File

@@ -82,6 +82,10 @@ bool test_smart_ref_type()
class recursive_vector
{
public:
recursive_vector (const recursive_vector &x)
: vector_(x.vector_)
{}
recursive_vector & operator=(const recursive_vector &x)
{ this->vector_ = x.vector_; return *this; }
@@ -340,24 +344,24 @@ int main()
typedef boost::container::vector<int> cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG
( !boost::has_trivial_destructor_after_move<pointer>::value ||
(boost::has_trivial_destructor_after_move<cont>::value ==
boost::has_trivial_destructor_after_move<allocator_type>::value)
, "has_trivial_destructor_after_move(default allocator) test failed"
);
}
// std::allocator
{
typedef boost::container::vector<int, std::allocator<int> > cont;
typedef cont::allocator_type allocator_type;
typedef boost::container::allocator_traits<allocator_type>::pointer pointer;
if (boost::has_trivial_destructor_after_move<cont>::value !=
boost::has_trivial_destructor_after_move<allocator_type>::value &&
boost::has_trivial_destructor_after_move<pointer>::value) {
std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl;
return 1;
}
BOOST_STATIC_ASSERT_MSG
( !boost::has_trivial_destructor_after_move<pointer>::value ||
(boost::has_trivial_destructor_after_move<cont>::value ==
boost::has_trivial_destructor_after_move<allocator_type>::value)
, "has_trivial_destructor_after_move(std::allocator) test failed"
);
}
return 0;

View File

@@ -338,6 +338,10 @@ int vector_test()
stdvector.erase(stdvector.begin());
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
boostvector.erase(boostvector.end()-1);
stdvector.erase(stdvector.end()-1);
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
{
//Initialize values
IntType aux_vect[50];