Reworked devector's relocation options, instead of relocation_limit<relocation_limit_XX>, it's specified by single "relocate_on_XX"

This commit is contained in:
Ion Gaztañaga
2022-10-01 23:39:28 +02:00
parent 4e4d2afef2
commit 4bed49ee14
9 changed files with 819 additions and 103 deletions

View File

@@ -471,7 +471,49 @@ implementation of methods that modify the devector at the front. In general, `de
are a superset of those of `vector` with similar 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*).
The static size overhead for boost's devector is one extra `size_t` per container: Usually sizeof(devector) == 4*sizeof(T*).
There are different strategies when elements are to be inserted at one extreme of the container and there is
no room for additional elements at that extreme. One simple strategy would be to reallocate a bigger buffer
and move all elements to the new memory. However, this would lead to unbounded memory waste when elements are
inserted predominantly on one extreme (e.g. pushed at one extreme and popped from the other, like a LIFO pattern).
To avoid unbounded memory waste, Boost.Container's `devector` uses a different strategy:
* If elements are inserted near a extreme and there is free space on that extreme, the insertion is performed
without any additional data movement (only the elements between the insertion point and the extreme are moved.
* If elements are inserted near one extreme and the free space on that extreme is exhausted, all existing elements
are relocated (moved) to the center of the internal memory buffer. This makes room in the exhausted extreme
to insert more elements whihout allocating a new buffer.
* Potentially, the maximum number of possible relocations (movements) reusing the memory buffer are Olog(N),
but that would lead non-amortized constant-time insertion at the extremes. In consequence, the number of
relocations must be limited ('relocation limit') and a reallocation (allocation of a new memory buffer) will be
performed if the load-factor of the container defined as (size()/length_of_buffer) surpasses the relocation limit (see
Lars Greger Nordland Hagen's [href http://larshagencpp.github.io/blog/2016/05/22/devector"Double-ended vector - is it useful?"]
article for more details.
* This approach offers a reasonable balance between a reasonable memory overhead and performance.
However, this strategy has also some downsides:
* Insertions at the extremes have no strong exception guarantee as data has to be move inside the existing buffer.
* Due to the memory relocation vs reallocation strategy explained above:
* `capacity()` can no longer tell the maximum number of elements that the container can hold and, at the same time,
the number of insertions to perform before a reallocation is performed. Depending on which extreme a insertion
takes place, a reallocation might occur or not (maybe there is free capacity at that extreme)
* Instead of removing the `capacity()` member or renaming it to "minimum_capacity()", the definition has been changed
to tell the *minimum* number of elements that can be inserted without reallocating. This allows the typical pattern
where:
* If `reserve(n)` is called, `capacity() >= n`
* If `capacity() == n` it is guaranteed that if `size() <= n` no reallocation will occur.
* However the usual container invariant where `size() <= capacity()` does not hold. `size()` can be bigger than
`capacity()` because elements can be always inserted at a extreme with free capacity without reallocation.
[endsect]
@@ -685,7 +727,7 @@ used to customize these containers:
[endsect]
[section:configurable_vectors Configurable vectors]
[section:configurable_vector Configurable vector]
The configuration for [classref boost::container::vector vector] is passed as
the last template parameter and defined using the utility class
@@ -706,42 +748,14 @@ the last template parameter and defined using the utility class
`size()` and `capacity()` inside vector, so that the size of an empty vector is minimized and cache
performance might be improved. See [classref boost::container::stored_size stored_size] for more details.
* [classref boost::container::devector devector] supports an addicional [classref boost::container::relocation_limit relocation_limit]
options to control container's behaviour when back or front free capacity is exhausted.
See the following example to see how [classref boost::container::vector_options vector_options] can be
used to customize `vector` container:
used to customize `vector`:
[import ../example/doc_custom_vector.cpp]
[doc_custom_vector]
[endsect]
[section:configurable_deques Configurable deques]
The configuration for [classref boost::container::deque deque] is passed as
the last template parameter and defined using the utility class
[classref boost::container::deque_options deque_options]. The following parameters can be configured:
Parameters that control the size of deque's 'block' (deque allocates contiguous chunks of elements, called 'blocks').
Only one of these paratemers can be specified:
* [classref boost::container::block_bytes block_bytes]: the number of bytes deque will allocate for store
elements contiguously: `deque::get_block_size()` will return aproximately `block_bytes/sizeof(value_type)`.
A value of zero means the default value.
* [classref boost::container::block_size block_size]: the number of elements deque will allocate contiguously.
If this option is specified, `deque::get_block_size()` will return the specified `block_size`.
A value of zero means the default value.
See the following example to see how [classref boost::container::deque_options deque_options] can be
used to customize `deque` container:
[import ../example/doc_custom_deque.cpp]
[doc_custom_deque]
[endsect]
[section:configurable_static_vectors Configurable static vector]
The configuration for [classref boost::container::static_vector static_vector] is passed as
@@ -757,7 +771,7 @@ the last template parameter and defined using the utility class
does not throw or abort, undefined behavior is triggered.
See the following example to see how [classref boost::container::static_vector_options static_vector_options] can be
used to customize `static_vector` container:
used to customize `static_vector`:
[import ../example/doc_custom_static_vector.cpp]
[doc_custom_static_vector]
@@ -784,13 +798,71 @@ the last template parameter and defined using the utility class
[classref boost::container::growth_factor_50 growth_factor_100].
See the following example to see how [classref boost::container::small_vector_options small_vector_options] can be
used to customize `small_vector` container:
used to customize `small_vector`:
[import ../example/doc_custom_small_vector.cpp]
[doc_custom_small_vector]
[endsect]
[section:configurable_deques Configurable deques]
The configuration for [classref boost::container::deque deque] is passed as
the last template parameter and defined using the utility class
[classref boost::container::deque_options deque_options]. The following parameters can be configured:
Parameters that control the size of deque's 'block' (deque allocates contiguous chunks of elements, called 'blocks').
Only one of these paratemers can be specified:
* [classref boost::container::block_bytes block_bytes]: the number of bytes deque will allocate for store
elements contiguously: `deque::get_block_size()` will return aproximately `block_bytes/sizeof(value_type)`.
A value of zero means the default value.
* [classref boost::container::block_size block_size]: the number of elements deque will allocate contiguously.
If this option is specified, `deque::get_block_size()` will return the specified `block_size`.
A value of zero means the default value.
See the following example to see how [classref boost::container::deque_options deque_options] can be
used to customize `deque`:
[import ../example/doc_custom_deque.cpp]
[doc_custom_deque]
[endsect]
[section:configurable_devector Configurable devector]
The configuration for [classref boost::container::devector devector] is passed as
the last template parameter and defined using the utility class
[classref boost::container::devector_options devector_options]. The following parameters can be configured:
* [classref boost::container::growth_factor growth_factor]: the growth policy of the devector.
The rate at which the capacity of a devector grows is implementation dependent and
implementations choose exponential growth in order to meet the amortized constant time requirement for push_back.
A higher growth factor will make it faster as it will require less data movement, but it will have a greater memory
impact (on average, more memory will be unused). A user can provide a custom implementation of the growth factor and some
predefined policies are available: [classref boost::container::growth_factor_50 growth_factor_50],
[classref boost::container::growth_factor_60 growth_factor_60] (usually the default) and
[classref boost::container::growth_factor_100 growth_factor_100].
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
parameters inside of the devector. Sometimes, when the maximum capacity to be used is much less than the
theoretical maximum that a devector can hold, it's interesting to use smaller unsigned integer types to represent
`size()` and `capacity()` inside devector, so that the size of an empty devector is minimized and cache
performance might be improved. See [classref boost::container::stored_size stored_size] for more details.
* [classref boost::container::relocate_on_66 relocate_on_XX]: load factor limit that will determine if
new memory should be allocated or elements should relocated inside existing memory, when the free space
is exhausted at one end of the container.
See the following example to see how [classref boost::container::devector_options devector_options] can be
used to customize `devector`:
[import ../example/doc_custom_devector.cpp]
[doc_custom_devector]
[endsect]
[endsect]
[section:extended_allocators Extended functionality: Extended allocators]

View File

@@ -0,0 +1,103 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2022-2022. 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/core/no_exceptions_support.hpp>
//[doc_custom_devector
#include <boost/container/devector.hpp>
#include <boost/static_assert.hpp>
/*<-*/
#include <boost/core/no_exceptions_support.hpp>
/*->*/
//Make sure assertions are active
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <cassert>
int main ()
{
using namespace boost::container;
////////////////////////////////////////////////
// 'stored_size' option
////////////////////////////////////////////////
//Specify that a devector will use "unsigned char" as the type to store size/capacity
typedef devector_options< stored_size<unsigned char> >::type size_option_t;
//Size-optimized devector is smaller than the default one.
typedef devector<int, new_allocator<int>, size_option_t > size_optimized_devector_t;
BOOST_STATIC_ASSERT(( sizeof(size_optimized_devector_t) < sizeof(devector<int>) ));
//Requesting capacity for more elements than representable by "unsigned char" is an error
bool exception_thrown = false;
/*<-*/
#ifndef BOOST_NO_EXCEPTIONS
BOOST_TRY{ size_optimized_devector_t v(256); } BOOST_CATCH(...){ exception_thrown = true; } BOOST_CATCH_END
#else
exception_thrown = true;
#endif //BOOST_NO_EXCEPTIONS
/*->*/
//=try { size_optimized_devector_t v(256); }
//=catch(...){ exception_thrown = true; }
assert(exception_thrown == true);
////////////////////////////////////////////////
// 'growth_factor' option
////////////////////////////////////////////////
//Specify that a devector will increase its capacity 50% when reallocating
typedef devector_options< growth_factor<growth_factor_50> >::type growth_50_option_t;
//Fill the devector until full capacity is reached
devector<int, new_allocator<int>, growth_50_option_t > growth_50_dv(5, 0);
std::size_t old_cap = growth_50_dv.capacity();
growth_50_dv.resize(old_cap);
//Now insert an additional item and check the new buffer is 50% bigger
growth_50_dv.push_back(1);
assert(growth_50_dv.capacity() == old_cap*3/2);
////////////////////////////////////////////////
// 'relocate_on' option
////////////////////////////////////////////////
//Specifies that a devector will not reallocate but relocate elements if the free space
//at one end is exhausted and the total load factor is below the 66% threshold.
typedef devector_options< relocate_on_66 >::type relocation_66_option_t;
//Configure devector to have equal free space at both ends
devector<int, new_allocator<int>, relocation_66_option_t > reloc_66_dv
(16u, 16u, reserve_only_tag_t());
old_cap = reloc_66_dv.capacity();
const std::size_t front_free_cap = reloc_66_dv.front_free_capacity();
//Fill vector at the back end
while (reloc_66_dv.back_free_capacity() > 0)
reloc_66_dv.push_back(0);
//Front free capacity is intact
assert(reloc_66_dv.front_free_capacity() == front_free_cap);
//Now insert new element, values should relocated to the middle as the
//load factor is near 50%
reloc_66_dv.push_back(0);
assert(reloc_66_dv.capacity() == old_cap);
assert(reloc_66_dv.front_free_capacity() < front_free_cap);
//Fill the back end again
while (reloc_66_dv.back_free_capacity() > 0)
reloc_66_dv.push_back(1);
//New insertion should reallocate as load factor is higher than 66%
reloc_66_dv.push_back(-1);
assert(reloc_66_dv.capacity() > old_cap);
return 0;
}
//]

View File

@@ -62,31 +62,6 @@ namespace container {
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
struct relocation_limit_66
{
static const std::size_t free_fraction = 3u;
};
struct relocation_limit_75
{
static const std::size_t free_fraction = 4u;
};
struct relocation_limit_80
{
static const std::size_t free_fraction = 5u;
};
struct relocation_limit_86
{
static const std::size_t free_fraction = 7u;
};
struct relocation_limit_90
{
static const std::size_t free_fraction = 10u;
};
struct growth_factor_60;
template<class Options, class AllocatorSizeType>
@@ -94,14 +69,14 @@ struct get_devector_opt
{
typedef devector_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
, typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
, typename default_if_void<typename Options::relocation_limit_type, relocation_limit_90>::type
, default_if_zero<Options::free_fraction, relocate_on_90::value>::value
> type;
};
template<class AllocatorSizeType>
struct get_devector_opt<void, AllocatorSizeType>
{
typedef devector_opt< growth_factor_60, AllocatorSizeType, relocation_limit_90> type;
typedef devector_opt< growth_factor_60, AllocatorSizeType, relocate_on_90::value> type;
};
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -178,7 +153,7 @@ class devector
typedef typename options_type::growth_factor_type growth_factor_type;
typedef typename options_type::stored_size_type stored_size_type;
static const std::size_t devector_min_free_fraction =
options_type::relocation_limit_type::free_fraction;
options_type::free_fraction;
#endif // ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@@ -984,9 +959,9 @@ class devector
/**
* **Returns**: The *minimum* number of elements that can be inserted into devector using
* position-based insertions without requiring a reallocation. Note that, unlike in
* typical sequence containers like `vector`, `capacity()` can be smaller than `size()`.
* typical sequence containers like `vector`, `capacity()`, `capacity()` can be smaller than `size()`.
* This can happen if a user inserts elements in a particular way (usually inserting at
* front up to fron_free_capacity() and at back up to back_free_capacity()).
* front up to front_free_capacity() and at back up to back_free_capacity()).
*
* **Complexity**: Constant.
*/

View File

@@ -200,6 +200,20 @@ struct default_if_void<void, Default>
typedef Default type;
};
template<std::size_t N, std::size_t DefaultN>
struct default_if_zero
{
static const std::size_t value = N;
};
template<std::size_t DefaultN>
struct default_if_zero<0u, DefaultN>
{
static const std::size_t value = DefaultN;
};
#endif
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -468,65 +482,75 @@ using static_vector_options_t = typename boost::container::static_vector_options
//
////////////////////////////////////////////////////////////////
//!This option setter specifies the relocation strategy of the underlying devector.
//!Thse options specify the relocation strategy of devector.
//!
//!\tparam RelocationLimit A predefined occupation limit, used in insertions, that will determine
//! if the currently used memory buffer will be reused relocating all elements to the middle. If
//! the new occupation ratio (size()/current_buffer_size) is lower or equal than the limit, relocation
//! is performed reusing the same buffer. If the ratio is higher, a new buffer is allocated to hold
//! elements.
//!
//!Predefined relocation limits that can be passed as arguments to this option are:
//!\c boost::container::relocation_limit_66
//!\c boost::container::relocation_limit_75
//!\c boost::container::relocation_limit_80
//!\c boost::container::relocation_limit_86
//!\c boost::container::relocation_limit_90
//!\c boost::container::relocate_on_66
//!\c boost::container::relocate_on_75
//!\c boost::container::relocate_on_80
//!\c boost::container::relocate_on_85
//!\c boost::container::relocate_on_90
//!
//!If this option is not specified, a default will be used by the container.
//!
//!Note: Repeated insertions at only one end (only back insertions or only front insertions) usually will
//!lead to a single relocation when `relocation_limit_66` is used and two relocations when `relocation_limit_90`
//!lead to a single relocation when `relocate_on_66` is used and two relocations when `relocate_on_90`
//!is used.
BOOST_INTRUSIVE_OPTION_TYPE(relocation_limit, RelocLimit, RelocLimit, relocation_limit_type)
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template<class GrowthType, class StoredSizeType, class RelocLimit>
BOOST_INTRUSIVE_OPTION_CONSTANT(relocate_on, std::size_t, Fraction, free_fraction)
struct relocate_on_66 : public relocate_on<3U>{};
struct relocate_on_75 : public relocate_on<4U> {};
struct relocate_on_80 : public relocate_on<5U> {};
struct relocate_on_85 : public relocate_on<7U> {};
struct relocate_on_90 : public relocate_on<10U> {};
template<class GrowthType, class StoredSizeType, std::size_t FreeFraction>
struct devector_opt
: vector_opt<GrowthType, StoredSizeType>
{
typedef RelocLimit relocation_limit_type;
static const std::size_t free_fraction = FreeFraction;
};
typedef devector_opt<void, void, void> devector_null_opt;
typedef devector_opt<void, void, 0u> devector_null_opt;
#else
//!This relocation limit argument specifies that the container will relocate
//!This relocation condition option specifies that the container will never relocate
//!elements when there is no space at the side the insertion should
//!take place
struct relocate_never;
//!This relocation condition option specifies that the container will relocate
//!all elements when there is no space at the side the insertion should
//!take place and memory usage is below 66% (2/3)
struct relocation_limit_66{};
struct relocate_on_66;
//!This relocation limit argument specifies that the container will relocate
//!This relocation condition option specifies that the container will relocate
//!all elements when there is no space at the side the insertion should
//!take place and memory usage is below 75% (3/4)
struct relocation_limit_75 {};
struct relocate_on_75;
//!This relocation limit argument specifies that the container will relocate
//!This relocation condition option specifies that the container will relocate
//!all elements when there is no space at the side the insertion should
//!take place and memory usage is below 80% (4/5)
struct relocation_limit_80 {};
struct relocate_on_80;
//!This relocation limit argument specifies that the container will relocate
//!This relocation condition option specifies that the container will relocate
//!all elements when there is no space at the side the insertion should
//!take place and memory usage is below 86% (6/7)
struct relocation_limit_86 {};
//!take place and memory usage is below 85% (6/7)
struct relocate_on_85;
//!This relocation limit argument specifies that the container will relocate
//!This relocation condition option specifies that the container will relocate
//!all elements when there is no space at the side the insertion should
//!take place and memory usage is below 90% (9/10)
struct relocation_limit_90 {};
struct relocate_on_90;
#endif
@@ -534,7 +558,7 @@ struct relocation_limit_90 {};
//! 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, \c boost::container::stored_size
//! and \c boost::container::relocation_limit
//! and \c boost::container::relocate_on
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
template<class ...Options>
#else
@@ -553,7 +577,7 @@ struct devector_options
>::type packed_options;
typedef devector_opt< typename packed_options::growth_factor_type
, typename packed_options::stored_size_type
, typename packed_options::relocation_limit_type
, packed_options::free_fraction
> implementation_defined;
/// @endcond
typedef implementation_defined type;

View File

@@ -208,6 +208,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hash_map_test", "hash_map_t
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_move_algo_test", "copy_move_algo_test.vcxproj", "{5CE11C83-84A7-093A-4FA2-A6BA20A30592}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_custom_devector", "doc_custom_devector.vcxproj", "{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -996,6 +998,14 @@ Global
{5CE11C83-84A7-093A-4FA2-A6BA20A30592}.Release|x64.Build.0 = Release|x64
{5CE11C83-84A7-093A-4FA2-A6BA20A30592}.Release|x86.ActiveCfg = Release|Win32
{5CE11C83-84A7-093A-4FA2-A6BA20A30592}.Release|x86.Build.0 = Release|Win32
{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}.Debug|x64.ActiveCfg = Debug|x64
{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}.Debug|x64.Build.0 = Debug|x64
{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}.Debug|x86.ActiveCfg = Debug|Win32
{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}.Debug|x86.Build.0 = Debug|Win32
{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}.Release|x64.ActiveCfg = Release|x64
{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}.Release|x64.Build.0 = Release|x64
{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}.Release|x86.ActiveCfg = Release|Win32
{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -0,0 +1,205 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{5CE11C83-84A7-093A-4FA2-A6BA20A30592}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<EnableASAN>
</EnableASAN>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>15.0.27625.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(Platform)\$(Configuration)\$(TargetName)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\Int\</IntDir>
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
<OutDir>$(Platform)\$(Configuration)\$(TargetName)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\Int\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(Platform)\$(Configuration)\$(TargetName)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\Int\</IntDir>
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
<OutDir>$(Platform)\$(Configuration)\$(TargetName)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\Int\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_ITERATOR_DEBUG_LEVEL=0</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../../stage/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)copy_move_algo_test.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<FixedBaseAddress>false</FixedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../../stage/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)copy_move_algo_test.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<FixedBaseAddress>false</FixedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat />
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../../stage/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
<FixedBaseAddress>false</FixedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>../../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>
</DebugInformationFormat>
<LanguageStandard>stdcpplatest</LanguageStandard>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<PreprocessToFile>false</PreprocessToFile>
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../../stage/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<FixedBaseAddress>false</FixedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\test\copy_move_algo_test.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,187 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{DB7B1CED-5670-8478-4C9D-F3BCF4A4209A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>15.0.27625.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(Platform)\$(Configuration)\$(TargetName)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\Int\</IntDir>
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
<OutDir>$(Platform)\$(Configuration)\$(TargetName)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\Int\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(Platform)\$(Configuration)\$(TargetName)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\Int\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(Platform)\$(Configuration)\$(TargetName)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\Int\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>Default</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../../stage/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)doc_custom_devector.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
<FixedBaseAddress>false</FixedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>../../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>Default</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../../stage/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)doc_custom_devector.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<FixedBaseAddress>false</FixedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>../../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat />
<LanguageStandard>Default</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../../stage/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
<FixedBaseAddress>false</FixedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>../../../..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>
</DebugInformationFormat>
<LanguageStandard>Default</LanguageStandard>
</ClCompile>
<Link>
<AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../../../../stage/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<FixedBaseAddress>false</FixedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\example\doc_custom_devector.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,140 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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.
//
//////////////////////////////////////////////////////////////////////////////
// the tests trigger deprecation warnings when compiled with msvc in C++17 mode
#if defined(_MSVC_LANG) && _MSVC_LANG > 201402
// warning STL4009: std::allocator<void> is deprecated in C++17
# define _SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/container/detail/copy_move_algo.hpp>
#include <boost/container/detail/advanced_insert_int.hpp>
#include <boost/container/detail/algorithm.hpp>
#include <boost/container/detail/placement_new.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/new_allocator.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/move/make_unique.hpp>
#include <vector>
#include "movable_int.hpp"
using namespace boost::container;
namespace boost {
namespace container {
namespace test {
//This function tests all the possible combinations when
//inserting data in a vector and expanding backwards
template<class ValueType>
void test_expand_backward_forward_and_insert_alloc()
{
typedef ValueType value_type;
//Distance old and new buffer
const unsigned int Offset[] =
{ 350, 300, 250, 200, 150, 100, 150, 100,
150, 50, 50, 50 };
//Initial vector size
const unsigned int InitialSize[] =
{ 200, 200, 200, 200, 200, 200, 200, 200,
200, 200, 200, 200 };
//Size of the data to insert
const unsigned int InsertSize[] =
{ 100, 100, 100, 100, 100, 100, 200, 200,
300, 25, 100, 200 };
//Number of tests
const unsigned int Iterations = sizeof(InsertSize) / sizeof(int);
//Insert position
const int Position[] =
{ 0, 100, 200 };
for (unsigned backmove = 2u; backmove != 0u; ) {
--backmove;
for (unsigned int pos = 0; pos < sizeof(Position) / sizeof(Position[0]); ++pos) {
BOOST_TEST(life_count<value_type>::check(0));
for (unsigned int iteration = 0; iteration < Iterations; ++iteration)
{
typedef std::vector<value_type> std_vector_val_t;
typedef boost::container::new_allocator<value_type> allocator_type;
typedef dtl::insert_range_proxy<allocator_type, typename std_vector_val_t::iterator> proxy_t;
{
std_vector_val_t initial_data;
initial_data.resize(InitialSize[iteration]);
for (unsigned int i = 0; i < InitialSize[iteration]; ++i) {
initial_data[i] = static_cast<value_type>((int)i);
}
BOOST_TEST(life_count<value_type>::check(InitialSize[iteration]));
std_vector_val_t data_to_insert;
data_to_insert.resize(InsertSize[iteration]);
for (unsigned int i = 0; i < InsertSize[iteration]; ++i) {
data_to_insert[i] = static_cast<value_type>(-(int)i);
}
BOOST_TEST(life_count<value_type>::check(InitialSize[iteration] + InsertSize[iteration]));
const unsigned int BufferSize = InitialSize[iteration] + InsertSize[iteration] + Offset[iteration];
boost::movelib::unique_ptr<char[]> memptr =
boost::movelib::make_unique_definit<char[]>(BufferSize * sizeof(value_type));
value_type* memory = move_detail::force_ptr<value_type*>(memptr.get());
allocator_type a;
value_type* final_memory;
value_type* initial_memory;
if(backmove){
initial_memory = memory + Offset[iteration];
final_memory = memory;
}
else{
initial_memory = memory + BufferSize - InitialSize[iteration] - Offset[iteration];
final_memory = memory + BufferSize - InitialSize[iteration] - InsertSize[iteration];
}
for (unsigned int i = 0; i < InitialSize[iteration]; ++i) {
allocator_traits<allocator_type>::construct(a, &initial_memory[i], (int)i);
}
proxy_t proxy(data_to_insert.begin());
boost::container::expand_backward_forward_and_insert_alloc
(initial_memory, initial_data.size(), final_memory, initial_memory + Position[pos]
, data_to_insert.size(), proxy, a);
BOOST_TEST(life_count<value_type>::check(InitialSize[iteration] * 2 + InsertSize[iteration] * 2));
initial_data.insert(initial_data.begin() + Position[pos]
, data_to_insert.begin(), data_to_insert.end());
//Now check that values are equal
BOOST_TEST(boost::container::algo_equal(initial_data.begin(), initial_data.end(), final_memory));
boost::container::destroy_alloc_n(a, final_memory, InitialSize[iteration] + InsertSize[iteration]);
}
BOOST_TEST(life_count<value_type>::check(0));
}
}
}
}
} //namespace test {
} //namespace container {
} //namespace boost {
using namespace boost::container;
int main()
{
test::test_expand_backward_forward_and_insert_alloc<test::movable_and_copyable_int>();
return boost::report_errors();
}

View File

@@ -111,13 +111,14 @@ void test_growth_factor_100()
BOOST_TEST(new_capacity == 2*old_capacity);
}
void test_stored_relloc_limit_66()
void test_stored_reloc_on_66()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = devector_options_t< relocation_limit<relocation_limit_66> >;
using options_t = devector_options_t< relocate_on_66 >;
#else
typedef devector_options
< relocation_limit<relocation_limit_66> >::type options_t;
< relocate_on_66 >::type options_t;
#endif
const std::size_t buffer_size = 32u;
const std::size_t initial_side = buffer_size/2u;
@@ -147,17 +148,16 @@ void test_stored_relloc_limit_66()
//New insertion should reallocate
v.push_back(-1);
BOOST_TEST(v.back_free_capacity() > 8);
BOOST_TEST(v.back_free_capacity() > initial_side/2u);
BOOST_TEST(v.capacity() > old_cp);
}
void test_stored_relloc_limit_90()
void test_stored_reloc_on_90()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = devector_options_t< relocation_limit<relocation_limit_90> >;
using options_t = devector_options_t< relocate_on_90 >;
#else
typedef devector_options
< relocation_limit<relocation_limit_90> >::type options_t;
typedef devector_options< relocate_on_90 >::type options_t;
#endif
const std::size_t buffer_size = 32u;
@@ -210,7 +210,7 @@ int main()
test_growth_factor_100();
test_stored_size_type<unsigned char>();
test_stored_size_type<unsigned short>();
test_stored_relloc_limit_66();
test_stored_relloc_limit_90();
test_stored_reloc_on_66();
test_stored_reloc_on_90();
return ::boost::report_errors();
}