Changes for 1.49

[SVN r76180]
This commit is contained in:
Ion Gaztañaga
2011-12-26 17:12:31 +00:00
parent eec59f29b7
commit 43a784a1f9
28 changed files with 2034 additions and 333 deletions

View File

@@ -60,7 +60,7 @@ compiler include path.
[*Boost.Container] requires a decent C++98 compatibility. Some compilers known to work are:
* Visual C++ >= 7.1.
* GCC >= 3.4.
* GCC >= 4.1.
* Intel C++ >= 9.0
[endsect]
@@ -412,7 +412,7 @@ a finite (10) number of parameters.
[endsect]
[section:alloc_traits_move_traits Stateful allocators and Scoped allocators]
[section:alloc_traits_move_traits Stateful allocators]
C++03 was not stateful-allocator friendly. For compactness of container objects and for
simplicity, it did not require containers to support allocators with state: Allocator objects
@@ -422,24 +422,18 @@ to suppose two allocators of the same type always compare equal (that means that
by one allocator object could be deallocated by another instance of the same type) and
allocators were not swapped when the container was swapped.
Many C++ container implementors felt C++03 guarantees were too weak and started to offer extensions.
[*Boost.Container], following [@http://www.boost.org/libs/interprocess/ Boost.Interprocess]
containers experience supporting stateful allocators, offers the following guarantees:
* Allocators are copy-constructed in copy/move constructors
* If possible, a single allocator is hold to construct `value_type` and this allocator is copy constructed
from the user-supplied allocator object during container's constructor. If the container needs an auxiliary
allocator (e.g. a array allocator used by `deque` or `stable_vector`), that allocator is also
copy-constructed from the user-supplied allocator when the container is constructed (i.e. it's
not constructed on the fly when auxiliary memory is needed).
* Allocators are compared for equality when swapping containers. If allocators don't compare
equal allocators are swapped using an unqualified `swap` call.
C++11 further improves stateful allocator support through the
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2554.pdf
Scoped Allocators model], using classes like `std::scoped_allocator_adaptor` and `std::allocator_traits`.
[*Boost.Container does not support it yet, but there are plans to do so and backport scoped allocator
support to C++03 compilers.
Scoped Allocators model]. [@http://en.cppreference.com/w/cpp/memory/allocator_traits
`std::allocator_traits`] is the protocol between a container and an allocator, and
an allocator writer can customize its behaviour (should the container propagate it in
move constructor, swap, etc.?) following `allocator_traits` requirements. [*Boost.Container]
not only supports this model with C++11 but also [*backports it to C++03].
If possible, a single allocator is hold to construct `value_type`. If the container needs an auxiliary
allocator (e.g. a array allocator used by `deque` or `stable_vector`), that allocator is also
constructed from the user-supplied allocator when the container is constructed (i.e. it's
not constructed on the fly when auxiliary memory is needed).
[endsect]
@@ -451,7 +445,14 @@ to C++03 compilers.
[endsect]
[section:Vector_bool vector<bool>]
[section:forward_list `forward_list<T>`]
[*Boost.Container] does not offer C++11 `forward_list` container yet, but it will be available in future
versions.
[endsect]
[section:Vector_bool `vector<bool>`]
`vector<bool>` specialization has been quite problematic, and there have been several
unsuccessful tries to deprecate or remove it from the standard. [*Boost.Container] does not implement it
@@ -584,7 +585,23 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes Release Notes]
* First release with Boost 1.48. Container code from [*Boost.Interprocess] was deleted
[section:release_notes_boost_1_49_00 Boost 1.49 Release]
* Fixed bugs
[@https://svn.boost.org/trac/boost/ticket/6205 #6205],
[@https://svn.boost.org/trac/boost/ticket/6287 #6287],
[@https://svn.boost.org/trac/boost/ticket/4383 #4383].
* Added `allocator_traits` support for both C++11 and C++03
compilers through an internal `allocator_traits` clone.
[endsect]
[section:release_notes_boost_1_48_00 Boost 1.48 Release]
* First release. Container code from [*Boost.Interprocess] was deleted
and redirected to [*Boost.Container ] via using directives.
[endsect]
[endsect]

View File

@@ -1,2 +1,46 @@
->Change "insert" and "push_back"/"push_front" to catch non-const rvalues
->Add an example with stateful allocators
->Add test to check convertible types in push_back/insert
Review allocator traits
-> Explicit instantiation of simple allocator & std::allocator to detect missing allocator_traits calls
-> Avoid any rebind<>::other
-> Review select_on_container_copy_xxx
-> Review propagate_on_xxx
-> Put default constructed containers with their own constructor (different nothrow guarantees). Optimization, not needed
-> Default + swap move constructors correct?
-> Review container documentation in swap/copy/move regarding allocators
Check all move constructors: swap might not be a valid idiom, allocators must be move constructed, intrusive containers are now movable
Add and test:
Test different propagation values and with inequal allocators
propagate_on_container_move_assignment
select_on_container_copy_construction
propagate_on_container_swap
propagate_on_container_copy_assignment
Test move constructors with data values and unequal allocators
An allocator should use a smart allocator not constructible from raw pointers to catch missing pointer_traits calls
Review all internal container swap's to check allocator propagation is correct
Add initializer lists
Write forward_list
Review all move constructors to test if allocator is move constructed
check move if noexcept conditions in vector, deque and stable_vector
Add new allocator propagation copy constructors
Review all destructors (search for "~") to detect placement destruction and replace it with allocator_traits::destroy
All functions from base classes like vector_base, node_alloc_holder, etc., should be named with underscore or
similar to avoid namespace pollution.

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="allocator_traits_test"
ProjectGUID="{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/allocator_traits_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/allocator_traits_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/allocator_traits_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/allocator_traits_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/allocator_traits_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{41737BCF-4312-7AC5-A066-32D75A32A2AF}">
<File
RelativePath="..\..\test\allocator_traits_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93815995-89BD-b043-5E8B-65FBE52E2AFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,4 +1,12 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_containerlib", "container.vcproj", "{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "allocator_traits_test", "allocator_traits_test.vcproj", "{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "deque_test", "deque_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792655}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@@ -7,7 +15,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_tree_test", "flat_tree
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_test", "list_ex.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792632}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slist_test", "slist_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792608}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
@@ -23,15 +31,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tree_test", "tree_test.vcpr
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slist_test", "slist_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792608}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vector_test", "vector_test.vcproj", "{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_containerlib", "container.vcproj", "{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pair_test", "pair_test.vcproj", "{58CA17C5-A74F-9602-48FE-B06310DA7FA6}"
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
EndProject
@@ -43,6 +51,14 @@ Global
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.ActiveCfg = Debug|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.Build.0 = Debug|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Release.ActiveCfg = Release|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Release.Build.0 = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792655}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792655}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792655}.Release.ActiveCfg = Release|Win32
@@ -51,10 +67,10 @@ 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-BA0D3A792632}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.Build.0 = Release|Win32
{5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Debug.ActiveCfg = Debug|Win32
{5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Debug.Build.0 = Debug|Win32
{5E11C8D3-FA52-760A-84FE-943A6BA05A21}.Release.ActiveCfg = Release|Win32
@@ -67,18 +83,18 @@ Global
{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-BA0D3A792608}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792608}.Release.Build.0 = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.ActiveCfg = Debug|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.Build.0 = Debug|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Release.ActiveCfg = Release|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Release.Build.0 = Release|Win32
{58CA17C5-A74F-9602-48FE-B06310DA7FA6}.Debug.ActiveCfg = Debug|Win32
{58CA17C5-A74F-9602-48FE-B06310DA7FA6}.Debug.Build.0 = Debug|Win32
{58CA17C5-A74F-9602-48FE-B06310DA7FA6}.Release.ActiveCfg = Release|Win32
{58CA17C5-A74F-9602-48FE-B06310DA7FA6}.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
{58CCE183-6092-48FE-A4F7-BA0D3A792632}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@@ -96,86 +96,7 @@
</References>
<Files>
<Filter
Name="detail"
Filter="">
<File
RelativePath="..\..\..\..\boost\container\detail\adaptive_node_pool_impl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\advanced_insert_int.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\algorithms.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\allocation_type.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\config_begin.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\config_end.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\destroyers.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\flat_tree.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\iterators.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\multiallocation_chain.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\node_alloc_holder.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\node_pool_impl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\pair.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\pool_common.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\preprocessor.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\transform_iterator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\tree.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\type_traits.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\utilities.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\value_init.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\variadic_templates_tools.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\version_type.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\workaround.hpp">
</File>
</Filter>
<Filter
Name="Documentation"
Name="doc"
Filter="">
<File
RelativePath="..\..\doc\container.qbk">
@@ -209,15 +130,9 @@
<Filter
Name="test"
Filter="">
<File
RelativePath="..\..\test\boost_interprocess_check.hpp">
</File>
<File
RelativePath="..\..\test\check_equal_containers.hpp">
</File>
<File
RelativePath="..\..\test\deque_test.cpp">
</File>
<File
RelativePath="..\..\test\dummy_test_allocator.hpp">
</File>
@@ -230,18 +145,12 @@
<File
RelativePath="..\..\test\expand_bwd_test_template.hpp">
</File>
<File
RelativePath="..\..\test\flat_tree_test.cpp">
</File>
<File
RelativePath="..\..\test\heap_allocator_v1.hpp">
</File>
<File
RelativePath="..\..\test\Jamfile.v2">
</File>
<File
RelativePath="..\..\test\list_test.cpp">
</File>
<File
RelativePath="..\..\test\list_test.hpp">
</File>
@@ -254,67 +163,154 @@
<File
RelativePath="..\..\test\print_container.hpp">
</File>
<File
RelativePath="..\..\test\propagate_allocator_test.hpp">
</File>
<File
RelativePath="..\..\test\set_test.hpp">
</File>
<File
RelativePath="..\..\test\slist_test.cpp">
</File>
<File
RelativePath="..\..\test\stable_vector_test.cpp">
</File>
<File
RelativePath="..\..\test\string_test.cpp">
</File>
<File
RelativePath="..\..\test\tree_test.cpp">
</File>
<File
RelativePath="..\..\test\util.hpp">
</File>
<File
RelativePath="..\..\test\vector_test.cpp">
</File>
<File
RelativePath="..\..\test\vector_test.hpp">
</File>
</Filter>
<File
RelativePath="..\..\..\..\boost\container\container_fwd.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\deque.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\flat_map.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\flat_set.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\list.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\map.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\set.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\slist.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\stable_vector.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\string.hpp">
</File>
<File
RelativePath="..\to-do.txt">
</File>
<File
RelativePath="..\..\..\..\boost\container\vector.hpp">
</File>
<Filter
Name="container"
Filter="">
<File
RelativePath="..\..\..\..\boost\container\container_fwd.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\deque.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\flat_map.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\flat_set.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\list.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\map.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\set.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\slist.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\stable_vector.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\string.hpp">
</File>
<File
RelativePath="..\to-do.txt">
</File>
<File
RelativePath="..\..\..\..\boost\container\vector.hpp">
</File>
<Filter
Name="allocator"
Filter="">
<File
RelativePath="..\..\..\..\boost\container\allocator\allocator_traits.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\allocator\memory_util.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\allocator\scoped_allocator.hpp">
</File>
</Filter>
<Filter
Name="detail"
Filter="">
<File
RelativePath="..\..\..\..\boost\container\detail\adaptive_node_pool_impl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\advanced_insert_int.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\algorithms.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\allocation_type.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\config_begin.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\config_end.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\destroyers.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\flat_tree.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\function_detector.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\iterators.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\math_functions.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\mpl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\multiallocation_chain.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\node_alloc_holder.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\node_pool_impl.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\pair.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\pool_common.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\preprocessor.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\transform_iterator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\tree.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\type_traits.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\utilities.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\value_init.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\variadic_templates_tools.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\version_type.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\workaround.hpp">
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="pair_test"
ProjectGUID="{58CA17C5-A74F-9602-48FE-B06310DA7FA6}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/pair_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/pair_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/pair_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/pair_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/pair_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A8E6-2A3E52EBA2FF}">
<File
RelativePath="..\..\test\pair_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,355 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. 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/detail/config_begin.hpp>
#include <cstddef>
#include <boost/container/allocator/allocator_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/container/detail/function_detector.hpp>
#include <boost/move/move.hpp>
template<class T>
class SimpleAllocator
{
bool allocate_called_;
bool deallocate_called_;
public:
typedef T value_type;
SimpleAllocator()
: allocate_called_(false)
, deallocate_called_(false)
{}
T* allocate(std::size_t)
{ allocate_called_ = true; return 0; }
void deallocate(T*, std::size_t)
{ deallocate_called_ = true; }
bool allocate_called() const
{ return allocate_called_; }
bool deallocate_called() const
{ return deallocate_called_; }
};
template<class T>
class SimpleSmartPtr
{
public:
SimpleSmartPtr()
: ptr_(0)
{}
SimpleSmartPtr(const SimpleSmartPtr &c)
{ this->ptr_ = c.ptr_; }
SimpleSmartPtr & operator=(const SimpleSmartPtr &c)
{ this->ptr_ = c.ptr_; }
typedef T* pointer;
private:
T *ptr_;
};
template<class T, class Arg>
class ComplexAllocator
{
bool allocate_called_;
bool deallocate_called_;
bool allocate_hint_called_;
bool destroy_called_;
mutable bool max_size_called_;
mutable bool select_on_container_copy_construction_called_;
bool construct_called_;
public:
typedef T value_type;
typedef SimpleSmartPtr<T> pointer;
typedef SimpleSmartPtr<const T> const_pointer;
typedef T & reference;
typedef const T & const_reference;
typedef SimpleSmartPtr<void> void_pointer;
typedef SimpleSmartPtr<const void> const_void_pointer;
typedef signed short difference_type;
typedef unsigned short size_type;
typedef boost::true_type propagate_on_container_copy_assignment;
typedef boost::true_type propagate_on_container_move_assignment;
typedef boost::true_type propagate_on_container_swap;
ComplexAllocator()
: allocate_called_(false)
, deallocate_called_(false)
, allocate_hint_called_(false)
, destroy_called_(false)
, max_size_called_(false)
, select_on_container_copy_construction_called_(false)
, construct_called_(false)
{}
pointer allocate(size_type)
{ allocate_called_ = true; return pointer(); }
void deallocate(pointer, size_type)
{ deallocate_called_ = true; }
//optional
ComplexAllocator select_on_container_copy_construction() const
{ select_on_container_copy_construction_called_ = true; return *this; }
pointer allocate(size_type n, const const_void_pointer &)
{ allocate_hint_called_ = true; return allocate(n); }
template<class U>
void destroy(U*)
{ destroy_called_ = true; }
size_type max_size() const
{ max_size_called_ = true; return size_type(size_type(0)-1); }
#define BOOST_PP_LOCAL_MACRO(n) \
template<class U BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) > \
void construct(U *p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
construct_called_ = true; \
::new (p) U (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
} \
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
//getters
bool allocate_called() const
{ return allocate_called_; }
bool deallocate_called() const
{ return deallocate_called_; }
bool allocate_hint_called() const
{ return allocate_hint_called_; }
bool destroy_called() const
{ return destroy_called_; }
bool max_size_called() const
{ return max_size_called_; }
bool select_on_container_copy_construction_called() const
{ return select_on_container_copy_construction_called_; }
bool construct_called() const
{ return construct_called_; }
};
class copymovable
{
bool copymoveconstructed_;
bool moved_;
BOOST_COPYABLE_AND_MOVABLE(copymovable)
public:
copymovable(int, int, int)
: copymoveconstructed_(false), moved_(false)
{}
copymovable()
: copymoveconstructed_(false), moved_(false)
{}
copymovable(const copymovable &)
: copymoveconstructed_(true), moved_(false)
{}
copymovable(BOOST_RV_REF(copymovable))
: copymoveconstructed_(true), moved_(true)
{}
copymovable & operator=(BOOST_COPY_ASSIGN_REF(copymovable) ){ return *this; }
copymovable & operator=(BOOST_RV_REF(copymovable) ){ return *this; }
bool copymoveconstructed() const
{ return copymoveconstructed_; }
bool moved() const
{ return moved_; }
};
int main()
{
//SimpleAllocator
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::value_type, int>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::pointer, int*>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::const_pointer, const int*>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::void_pointer, void*>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::const_void_pointer, const void*>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::difference_type, std::ptrdiff_t>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::size_type, std::size_t>::value ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< SimpleAllocator<int> >::propagate_on_container_copy_assignment::value == false ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< SimpleAllocator<int> >::propagate_on_container_move_assignment::value == false ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< SimpleAllocator<int> >::propagate_on_container_swap::value == false ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::rebind_traits<double>::allocator_type
, SimpleAllocator<double> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< SimpleAllocator<int> >::rebind_alloc<double>::value_type
, double >::value ));
//ComplexAllocator
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::value_type, int>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::pointer, SimpleSmartPtr<int> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::const_pointer, SimpleSmartPtr<const int> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::void_pointer, SimpleSmartPtr<void> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::const_void_pointer, SimpleSmartPtr<const void> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::difference_type, signed short>::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::size_type, unsigned short>::value ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< ComplexAllocator<int, void> >::propagate_on_container_copy_assignment::value == true ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< ComplexAllocator<int, void> >::propagate_on_container_move_assignment::value == true ));
BOOST_STATIC_ASSERT(( boost::container::allocator_traits
< ComplexAllocator<int, void> >::propagate_on_container_swap::value == true ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::rebind_traits<double>::allocator_type
, ComplexAllocator<double, void> >::value ));
BOOST_STATIC_ASSERT(( boost::is_same<boost::container::allocator_traits
< ComplexAllocator<int, void> >::rebind_alloc<double>::value_type
, double >::value ));
typedef ComplexAllocator<int, void> CAlloc;
typedef SimpleAllocator<int> SAlloc;
typedef boost::container::allocator_traits<CAlloc> CAllocTraits;
typedef boost::container::allocator_traits<SAlloc> SAllocTraits;
CAlloc c_alloc;
SAlloc s_alloc;
//allocate
CAllocTraits::allocate(c_alloc, 1);
if(!c_alloc.allocate_called()){
return 1;
}
SAllocTraits::allocate(s_alloc, 1);
if(!s_alloc.allocate_called()){
return 1;
}
//deallocate
CAllocTraits::deallocate(c_alloc, CAllocTraits::pointer(), 1);
if(!c_alloc.deallocate_called()){
return 1;
}
SAllocTraits::deallocate(s_alloc, SAllocTraits::pointer(), 1);
if(!s_alloc.deallocate_called()){
return 1;
}
//allocate with hint
CAllocTraits::allocate(c_alloc, 1, CAllocTraits::const_void_pointer());
if(!c_alloc.allocate_hint_called()){
return 1;
}
SAllocTraits::allocate(s_alloc, 1, SAllocTraits::const_void_pointer());
//destroy
float dummy;
CAllocTraits::destroy(c_alloc, &dummy);
if(!c_alloc.destroy_called()){
return 1;
}
SAllocTraits::destroy(s_alloc, &dummy);
//max_size
CAllocTraits::max_size(c_alloc);
if(!c_alloc.max_size_called()){
return 1;
}
SAllocTraits::max_size(s_alloc);
//select_on_container_copy_construction
CAllocTraits::select_on_container_copy_construction(c_alloc);
if(!c_alloc.select_on_container_copy_construction_called()){
return 1;
}
SAllocTraits::select_on_container_copy_construction(s_alloc);
//construct
{
copymovable c;
copymovable c2;
CAllocTraits::construct(c_alloc, &c, c2);
if(!c_alloc.construct_called() || !c.copymoveconstructed() || c.moved()){
return 1;
}
}
{
copymovable c;
copymovable c2;
CAllocTraits::construct(c_alloc, &c, ::boost::move(c2));
if(!c_alloc.construct_called() || !c.copymoveconstructed() || !c.moved()){
return 1;
}
}
{
copymovable c;
copymovable c2;
SAllocTraits::construct(s_alloc, &c, c2);
if(!c.copymoveconstructed() || c.moved()){
return 1;
}
}
{
copymovable c;
copymovable c2;
SAllocTraits::construct(s_alloc, &c, ::boost::move(c2));
if(!c.copymoveconstructed() || !c.moved()){
return 1;
}
}
{
copymovable c;
CAllocTraits::construct(c_alloc, &c, 0, 1, 2);
if(!c_alloc.construct_called() || c.copymoveconstructed() || c.moved()){
return 1;
}
}
{
copymovable c;
copymovable c2;
SAllocTraits::construct(s_alloc, &c, 0, 1, 2);
if(c.copymoveconstructed() || c.moved()){
return 1;
}
}
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -8,8 +8,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP
#define BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP
#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINER_HPP
#define BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINER_HPP
#include <boost/container/detail/config_begin.hpp>
#include <functional>
@@ -73,4 +73,4 @@ bool CheckEqualPairContainers(MyBoostCont *boostcont, MyStdCont *stdcont)
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP
#endif //#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINER_HPP

View File

@@ -26,26 +26,39 @@
#include <boost/container/detail/type_traits.hpp>
#include <string>
#include "emplace_test.hpp"
#include "propagate_allocator_test.hpp"
#include "vector_test.hpp"
using namespace boost::container;
namespace boost {
namespace container {
//Explicit instantiation to detect compilation errors
template class boost::container::deque
< test::movable_and_copyable_int
, test::simple_allocator<test::movable_and_copyable_int> >;
template class boost::container::deque
< test::movable_and_copyable_int
, test::dummy_test_allocator<test::movable_and_copyable_int> >;
template class boost::container::deque
< test::movable_and_copyable_int
, std::allocator<test::movable_and_copyable_int> >;
}}
//Function to check if both sets are equal
template<class V1, class V2>
bool deque_copyable_only(V1 *, V2 *, containers_detail::false_type)
bool deque_copyable_only(V1 *, V2 *, container_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool deque_copyable_only(V1 *cntdeque, V2 *stddeque, containers_detail::true_type)
bool deque_copyable_only(V1 *cntdeque, V2 *stddeque, container_detail::true_type)
{
typedef typename V1::value_type IntType;
std::size_t size = cntdeque->size();
@@ -100,6 +113,10 @@ bool deque_copyable_only(V1 *cntdeque, V2 *stddeque, containers_detail::true_typ
class recursive_deque
{
public:
recursive_deque & operator=(const recursive_deque &x)
{ this->deque_ = x.deque_; return *this; }
int id_;
deque<recursive_deque> deque_;
};
@@ -161,6 +178,7 @@ bool do_test()
typename MyCntDeque::iterator it;
typename MyCntDeque::const_iterator cit = it;
(void)cit;
cntdeque->erase(cntdeque->begin()++);
stddeque->erase(stddeque->begin()++);
@@ -212,7 +230,7 @@ bool do_test()
}
if(!deque_copyable_only(cntdeque, stddeque
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
,container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return false;
}
@@ -268,6 +286,21 @@ int main ()
if(!do_test<test::movable_int>())
return 1;
if(!do_test<test::movable_and_copyable_int>())
return 1;
if(!do_test<test::copyable_int>())
return 1;
//Test non-copy-move operations
{
deque<test::non_copymovable_int> d;
d.emplace_back();
d.emplace_front(1);
d.resize(10);
d.resize(1);
}
{
typedef deque<int> MyDeque;
typedef deque<test::movable_int> MyMoveDeque;
@@ -289,6 +322,9 @@ int main ()
< deque<test::EmplaceInt>, Options>())
return 1;
if(!boost::container::test::test_propagate_allocator<deque>())
return 1;
return 0;
}

View File

@@ -23,7 +23,10 @@
#include <boost/assert.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/multiallocation_chain.hpp>
#include <boost/move/move.hpp>
#include <memory>
#include <algorithm>
#include <cstddef>
@@ -37,34 +40,59 @@ namespace boost {
namespace container {
namespace test {
//This allocator just allows two allocations. The first one will return
//mp_buffer + m_offset configured in the constructor. The second one
//will return mp_buffer.
//Very simple version 1 allocator
template<class T>
class simple_allocator
{
public:
typedef T value_type;
simple_allocator()
{}
template<class U>
simple_allocator(const simple_allocator<U> &)
{}
T* allocate(std::size_t n)
{ return (T*)::new char[sizeof(T)*n]; }
void deallocate(T*p, std::size_t)
{ delete[] ((char*)p);}
friend bool operator==(const simple_allocator &, const simple_allocator &)
{ return true; }
friend bool operator!=(const simple_allocator &, const simple_allocator &)
{ return false; }
};
//Version 2 allocator with rebind
template<class T>
class dummy_test_allocator
{
private:
typedef dummy_test_allocator<T> self_t;
typedef dummy_test_allocator<T> self_t;
typedef void * aux_pointer_t;
typedef const void * cvoid_ptr;
template<class T2>
dummy_test_allocator& operator=(const dummy_test_allocator<T2>&);
dummy_test_allocator& operator=(const dummy_test_allocator&);
public:
typedef T value_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef typename containers_detail::add_reference
typedef typename container_detail::add_reference
<value_type>::type reference;
typedef typename containers_detail::add_reference
typedef typename container_detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
// typedef boost::container::version_type<dummy_test_allocator, 2> version;
typedef container_detail::basic_multiallocation_chain
<void*> multialloc_cached_counted;
typedef boost::container::container_detail::transform_multiallocation_chain
<multialloc_cached_counted, value_type> multiallocation_chain;
typedef boost::container::container_detail::version_type<dummy_test_allocator, 2> version;
template<class T2>
struct rebind
@@ -115,7 +143,7 @@ class dummy_test_allocator
size_type,
size_type,
size_type &, const pointer & = 0)
{ return std::pair<pointer, bool>(pointer(0), true); }
{ return std::pair<pointer, bool>(pointer(), true); }
//!Returns maximum the number of objects the previously allocated memory
//!pointed by p can hold.
@@ -126,26 +154,198 @@ class dummy_test_allocator
//!must be deallocated only with deallocate_one().
//!Throws boost::container::bad_alloc if there is no enough memory
pointer allocate_one()
{ return pointer(0); }
{ return pointer(); }
//!Deallocates memory previously allocated with allocate_one().
//!You should never use deallocate_one to deallocate memory allocated
//!with other functions different from allocate_one(). Never throws
void deallocate_one(const pointer &)
{}
//!Allocates many elements of size == 1 in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
//!the preferred and maximum number is
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
multiallocation_chain allocate_individual(size_type)
{ return multiallocation_chain(); }
//!Allocates many elements of size == 1 in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
//!the preferred and maximum number is
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. Memory allocated with this function
//!must be deallocated only with deallocate_one().
void deallocate_individual(multiallocation_chain)
{}
//!Allocates many elements of size elem_size in a contiguous block
//!of memory. The minimum number to be allocated is min_elements,
//!the preferred and maximum number is
//!preferred_elements. The number of actually allocated elements is
//!will be assigned to received_size. The elements must be deallocated
//!with deallocate(...)
void deallocate_many(multiallocation_chain)
{}
};
//!Equality test for same type of dummy_test_allocator
template<class T> inline
bool operator==(const dummy_test_allocator<T> &,
const dummy_test_allocator<T> &)
{ return false; }
{ return true; }
//!Inequality test for same type of dummy_test_allocator
template<class T> inline
bool operator!=(const dummy_test_allocator<T> &,
const dummy_test_allocator<T> &)
{ return true; }
{ return false; }
template< class T
, bool PropagateOnContCopyAssign
, bool PropagateOnContMoveAssign
, bool PropagateOnContSwap
, bool CopyOnPropagateOnContSwap
>
class propagation_test_allocator
{
BOOST_COPYABLE_AND_MOVABLE(propagation_test_allocator)
public:
typedef T value_type;
typedef boost::container::container_detail::bool_<PropagateOnContCopyAssign>
propagate_on_container_copy_assignment;
typedef boost::container::container_detail::bool_<PropagateOnContMoveAssign>
propagate_on_container_move_assignment;
typedef boost::container::container_detail::bool_<PropagateOnContSwap>
propagate_on_container_swap;
template<class T2>
struct rebind
{ typedef propagation_test_allocator
< T2
, PropagateOnContCopyAssign
, PropagateOnContMoveAssign
, PropagateOnContSwap
, CopyOnPropagateOnContSwap> other;
};
propagation_test_allocator select_on_container_copy_construction() const
{ return CopyOnPropagateOnContSwap ? propagation_test_allocator(*this) : propagation_test_allocator(); }
explicit propagation_test_allocator()
: id_(unique_id_++)
, ctr_copies_(0)
, ctr_moves_(0)
, assign_copies_(0)
, assign_moves_(0)
, swaps_(0)
{}
propagation_test_allocator(const propagation_test_allocator &x)
: id_(x.id_)
, ctr_copies_(x.ctr_copies_+1)
, ctr_moves_(x.ctr_moves_)
, assign_copies_(x.assign_copies_)
, assign_moves_(x.assign_moves_)
, swaps_(x.swaps_)
{}
template<class U>
propagation_test_allocator(const propagation_test_allocator
< U
, PropagateOnContCopyAssign
, PropagateOnContMoveAssign
, PropagateOnContSwap
, CopyOnPropagateOnContSwap> &x)
: id_(x.id_)
, ctr_copies_(0)
, ctr_moves_(0)
, assign_copies_(0)
, assign_moves_(0)
, swaps_(0)
{}
propagation_test_allocator(BOOST_RV_REF(propagation_test_allocator) x)
: id_(x.id_)
, ctr_copies_(x.ctr_copies_)
, ctr_moves_(x.ctr_moves_ + 1)
, assign_copies_(x.assign_copies_)
, assign_moves_(x.assign_moves_)
, swaps_(x.swaps_)
{}
propagation_test_allocator &operator=(BOOST_COPY_ASSIGN_REF(propagation_test_allocator) x)
{
id_ = x.id_;
ctr_copies_ = x.ctr_copies_;
ctr_moves_ = x.ctr_moves_;
assign_copies_ = x.assign_copies_+1;
assign_moves_ = x.assign_moves_;
swaps_ = x.swaps_;
return *this;
}
propagation_test_allocator &operator=(BOOST_RV_REF(propagation_test_allocator) x)
{
id_ = x.id_;
ctr_copies_ = x.ctr_copies_;
ctr_moves_ = x.ctr_moves_;
assign_copies_ = x.assign_copies_;
assign_moves_ = x.assign_moves_+1;
swaps_ = x.swaps_;
return *this;
}
static void reset_unique_id()
{ unique_id_ = 0; }
T* allocate(std::size_t n)
{ return (T*)::new char[sizeof(T)*n]; }
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 &, const propagation_test_allocator &)
{ return false; }
friend void swap(propagation_test_allocator &l, propagation_test_allocator &r)
{
++l.swaps_; ++r.swaps_;
container_detail::do_swap(l.id_, r.id_);
container_detail::do_swap(l.ctr_copies_, r.ctr_copies_);
container_detail::do_swap(l.ctr_moves_, r.ctr_moves_);
container_detail::do_swap(l.assign_copies_, r.assign_copies_);
container_detail::do_swap(l.assign_moves_, r.assign_moves_);
container_detail::do_swap(l.swaps_, r.swaps_);
}
unsigned int id_;
unsigned int ctr_copies_;
unsigned int ctr_moves_;
unsigned int assign_copies_;
unsigned int assign_moves_;
unsigned int swaps_;
static unsigned unique_id_;
};
template< class T
, bool PropagateOnContCopyAssign
, bool PropagateOnContMoveAssign
, bool PropagateOnContSwap
, bool CopyOnPropagateOnContSwap
>
unsigned int propagation_test_allocator< T
, PropagateOnContCopyAssign
, PropagateOnContMoveAssign
, PropagateOnContSwap
, CopyOnPropagateOnContSwap>::unique_id_ = 0;
} //namespace test {
} //namespace container {

View File

@@ -157,7 +157,7 @@ static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
template<class Container>
bool test_emplace_back(containers_detail::true_)
bool test_emplace_back(container_detail::true_)
{
std::cout << "Starting test_emplace_back." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
@@ -194,11 +194,11 @@ bool test_emplace_back(containers_detail::true_)
}
template<class Container>
bool test_emplace_back(containers_detail::false_)
bool test_emplace_back(container_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_front(containers_detail::true_)
bool test_emplace_front(container_detail::true_)
{
std::cout << "Starting test_emplace_front." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
@@ -234,11 +234,11 @@ bool test_emplace_front(containers_detail::true_)
}
template<class Container>
bool test_emplace_front(containers_detail::false_)
bool test_emplace_front(container_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_before(containers_detail::true_)
bool test_emplace_before(container_detail::true_)
{
std::cout << "Starting test_emplace_before." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
@@ -309,11 +309,11 @@ bool test_emplace_before(containers_detail::true_)
}
template<class Container>
bool test_emplace_before(containers_detail::false_)
bool test_emplace_before(container_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_after(containers_detail::true_)
bool test_emplace_after(container_detail::true_)
{
std::cout << "Starting test_emplace_after." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
@@ -383,11 +383,11 @@ bool test_emplace_after(containers_detail::true_)
}
template<class Container>
bool test_emplace_after(containers_detail::false_)
bool test_emplace_after(container_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_assoc(containers_detail::true_)
bool test_emplace_assoc(container_detail::true_)
{
std::cout << "Starting test_emplace_assoc." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
@@ -423,11 +423,11 @@ bool test_emplace_assoc(containers_detail::true_)
}
template<class Container>
bool test_emplace_assoc(containers_detail::false_)
bool test_emplace_assoc(container_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_hint(containers_detail::true_)
bool test_emplace_hint(container_detail::true_)
{
std::cout << "Starting test_emplace_hint." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
@@ -466,11 +466,11 @@ bool test_emplace_hint(containers_detail::true_)
}
template<class Container>
bool test_emplace_hint(containers_detail::false_)
bool test_emplace_hint(container_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_assoc_pair(containers_detail::true_)
bool test_emplace_assoc_pair(container_detail::true_)
{
std::cout << "Starting test_emplace_assoc_pair." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
@@ -478,15 +478,9 @@ bool test_emplace_assoc_pair(containers_detail::true_)
new(&expected_pair[0].first) EmplaceInt();
new(&expected_pair[0].second) EmplaceInt();
new(&expected_pair[1].first) EmplaceInt(1);
new(&expected_pair[1].second) EmplaceInt();
new(&expected_pair[1].second) EmplaceInt(1);
new(&expected_pair[2].first) EmplaceInt(2);
new(&expected_pair[2].second) EmplaceInt(2);
new(&expected_pair[3].first) EmplaceInt(3);
new(&expected_pair[3].second) EmplaceInt(2, 3);
new(&expected_pair[4].first) EmplaceInt(4);
new(&expected_pair[4].second) EmplaceInt(2, 3, 4);
new(&expected_pair[5].first) EmplaceInt(5);
new(&expected_pair[5].second) EmplaceInt(2, 3, 4, 5);
{
Container c;
c.emplace();
@@ -494,7 +488,7 @@ bool test_emplace_assoc_pair(containers_detail::true_)
std::cout << "Error after c.emplace();\n";
return false;
}
c.emplace(1);
c.emplace(1, 1);
if(!test_expected_container(c, &expected_pair[0], 2)){
std::cout << "Error after c.emplace(1);\n";
return false;
@@ -504,31 +498,16 @@ bool test_emplace_assoc_pair(containers_detail::true_)
std::cout << "Error after c.emplace(2, 2);\n";
return false;
}
c.emplace(3, 2, 3);
if(!test_expected_container(c, &expected_pair[0], 4)){
std::cout << "Error after c.emplace(3, 2, 3);\n";
return false;
}
c.emplace(4, 2, 3, 4);
if(!test_expected_container(c, &expected_pair[0], 5)){
std::cout << "Error after c.emplace(4, 2, 3, 4);\n";
return false;
}
c.emplace(5, 2, 3, 4, 5);
if(!test_expected_container(c, &expected_pair[0], 6)){
std::cout << "Error after c.emplace(5, 2, 3, 4, 5);\n";
return false;
}
}
return true;
}
template<class Container>
bool test_emplace_assoc_pair(containers_detail::false_)
bool test_emplace_assoc_pair(container_detail::false_)
{ return true; }
template<class Container>
bool test_emplace_hint_pair(containers_detail::true_)
bool test_emplace_hint_pair(container_detail::true_)
{
std::cout << "Starting test_emplace_hint_pair." << std::endl << " Class: "
<< typeid(Container).name() << std::endl;
@@ -536,15 +515,9 @@ bool test_emplace_hint_pair(containers_detail::true_)
new(&expected_pair[0].first) EmplaceInt();
new(&expected_pair[0].second) EmplaceInt();
new(&expected_pair[1].first) EmplaceInt(1);
new(&expected_pair[1].second) EmplaceInt();
new(&expected_pair[1].second) EmplaceInt(1);
new(&expected_pair[2].first) EmplaceInt(2);
new(&expected_pair[2].second) EmplaceInt(2);
new(&expected_pair[3].first) EmplaceInt(3);
new(&expected_pair[3].second) EmplaceInt(2, 3);
new(&expected_pair[4].first) EmplaceInt(4);
new(&expected_pair[4].second) EmplaceInt(2, 3, 4);
new(&expected_pair[5].first) EmplaceInt(5);
new(&expected_pair[5].second) EmplaceInt(2, 3, 4, 5);
{
Container c;
typename Container::const_iterator it;
@@ -553,7 +526,7 @@ bool test_emplace_hint_pair(containers_detail::true_)
std::cout << "Error after c.emplace(1);\n";
return false;
}
it = c.emplace_hint(it, 1);
it = c.emplace_hint(it, 1, 1);
if(!test_expected_container(c, &expected_pair[0], 2)){
std::cout << "Error after c.emplace(it, 1);\n";
return false;
@@ -563,44 +536,29 @@ bool test_emplace_hint_pair(containers_detail::true_)
std::cout << "Error after c.emplace(it, 2, 2);\n";
return false;
}
it = c.emplace_hint(it, 3, 2, 3);
if(!test_expected_container(c, &expected_pair[0], 4)){
std::cout << "Error after c.emplace(it, 3, 2, 3);\n";
return false;
}
it = c.emplace_hint(it, 4, 2, 3, 4);
if(!test_expected_container(c, &expected_pair[0], 5)){
std::cout << "Error after c.emplace(it, 4, 2, 3, 4);\n";
return false;
}
it = c.emplace_hint(it, 5, 2, 3, 4, 5);
if(!test_expected_container(c, &expected_pair[0], 6)){
std::cout << "Error after c.emplace(it, 5, 2, 3, 4, 5);\n";
return false;
}
}
return true;
}
template<class Container>
bool test_emplace_hint_pair(containers_detail::false_)
bool test_emplace_hint_pair(container_detail::false_)
{ return true; }
template <EmplaceOptions O, EmplaceOptions Mask>
struct emplace_active
{
static const bool value = (0 != (O & Mask));
typedef containers_detail::bool_<value> type;
typedef container_detail::bool_<value> type;
operator type() const{ return type(); }
};
template<class Container, EmplaceOptions O>
bool test_emplace()
{
// if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>()))
// return false;
if(!test_emplace_back<Container>(emplace_active<O, EMPLACE_BACK>()))
return false;
if(!test_emplace_front<Container>(emplace_active<O, EMPLACE_FRONT>()))
return false;/*
return false;
if(!test_emplace_before<Container>(emplace_active<O, EMPLACE_BEFORE>()))
return false;
if(!test_emplace_after<Container>(emplace_active<O, EMPLACE_AFTER>()))
@@ -612,7 +570,7 @@ bool test_emplace()
if(!test_emplace_assoc_pair<Container>(emplace_active<O, EMPLACE_ASSOC_PAIR>()))
return false;
if(!test_emplace_hint_pair<Container>(emplace_active<O, EMPLACE_HINT_PAIR>()))
return false;*/
return false;
return true;
}

View File

@@ -56,14 +56,14 @@ class expand_bwd_test_allocator
typedef T value_type;
typedef T * pointer;
typedef const T * const_pointer;
typedef typename containers_detail::add_reference
typedef typename container_detail::add_reference
<value_type>::type reference;
typedef typename containers_detail::add_reference
typedef typename container_detail::add_reference
<const value_type>::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef boost::container::containers_detail::version_type<expand_bwd_test_allocator, 2> version;
typedef boost::container::container_detail::version_type<expand_bwd_test_allocator, 2> version;
template<class T2>
struct rebind
@@ -109,9 +109,9 @@ class expand_bwd_test_allocator
friend void swap(self_t &alloc1, self_t &alloc2)
{
containers_detail::do_swap(alloc1.mp_buffer, alloc2.mp_buffer);
containers_detail::do_swap(alloc1.m_size, alloc2.m_size);
containers_detail::do_swap(alloc1.m_offset, alloc2.m_offset);
container_detail::do_swap(alloc1.mp_buffer, alloc2.mp_buffer);
container_detail::do_swap(alloc1.m_size, alloc2.m_size);
container_detail::do_swap(alloc1.m_offset, alloc2.m_offset);
}
//Experimental version 2 expand_bwd_test_allocator functions

View File

@@ -17,10 +17,106 @@
#include "movable_int.hpp"
#include "set_test.hpp"
#include "map_test.hpp"
#include "propagate_allocator_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
namespace boost {
namespace container {
//Explicit instantiation to detect compilation errors
//flat_map
template class flat_map
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::dummy_test_allocator
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
template class flat_map
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::simple_allocator
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
template class flat_map
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, std::allocator
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
//flat_multimap
template class flat_multimap
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::dummy_test_allocator
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
template class flat_multimap
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::simple_allocator
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
template class flat_multimap
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, std::allocator
< std::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
//flat_set
template class flat_set
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::dummy_test_allocator<test::movable_and_copyable_int>
>;
template class flat_set
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::simple_allocator<test::movable_and_copyable_int>
>;
template class flat_set
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, std::allocator<test::movable_and_copyable_int>
>;
//flat_multiset
template class flat_multiset
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::dummy_test_allocator<test::movable_and_copyable_int>
>;
template class flat_multiset
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::simple_allocator<test::movable_and_copyable_int>
>;
template class flat_multiset
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, std::allocator<test::movable_and_copyable_int>
>;
}} //boost::container
//Alias allocator type
typedef std::allocator<int> allocator_t;
typedef std::allocator<test::movable_int>
@@ -84,7 +180,6 @@ typedef flat_multimap<test::copyable_int, test::copyable_int
,copy_pair_allocator_t> MyCopyBoostMultiMap;
//Test recursive structures
class recursive_flat_set
{
@@ -178,6 +273,36 @@ void test_move()
move_assign.swap(original);
}
template<class T, class A>
class flat_tree_propagate_test_wrapper
: public container_detail::flat_tree<T, T, container_detail::identity<T>, std::less<T>, A>
{
BOOST_COPYABLE_AND_MOVABLE(flat_tree_propagate_test_wrapper)
typedef container_detail::flat_tree<T, T, container_detail::identity<T>, std::less<T>, A> Base;
public:
flat_tree_propagate_test_wrapper()
: Base()
{}
flat_tree_propagate_test_wrapper(const flat_tree_propagate_test_wrapper &x)
: Base(x)
{}
flat_tree_propagate_test_wrapper(BOOST_RV_REF(flat_tree_propagate_test_wrapper) x)
: Base(boost::move(static_cast<Base&>(x)))
{}
flat_tree_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(flat_tree_propagate_test_wrapper) x)
{ this->Base::operator=(x); return *this; }
flat_tree_propagate_test_wrapper &operator=(BOOST_RV_REF(flat_tree_propagate_test_wrapper) x)
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
void swap(flat_tree_propagate_test_wrapper &x)
{ this->Base::swap(x); }
};
int main()
{
using namespace boost::container::test;
@@ -272,13 +397,13 @@ int main()
return 1;
}
// if (0 != map_test<
// MyMovableBoostMap
// ,MyStdMap
// ,MyMovableBoostMultiMap
// ,MyStdMultiMap>()){
// return 1;
// }
if (0 != map_test<
MyMovableBoostMap
,MyStdMap
,MyMovableBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if (0 != map_test<
MyMoveCopyBoostMap
@@ -319,14 +444,17 @@ int main()
const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC);
const test::EmplaceOptions MapOptions = (test::EmplaceOptions)(test::EMPLACE_HINT_PAIR | test::EMPLACE_ASSOC_PAIR);
// if(!boost::container::test::test_emplace<flat_map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
// return 1;
if(!boost::container::test::test_emplace<flat_map<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
if(!boost::container::test::test_emplace<flat_multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
if(!boost::container::test::test_emplace<flat_set<test::EmplaceInt>, SetOptions>())
return 1;
if(!boost::container::test::test_emplace<flat_multiset<test::EmplaceInt>, SetOptions>())
return 1;
if(!boost::container::test::test_propagate_allocator<flat_tree_propagate_test_wrapper>())
return 1;
return 0;
}

View File

@@ -18,7 +18,7 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/container/detail/allocation_type.hpp>

View File

@@ -11,15 +11,29 @@
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/list.hpp>
#include "dummy_test_allocator.hpp"
#include <memory>
#include "movable_int.hpp"
#include "list_test.hpp"
#include "propagate_allocator_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
namespace boost {
namespace container {
//Explicit instantiation to detect compilation errors
template class boost::container::list<test::movable_and_copyable_int,
test::simple_allocator<test::movable_and_copyable_int> >;
template class boost::container::list<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
template class boost::container::list<test::movable_and_copyable_int,
std::allocator<test::movable_and_copyable_int> >;
}}
typedef list<int> MyList;
typedef list<test::movable_int> MyMoveList;
@@ -72,6 +86,9 @@ int main ()
if(!boost::container::test::test_emplace<list<test::EmplaceInt>, Options>())
return 1;
if(!boost::container::test::test_propagate_allocator<list>())
return 1;
return 0;
}

View File

@@ -26,14 +26,14 @@ namespace container {
namespace test{
template<class V1, class V2>
bool list_copyable_only(V1 *, V2 *, boost::container::containers_detail::false_type)
bool list_copyable_only(V1 *, V2 *, boost::container::container_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool list_copyable_only(V1 *boostlist, V2 *stdlist, boost::container::containers_detail::true_type)
bool list_copyable_only(V1 *boostlist, V2 *stdlist, boost::container::container_detail::true_type)
{
typedef typename V1::value_type IntType;
boostlist->insert(boostlist->end(), 50, IntType(1));
@@ -289,7 +289,7 @@ int list_test (bool copied_allocators_equal = true)
}
if(!list_copyable_only(boostlist, stdlist
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
,container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return 1;
}
}

View File

@@ -38,7 +38,7 @@ template<class MyBoostMap
int map_test ()
{
typedef typename MyBoostMap::key_type IntType;
typedef containers_detail::pair<IntType, IntType> IntPairType;
typedef container_detail::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int max = 100;
@@ -101,6 +101,9 @@ int map_test ()
IntType i2(i);
new(&aux_vect3[i])IntPairType(boost::move(i1), boost::move(i2));
}
if(!CheckEqualContainers(boostmap2, stdmap2)) return 1;
if(!CheckEqualContainers(boostmultimap2, stdmultimap2)) return 1;
/*
MyBoostMap *boostmap3 = new MyBoostMap
( ordered_unique_range
@@ -122,6 +125,23 @@ int map_test ()
return 1;
}
*/
IntType i0(0);
boostmap2->erase(i0);
boostmultimap2->erase(i0);
stdmap2->erase(0);
stdmultimap2->erase(0);
{
IntType i0(0);
IntType i1(1);
(*boostmap2)[::boost::move(i0)] = ::boost::move(i1);
}
{
IntType i1(1);
(*boostmap2)[IntType(0)] = ::boost::move(i1);
}
(*stdmap2)[0] = 1;
if(!CheckEqualContainers(boostmap2, stdmap2)) return 1;
delete boostmap2;
delete boostmultimap2;
delete stdmap2;
@@ -158,6 +178,7 @@ int map_test ()
typename MyBoostMap::iterator it;
typename MyBoostMap::const_iterator cit = it;
(void)cit;
boostmap->erase(boostmap->begin()++);
stdmap->erase(stdmap->begin()++);
@@ -449,7 +470,7 @@ template<class MyBoostMap
int map_test_copyable ()
{
typedef typename MyBoostMap::key_type IntType;
typedef containers_detail::pair<IntType, IntType> IntPairType;
typedef container_detail::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int max = 100;

View File

@@ -221,6 +221,45 @@ struct is_copyable<copyable_int>
static const bool value = true;
};
class non_copymovable_int
{
non_copymovable_int(const non_copymovable_int& mmi);
non_copymovable_int & operator= (const non_copymovable_int &mi);
public:
non_copymovable_int()
: m_int(0)
{}
explicit non_copymovable_int(int a)
: m_int(a)
{}
bool operator ==(const non_copymovable_int &mi) const
{ return this->m_int == mi.m_int; }
bool operator !=(const non_copymovable_int &mi) const
{ return this->m_int != mi.m_int; }
bool operator <(const non_copymovable_int &mi) const
{ return this->m_int < mi.m_int; }
bool operator <=(const non_copymovable_int &mi) const
{ return this->m_int <= mi.m_int; }
bool operator >=(const non_copymovable_int &mi) const
{ return this->m_int >= mi.m_int; }
bool operator >(const non_copymovable_int &mi) const
{ return this->m_int > mi.m_int; }
int get_int() const
{ return m_int; }
private:
int m_int;
};
} //namespace test {
} //namespace container {
} //namespace boost {

54
test/pair_test.cpp Normal file
View File

@@ -0,0 +1,54 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. 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/detail/config_begin.hpp>
#include <boost/container/detail/pair.hpp>
#include "movable_int.hpp"
#include "emplace_test.hpp"
#include<boost/move/move.hpp>
//non_copymovable_int
//copyable_int
//movable_int
//movable_and_copyable_int
using namespace ::boost::container;
int main ()
{
{
container_detail::pair<test::non_copymovable_int, test::non_copymovable_int> p1;
container_detail::pair<test::copyable_int, test::copyable_int> p2;
container_detail::pair<test::movable_int, test::movable_int> p3;
container_detail::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> p4;
}
{ //Constructible from two values
container_detail::pair<test::non_copymovable_int, test::non_copymovable_int> p1(1, 2);
container_detail::pair<test::copyable_int, test::copyable_int> p2(1, 2);
container_detail::pair<test::movable_int, test::movable_int> p3(1, 2);
container_detail::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> p4(1, 2);
}
{ //Constructible from internal types
container_detail::pair<test::copyable_int, test::copyable_int> p2(test::copyable_int(1), test::copyable_int(2));
{
test::movable_int a(1), b(2);
container_detail::pair<test::movable_int, test::movable_int> p3(::boost::move(a), ::boost::move(b));
}
{
test::movable_and_copyable_int a(1), b(2);
container_detail::pair<test::movable_and_copyable_int, test::movable_and_copyable_int> p4(::boost::move(a), ::boost::move(b));
}
}
//piecewise_construct missing...
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -0,0 +1,181 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008. 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_PROPAGATE_ALLOCATOR_TEST_HPP
#define BOOST_CONTAINER_PROPAGATE_ALLOCATOR_TEST_HPP
#include <boost/container/detail/config_begin.hpp>
#include <boost/detail/lightweight_test.hpp>
#include "dummy_test_allocator.hpp"
#include <iostream>
namespace boost{
namespace container {
namespace test{
template<template<class, class> class ContainerWrapper>
bool test_propagate_allocator()
{
{
typedef propagation_test_allocator<char, true, true, true, true> AlwaysPropagate;
typedef ContainerWrapper<char, AlwaysPropagate> PropagateCont;
//////////////////////////////////////////
//Test AlwaysPropagate allocator propagation
//////////////////////////////////////////
AlwaysPropagate::reset_unique_id();
//default constructor
PropagateCont c;
BOOST_TEST (c.get_stored_allocator().id_ == 0);
BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0);
BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0);
BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c.get_stored_allocator().swaps_ == 0);
//copy constructor
PropagateCont c2(c);
//propagate_on_copy_constructor produces copies, moves or RVO (depending on the compiler).
//For allocators that copy in select_on_container_copy_construction, at least we must have a copy
unsigned int ctr_copies = c2.get_stored_allocator().ctr_copies_;
unsigned int ctr_moves = c2.get_stored_allocator().ctr_moves_;
BOOST_TEST (c2.get_stored_allocator().id_ == 0);
BOOST_TEST (ctr_copies > 0);
BOOST_TEST (c2.get_stored_allocator().ctr_moves_ >= 0);
BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);
//move constructor
PropagateCont c3(boost::move(c2));
BOOST_TEST (c3.get_stored_allocator().id_ == 0);
BOOST_TEST (c3.get_stored_allocator().ctr_copies_ == ctr_copies);
BOOST_TEST (c3.get_stored_allocator().ctr_moves_ > ctr_moves);
ctr_moves = c3.get_stored_allocator().ctr_moves_;
BOOST_TEST (ctr_moves > 0);
BOOST_TEST (c3.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c3.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c3.get_stored_allocator().swaps_ == 0);
//copy assign
c2 = c3;
unsigned int assign_copies = c2.get_stored_allocator().assign_copies_;
BOOST_TEST (c2.get_stored_allocator().id_ == 0);
BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies);
BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == ctr_moves);
BOOST_TEST (assign_copies == 1);
BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);
//move assign
c = boost::move(c2);
unsigned int assign_moves = c.get_stored_allocator().assign_moves_;
BOOST_TEST (c.get_stored_allocator().id_ == 0);
BOOST_TEST (c.get_stored_allocator().ctr_copies_ == ctr_copies);
BOOST_TEST (c.get_stored_allocator().ctr_moves_ == ctr_moves);
BOOST_TEST (c.get_stored_allocator().assign_copies_ == assign_copies);
BOOST_TEST (assign_moves == 1);
BOOST_TEST (c.get_stored_allocator().swaps_ == 0);
//swap
c.get_stored_allocator().id_ = 999;
c.swap(c2);
unsigned int swaps = c2.get_stored_allocator().swaps_;
BOOST_TEST (c2.get_stored_allocator().id_ == 999);
BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies);
BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == ctr_moves);
BOOST_TEST (c2.get_stored_allocator().assign_copies_ == assign_copies);
BOOST_TEST (c2.get_stored_allocator().assign_moves_ == assign_moves);
BOOST_TEST (swaps == 1);
}
//////////////////////////////////////////
//Test NeverPropagate allocator propagation
//////////////////////////////////////////
{
typedef propagation_test_allocator<char, false, false, false, false> NeverPropagate;
typedef ContainerWrapper<char, NeverPropagate> NoPropagateCont;
NeverPropagate::reset_unique_id();
//default constructor
NoPropagateCont c;
BOOST_TEST (c.get_stored_allocator().id_ == 0);
BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0);
BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0);
BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c.get_stored_allocator().swaps_ == 0);
//copy constructor
//propagate_on_copy_constructor produces copies, moves or RVO (depending on the compiler)
//For allocators that don't copy in select_on_container_copy_construction we must have a default
//construction
NoPropagateCont c2(c);
unsigned int ctr_copies = c2.get_stored_allocator().ctr_copies_;
unsigned int ctr_moves = c2.get_stored_allocator().ctr_moves_;
BOOST_TEST (c2.get_stored_allocator().id_ == 1);
BOOST_TEST (ctr_copies >= 0);
BOOST_TEST (ctr_moves >= 0);
BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);
//move constructor
NoPropagateCont c3(boost::move(c2));
BOOST_TEST (c3.get_stored_allocator().id_ == 1);
BOOST_TEST (c3.get_stored_allocator().ctr_copies_ == ctr_copies);
BOOST_TEST (c3.get_stored_allocator().ctr_moves_ > ctr_moves);
unsigned int ctr_moves2 = ctr_moves;
ctr_moves = c3.get_stored_allocator().ctr_moves_;
BOOST_TEST (c3.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c3.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c3.get_stored_allocator().swaps_ == 0);
//copy assign
c2 = c3;
BOOST_TEST (c2.get_stored_allocator().id_ == 1);
BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies);
BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == ctr_moves2);
BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);
//move assign
c = boost::move(c2);
BOOST_TEST (c.get_stored_allocator().id_ == 0);
BOOST_TEST (c.get_stored_allocator().ctr_copies_ == 0);
BOOST_TEST (c.get_stored_allocator().ctr_moves_ == 0);
BOOST_TEST (c.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c.get_stored_allocator().swaps_ == 0);
//swap
c.get_stored_allocator().id_ = 999;
c2.swap(c);
BOOST_TEST (c2.get_stored_allocator().id_ == 1);
BOOST_TEST (c.get_stored_allocator().id_ == 999);
BOOST_TEST (c2.get_stored_allocator().ctr_copies_ == ctr_copies);
BOOST_TEST (c2.get_stored_allocator().ctr_moves_ == ctr_moves2);
BOOST_TEST (c2.get_stored_allocator().assign_copies_ == 0);
BOOST_TEST (c2.get_stored_allocator().assign_moves_ == 0);
BOOST_TEST (c2.get_stored_allocator().swaps_ == 0);
}
return report_errors() == 0;
}
} //namespace test{
} //namespace container {
} //namespace boost{
#include <boost/container/detail/config_end.hpp>
#endif //#ifndef BOOST_CONTAINER_PROPAGATE_ALLOCATOR_TEST_HPP

View File

@@ -145,6 +145,7 @@ int set_test ()
typename MyBoostSet::iterator it;
typename MyBoostSet::const_iterator cit = it;
(void)cit;
boostset->erase(boostset->begin()++);
stdset->erase(stdset->begin()++);

View File

@@ -9,17 +9,29 @@
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/slist.hpp>
#include <memory>
#include "dummy_test_allocator.hpp"
#include "movable_int.hpp"
#include "list_test.hpp"
#include "propagate_allocator_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
namespace boost {
namespace container {
//Explicit instantiation to detect compilation errors
template class boost::container::slist<test::movable_and_copyable_int,
test::simple_allocator<test::movable_and_copyable_int> >;
template class boost::container::slist<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
template class boost::container::slist<test::movable_and_copyable_int,
std::allocator<test::movable_and_copyable_int> >;
}}
typedef slist<int> MyList;
typedef slist<test::movable_int> MyMoveList;
typedef slist<test::movable_and_copyable_int> MyCopyMoveList;
@@ -76,6 +88,9 @@ int main ()
if(!boost::container::test::test_emplace
< slist<test::EmplaceInt>, Options>())
return 1;
if(!boost::container::test::test_propagate_allocator<slist>())
return 1;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -21,13 +21,25 @@
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "dummy_test_allocator.hpp"
#include "propagate_allocator_test.hpp"
#include "vector_test.hpp"
using namespace boost::container;
namespace boost {
namespace container {
//Explicit instantiation to detect compilation errors
//template class stable_vector<test::movable_and_copyable_int,
//test::dummy_test_allocator<test::movable_and_copyable_int> >;
template class stable_vector<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
template class stable_vector<test::movable_and_copyable_int,
test::simple_allocator<test::movable_and_copyable_int> >;
template class stable_vector<test::movable_and_copyable_int,
std::allocator<test::movable_and_copyable_int> >;
}}
class recursive_vector
{
@@ -58,6 +70,14 @@ int main()
move_assign = boost::move(move_ctor);
move_assign.swap(original);
}
//Test non-copy-move operations
{
stable_vector<test::non_copymovable_int> sv;
sv.emplace_back();
sv.resize(10);
sv.resize(1);
}
typedef stable_vector<int> MyVector;
typedef stable_vector<test::movable_int> MyMoveVector;
typedef stable_vector<test::movable_and_copyable_int> MyCopyMoveVector;
@@ -80,6 +100,9 @@ int main()
< stable_vector<test::EmplaceInt>, Options>())
return 1;
if(!boost::container::test::test_propagate_allocator<stable_vector>())
return 1;
return 0;
}

View File

@@ -22,6 +22,7 @@
#include "check_equal_containers.hpp"
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "propagate_allocator_test.hpp"
using namespace boost::container;
@@ -32,13 +33,23 @@ typedef test::dummy_test_allocator<wchar_t> DummyWCharAllocator;
typedef basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator> DummyWString;
typedef test::dummy_test_allocator<DummyWString> DummyWStringAllocator;
namespace boost {
namespace container {
//Explicit instantiations of container::basic_string
template class basic_string<char, std::char_traits<char>, DummyCharAllocator>;
template class basic_string<char, std::char_traits<char>, DummyCharAllocator>;
template class basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator>;
template class basic_string<char, std::char_traits<char>, test::simple_allocator<char> >;
template class basic_string<wchar_t, std::char_traits<wchar_t>, test::simple_allocator<wchar_t> >;
template class basic_string<char, std::char_traits<char>, std::allocator<char> >;
template class basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >;
//Explicit instantiation of container::vectors of container::strings
template class vector<DummyString, DummyStringAllocator>;
template class vector<DummyWString, DummyWStringAllocator>;
}}
struct StringEqual
{
template<class Str1, class Str2>
@@ -60,10 +71,64 @@ bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2)
strvect2->begin(), comp);
}
template<class CharType>
struct string_literals;
template<>
struct string_literals<char>
{
static const char *String()
{ return "String"; }
static const char *Prefix()
{ return "Prefix"; }
static const char *Suffix()
{ return "Suffix"; }
static const char *LongString()
{ return "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; }
static void sprintf_number(char *buf, int number)
{
std::sprintf(buf, "%i", number);
}
};
template<>
struct string_literals<wchar_t>
{
static const wchar_t *String()
{ return L"String"; }
static const wchar_t *Prefix()
{ return L"Prefix"; }
static const wchar_t *Suffix()
{ return L"Suffix"; }
static const wchar_t *LongString()
{ return L"LongLongLongLongLongLongLongLongLongLongLongLongLongString"; }
static void sprintf_number(wchar_t *buffer, unsigned int number)
{
//For compilers without wsprintf, print it backwards
const wchar_t *digits = L"0123456789";
wchar_t *buf = buffer;
while(1){
int rem = number % 10;
number = number / 10;
*buf = digits[rem];
++buf;
if(!number){
*buf = 0;
break;
}
}
}
};
template<class CharType>
int string_test()
{
typedef std::string StdString;
typedef std::basic_string<CharType> StdString;
typedef vector<StdString> StdStringVector;
typedef basic_string<CharType> BoostString;
typedef vector<BoostString> BoostStringVector;
@@ -81,9 +146,9 @@ int string_test()
//First, push back
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString = string_literals<CharType>::String();
auxStdString = string_literals<CharType>::String();
string_literals<CharType>::sprintf_number(buffer, i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->push_back(auxBoostString);
@@ -96,9 +161,9 @@ int string_test()
//Now push back moving
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString = string_literals<CharType>::String();
auxStdString = string_literals<CharType>::String();
string_literals<CharType>::sprintf_number(buffer, i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->push_back(boost::move(auxBoostString));
@@ -111,9 +176,9 @@ int string_test()
//push front
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString = string_literals<CharType>::String();
auxStdString = string_literals<CharType>::String();
string_literals<CharType>::sprintf_number(buffer, i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->insert(boostStringVect->begin(), auxBoostString);
@@ -126,9 +191,9 @@ int string_test()
//Now push front moving
for(int i = 0; i < MaxSize; ++i){
auxBoostString = "String";
auxStdString = "String";
std::sprintf(buffer, "%i", i);
auxBoostString = string_literals<CharType>::String();
auxStdString = string_literals<CharType>::String();
string_literals<CharType>::sprintf_number(buffer, i);
auxBoostString += buffer;
auxStdString += buffer;
boostStringVect->insert(boostStringVect->begin(), boost::move(auxBoostString));
@@ -142,8 +207,8 @@ int string_test()
//Now test long and short representation swapping
//Short first
auxBoostString = "String";
auxStdString = "String";
auxBoostString = string_literals<CharType>::String();
auxStdString = string_literals<CharType>::String();
BoostString boost_swapper;
StdString std_swapper;
boost_swapper.swap(auxBoostString);
@@ -177,8 +242,8 @@ int string_test()
return 1;
//Long string
auxBoostString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
auxStdString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
auxBoostString = string_literals<CharType>::LongString();
auxStdString = string_literals<CharType>::LongString();
boost_swapper = BoostString();
std_swapper = StdString();
boost_swapper.swap(auxBoostString);
@@ -208,9 +273,9 @@ int string_test()
std::sort(stdStringVect->begin(), stdStringVect->end());
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
const CharType prefix [] = "Prefix";
const int prefix_size = sizeof(prefix)/sizeof(prefix[0])-1;
const CharType sufix [] = "Suffix";
const CharType *prefix = string_literals<CharType>::Prefix();
const int prefix_size = std::char_traits<CharType>::length(prefix);
const CharType *sufix = string_literals<CharType>::Suffix();
for(int i = 0; i < MaxSize; ++i){
(*boostStringVect)[i].append(sufix);
@@ -247,10 +312,10 @@ int string_test()
for(int i = 0; i < MaxSize; ++i){
(*boostStringVect)[i].replace((*boostStringVect)[i].begin(),
(*boostStringVect)[i].end(),
"String");
string_literals<CharType>::String());
(*stdStringVect)[i].replace((*stdStringVect)[i].begin(),
(*stdStringVect)[i].end(),
"String");
string_literals<CharType>::String());
}
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
@@ -261,6 +326,80 @@ int string_test()
stdStringVect->end());
if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1;
//Check addition
{
typedef std::basic_string<CharType> StdString;
typedef basic_string<CharType> BoostString;
BoostString bs2 = string_literals<CharType>::String();
StdString ss2 = string_literals<CharType>::String();
BoostString bs3 = string_literals<CharType>::Suffix();
StdString ss3 = string_literals<CharType>::Suffix();
BoostString bs4 = bs2 + bs3;
StdString ss4 = ss2 + ss3;
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs4 = bs2 + BoostString();
ss4 = ss2 + StdString();
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs4 = BoostString() + bs2;
ss4 = StdString() + ss2;
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs4 = BoostString() + boost::move(bs2);
ss4 = StdString() + boost::move(ss2);
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs2 = string_literals<CharType>::String();
ss2 = string_literals<CharType>::String();
bs4 = boost::move(bs2) + BoostString();
ss4 = boost::move(ss2) + StdString();
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs2 = string_literals<CharType>::String();
ss2 = string_literals<CharType>::String();
bs4 = string_literals<CharType>::Prefix() + boost::move(bs2);
ss4 = string_literals<CharType>::Prefix() + boost::move(ss2);
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs2 = string_literals<CharType>::String();
ss2 = string_literals<CharType>::String();
bs4 = boost::move(bs2) + string_literals<CharType>::Suffix();
ss4 = boost::move(ss2) + string_literals<CharType>::Suffix();
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs2 = string_literals<CharType>::String();
ss2 = string_literals<CharType>::String();
bs4 = string_literals<CharType>::Prefix() + bs2;
ss4 = string_literals<CharType>::Prefix() + ss2;
if(!StringEqual()(bs4, ss4)){
return 1;
}
bs2 = string_literals<CharType>::String();
ss2 = string_literals<CharType>::String();
bs4 = bs2 + string_literals<CharType>::Suffix();
ss4 = ss2 + string_literals<CharType>::Suffix();
if(!StringEqual()(bs4, ss4)){
return 1;
}
}
//When done, delete vector
delete boostStringVect;
delete stdStringVect;
@@ -278,15 +417,51 @@ bool test_expand_bwd()
return test::test_all_expand_bwd<string_type>();
}
template<class T, class A>
class string_propagate_test_wrapper
: public basic_string<T, std::char_traits<T>, A>
{
BOOST_COPYABLE_AND_MOVABLE(string_propagate_test_wrapper)
typedef basic_string<T, std::char_traits<T>, A> Base;
public:
string_propagate_test_wrapper()
: Base()
{}
string_propagate_test_wrapper(const string_propagate_test_wrapper &x)
: Base(x)
{}
string_propagate_test_wrapper(BOOST_RV_REF(string_propagate_test_wrapper) x)
: Base(boost::move(static_cast<Base&>(x)))
{}
string_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(string_propagate_test_wrapper) x)
{ this->Base::operator=(x); return *this; }
string_propagate_test_wrapper &operator=(BOOST_RV_REF(string_propagate_test_wrapper) x)
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
void swap(string_propagate_test_wrapper &x)
{ this->Base::swap(x); }
};
int main()
{
if(string_test<char>()){
return 1;
}
if(string_test<wchar_t>()){
return 1;
}
if(!test_expand_bwd())
return 1;
if(!boost::container::test::test_propagate_allocator<string_propagate_test_wrapper>())
return 1;
return 0;
}

View File

@@ -16,6 +16,7 @@
#include "dummy_test_allocator.hpp"
#include "set_test.hpp"
#include "map_test.hpp"
#include "propagate_allocator_test.hpp"
#include "emplace_test.hpp"
using namespace boost::container;
@@ -49,10 +50,109 @@ typedef map<test::copyable_int
,test::copyable_int> MyCopyBoostMap;
typedef multimap<test::copyable_int
,test::copyable_int> MyCopyBoostMultiMap;
namespace boost {
namespace container {
//Explicit instantiation to detect compilation errors
//map
template class map
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::dummy_test_allocator
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
template class map
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::simple_allocator
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
template class map
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, std::allocator
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
//multimap
template class multimap
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::dummy_test_allocator
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
template class multimap
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::simple_allocator
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
template class multimap
< test::movable_and_copyable_int
, test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, std::allocator
< std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int> >
>;
//set
template class set
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::dummy_test_allocator<test::movable_and_copyable_int>
>;
template class set
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::simple_allocator<test::movable_and_copyable_int>
>;
template class set
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, std::allocator<test::movable_and_copyable_int>
>;
//multiset
template class multiset
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::dummy_test_allocator<test::movable_and_copyable_int>
>;
template class multiset
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, test::simple_allocator<test::movable_and_copyable_int>
>;
template class multiset
< test::movable_and_copyable_int
, std::less<test::movable_and_copyable_int>
, std::allocator<test::movable_and_copyable_int>
>;
}} //boost::container
//Test recursive structures
class recursive_set
{
public:
recursive_set & operator=(const recursive_set &x)
{ id_ = x.id_; set_ = x.set_; return *this; }
int id_;
set<recursive_set> set_;
friend bool operator< (const recursive_set &a, const recursive_set &b)
@@ -62,6 +162,9 @@ public:
class recursive_map
{
public:
recursive_map & operator=(const recursive_map &x)
{ id_ = x.id_; map_ = x.map_; return *this; }
int id_;
map<recursive_map, recursive_map> map_;
friend bool operator< (const recursive_map &a, const recursive_map &b)
@@ -71,7 +174,10 @@ class recursive_map
//Test recursive structures
class recursive_multiset
{
public:
public:
recursive_multiset & operator=(const recursive_multiset &x)
{ id_ = x.id_; multiset_ = x.multiset_; return *this; }
int id_;
multiset<recursive_multiset> multiset_;
friend bool operator< (const recursive_multiset &a, const recursive_multiset &b)
@@ -80,7 +186,10 @@ public:
class recursive_multimap
{
public:
public:
recursive_multimap & operator=(const recursive_multimap &x)
{ id_ = x.id_; multimap_ = x.multimap_; return *this; }
int id_;
multimap<recursive_multimap, recursive_multimap> multimap_;
friend bool operator< (const recursive_multimap &a, const recursive_multimap &b)
@@ -98,6 +207,35 @@ void test_move()
move_assign.swap(original);
}
template<class T, class A>
class tree_propagate_test_wrapper
: public container_detail::rbtree<T, T, container_detail::identity<T>, std::less<T>, A>
{
BOOST_COPYABLE_AND_MOVABLE(tree_propagate_test_wrapper)
typedef container_detail::rbtree<T, T, container_detail::identity<T>, std::less<T>, A> Base;
public:
tree_propagate_test_wrapper()
: Base()
{}
tree_propagate_test_wrapper(const tree_propagate_test_wrapper &x)
: Base(x)
{}
tree_propagate_test_wrapper(BOOST_RV_REF(tree_propagate_test_wrapper) x)
: Base(boost::move(static_cast<Base&>(x)))
{}
tree_propagate_test_wrapper &operator=(BOOST_COPY_ASSIGN_REF(tree_propagate_test_wrapper) x)
{ this->Base::operator=(x); return *this; }
tree_propagate_test_wrapper &operator=(BOOST_RV_REF(tree_propagate_test_wrapper) x)
{ this->Base::operator=(boost::move(static_cast<Base&>(x))); return *this; }
void swap(tree_propagate_test_wrapper &x)
{ this->Base::swap(x); }
};
int main ()
{
//Recursive container instantiation
@@ -180,13 +318,12 @@ int main ()
return 1;
}
// if (0 != test::map_test<my_managed_shared_memory
// ,MyMovableBoostMap
// ,MyStdMap
// ,MyMovableBoostMultiMap
// ,MyStdMultiMap>()){
// return 1;
// }
if (0 != test::map_test<MyMovableBoostMap
,MyStdMap
,MyMovableBoostMultiMap
,MyStdMultiMap>()){
return 1;
}
if (0 != test::map_test<MyMoveCopyBoostMap
,MyStdMap
@@ -226,6 +363,8 @@ int main ()
return 1;
if(!boost::container::test::test_emplace<multimap<test::EmplaceInt, test::EmplaceInt>, MapOptions>())
return 1;
if(!boost::container::test::test_propagate_allocator<tree_propagate_test_wrapper>())
return 1;
return 0;
}

View File

@@ -7,7 +7,6 @@
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/detail/config_begin.hpp>
#include <algorithm>
#include <memory>
@@ -16,19 +15,32 @@
#include <functional>
#include <boost/container/vector.hpp>
#include <boost/move/move.hpp>
#include "check_equal_containers.hpp"
#include "movable_int.hpp"
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "dummy_test_allocator.hpp"
#include "propagate_allocator_test.hpp"
#include "vector_test.hpp"
using namespace boost::container;
namespace boost {
namespace container {
//Explicit instantiation to detect compilation errors
template class boost::container::vector<test::movable_and_copyable_int,
test::simple_allocator<test::movable_and_copyable_int> >;
template class boost::container::vector<test::movable_and_copyable_int,
test::dummy_test_allocator<test::movable_and_copyable_int> >;
template class boost::container::vector<test::movable_and_copyable_int,
std::allocator<test::movable_and_copyable_int> >;
}}
int test_expand_bwd()
{
//Now test all back insertion possibilities
@@ -81,7 +93,6 @@ enum Test
zero, one, two, three, four, five, six
};
int main()
{
recursive_vector_test();
@@ -99,7 +110,6 @@ int main()
typedef vector<test::copyable_int> MyCopyVector;
typedef vector<Test> MyEnumVector;
if(test::vector_test<MyVector>())
return 1;
if(test::vector_test<MyMoveVector>())
@@ -122,6 +132,9 @@ int main()
< vector<test::EmplaceInt>, Options>())
return 1;
if(!boost::container::test::test_propagate_allocator<vector>())
return 1;
return 0;
}
#include <boost/container/detail/config_end.hpp>

View File

@@ -30,14 +30,14 @@ namespace container {
namespace test{
template<class V1, class V2>
bool vector_copyable_only(V1 *, V2 *, boost::container::containers_detail::false_type)
bool vector_copyable_only(V1 *, V2 *, boost::container::container_detail::false_type)
{
return true;
}
//Function to check if both sets are equal
template<class V1, class V2>
bool vector_copyable_only(V1 *boostvector, V2 *stdvector, boost::container::containers_detail::true_type)
bool vector_copyable_only(V1 *boostvector, V2 *stdvector, boost::container::container_detail::true_type)
{
typedef typename V1::value_type IntType;
std::size_t size = boostvector->size();
@@ -111,6 +111,7 @@ int vector_test()
typename MyBoostVector::iterator boostit(boostvector->begin());
typename MyStdVector::iterator stdit(stdvector->begin());
typename MyBoostVector::const_iterator cboostit = boostit;
(void)cboostit;
++boostit; ++stdit;
boostvector->erase(boostit);
stdvector->erase(stdit);
@@ -183,7 +184,7 @@ int vector_test()
if(!test::CheckEqualContainers(boostvector, stdvector)) return 1;
if(!vector_copyable_only(boostvector, stdvector
,containers_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
,container_detail::bool_<boost::container::test::is_copyable<IntType>::value>())){
return 1;
}