diff --git a/proj/vc7ide/allocator_traits_test.vcproj b/proj/vc7ide/allocator_traits_test.vcproj
new file mode 100644
index 0000000..ad50eba
--- /dev/null
+++ b/proj/vc7ide/allocator_traits_test.vcproj
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/proj/vc7ide/container.sln b/proj/vc7ide/container.sln
index ea29003..38cb19d 100644
--- a/proj/vc7ide/container.sln
+++ b/proj/vc7ide/container.sln
@@ -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
diff --git a/proj/vc7ide/container.vcproj b/proj/vc7ide/container.vcproj
index 500b5ca..7588d88 100644
--- a/proj/vc7ide/container.vcproj
+++ b/proj/vc7ide/container.vcproj
@@ -96,86 +96,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -209,15 +130,9 @@
-
-
-
-
@@ -230,18 +145,12 @@
-
-
-
-
@@ -254,67 +163,154 @@
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/proj/vc7ide/list_ex.vcproj b/proj/vc7ide/list_test.vcproj
similarity index 100%
rename from proj/vc7ide/list_ex.vcproj
rename to proj/vc7ide/list_test.vcproj
diff --git a/proj/vc7ide/pair_test.vcproj b/proj/vc7ide/pair_test.vcproj
new file mode 100644
index 0000000..6f32b3e
--- /dev/null
+++ b/proj/vc7ide/pair_test.vcproj
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/allocator_traits_test.cpp b/test/allocator_traits_test.cpp
new file mode 100644
index 0000000..ed109d4
--- /dev/null
+++ b/test/allocator_traits_test.cpp
@@ -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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+template
+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 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 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 pointer;
+ typedef SimpleSmartPtr const_pointer;
+ typedef T & reference;
+ typedef const T & const_reference;
+ typedef SimpleSmartPtr void_pointer;
+ typedef SimpleSmartPtr 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
+ 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 \
+ 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 >::value_type, int>::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::pointer, int*>::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::const_pointer, const int*>::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::void_pointer, void*>::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::const_void_pointer, const void*>::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::difference_type, std::ptrdiff_t>::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::size_type, std::size_t>::value ));
+ BOOST_STATIC_ASSERT(( boost::container::allocator_traits
+ < SimpleAllocator >::propagate_on_container_copy_assignment::value == false ));
+ BOOST_STATIC_ASSERT(( boost::container::allocator_traits
+ < SimpleAllocator >::propagate_on_container_move_assignment::value == false ));
+ BOOST_STATIC_ASSERT(( boost::container::allocator_traits
+ < SimpleAllocator >::propagate_on_container_swap::value == false ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::rebind_traits::allocator_type
+ , SimpleAllocator >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::rebind_alloc::value_type
+ , double >::value ));
+
+ //ComplexAllocator
+ BOOST_STATIC_ASSERT(( boost::is_same >::value_type, int>::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::pointer, SimpleSmartPtr >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::const_pointer, SimpleSmartPtr >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::void_pointer, SimpleSmartPtr >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::const_void_pointer, SimpleSmartPtr >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::difference_type, signed short>::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::size_type, unsigned short>::value ));
+ BOOST_STATIC_ASSERT(( boost::container::allocator_traits
+ < ComplexAllocator >::propagate_on_container_copy_assignment::value == true ));
+ BOOST_STATIC_ASSERT(( boost::container::allocator_traits
+ < ComplexAllocator >::propagate_on_container_move_assignment::value == true ));
+ BOOST_STATIC_ASSERT(( boost::container::allocator_traits
+ < ComplexAllocator >::propagate_on_container_swap::value == true ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::rebind_traits::allocator_type
+ , ComplexAllocator >::value ));
+ BOOST_STATIC_ASSERT(( boost::is_same >::rebind_alloc::value_type
+ , double >::value ));
+
+ typedef ComplexAllocator CAlloc;
+ typedef SimpleAllocator SAlloc;
+ typedef boost::container::allocator_traits CAllocTraits;
+ typedef boost::container::allocator_traits 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
diff --git a/test/check_equal_containers.hpp b/test/check_equal_containers.hpp
index ccdfa45..ad89e6b 100644
--- a/test/check_equal_containers.hpp
+++ b/test/check_equal_containers.hpp
@@ -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
#include
@@ -73,4 +73,4 @@ bool CheckEqualPairContainers(MyBoostCont *boostcont, MyStdCont *stdcont)
#include
-#endif //#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINERS_HPP
+#endif //#ifndef BOOST_CONTAINER_TEST_CHECK_EQUAL_CONTAINER_HPP
diff --git a/test/deque_test.cpp b/test/deque_test.cpp
index ad4b7ac..bc8bf9e 100644
--- a/test/deque_test.cpp
+++ b/test/deque_test.cpp
@@ -26,26 +26,39 @@
#include
#include
#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 >;
+
template class boost::container::deque
< test::movable_and_copyable_int
, test::dummy_test_allocator >;
+template class boost::container::deque
+ < test::movable_and_copyable_int
+ , std::allocator >;
+
+}}
+
//Function to check if both sets are equal
template
-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
-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 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_::value>())){
+ ,container_detail::bool_::value>())){
return false;
}
@@ -268,6 +286,21 @@ int main ()
if(!do_test())
return 1;
+ if(!do_test())
+ return 1;
+
+ if(!do_test())
+ return 1;
+
+ //Test non-copy-move operations
+ {
+ deque d;
+ d.emplace_back();
+ d.emplace_front(1);
+ d.resize(10);
+ d.resize(1);
+ }
+
{
typedef deque MyDeque;
typedef deque MyMoveDeque;
@@ -289,6 +322,9 @@ int main ()
< deque, Options>())
return 1;
+ if(!boost::container::test::test_propagate_allocator())
+ return 1;
+
return 0;
}
diff --git a/test/dummy_test_allocator.hpp b/test/dummy_test_allocator.hpp
index e03255e..719d0ca 100644
--- a/test/dummy_test_allocator.hpp
+++ b/test/dummy_test_allocator.hpp
@@ -23,7 +23,10 @@
#include
#include
#include
+#include
#include
+#include
+#include
#include
#include
#include
@@ -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 simple_allocator
+{
+ public:
+ typedef T value_type;
+
+ simple_allocator()
+ {}
+
+ template
+ simple_allocator(const simple_allocator &)
+ {}
+
+ 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 dummy_test_allocator
{
private:
- typedef dummy_test_allocator self_t;
+ typedef dummy_test_allocator self_t;
typedef void * aux_pointer_t;
typedef const void * cvoid_ptr;
- template
- dummy_test_allocator& operator=(const dummy_test_allocator&);
-
- 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
::type reference;
- typedef typename containers_detail::add_reference
+ typedef typename container_detail::add_reference
::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
-// typedef boost::container::version_type version;
+ typedef container_detail::basic_multiallocation_chain
+ multialloc_cached_counted;
+ typedef boost::container::container_detail::transform_multiallocation_chain
+ multiallocation_chain;
+
+ typedef boost::container::container_detail::version_type version;
template
struct rebind
@@ -115,7 +143,7 @@ class dummy_test_allocator
size_type,
size_type,
size_type &, const pointer & = 0)
- { return std::pair(pointer(0), true); }
+ { return std::pair(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 inline
bool operator==(const dummy_test_allocator &,
const dummy_test_allocator &)
-{ return false; }
+{ return true; }
//!Inequality test for same type of dummy_test_allocator
template inline
bool operator!=(const dummy_test_allocator &,
const dummy_test_allocator &)
-{ 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_
+ propagate_on_container_copy_assignment;
+ typedef boost::container::container_detail::bool_
+ propagate_on_container_move_assignment;
+ typedef boost::container::container_detail::bool_
+ propagate_on_container_swap;
+
+ template
+ 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
+ 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 {
diff --git a/test/emplace_test.hpp b/test/emplace_test.hpp
index 3cae3f8..ff93659 100644
--- a/test/emplace_test.hpp
+++ b/test/emplace_test.hpp
@@ -157,7 +157,7 @@ static EmplaceIntPair * expected_pair = initialize_emplace_int_pair();
template
-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
-bool test_emplace_back(containers_detail::false_)
+bool test_emplace_back(container_detail::false_)
{ return true; }
template
-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
-bool test_emplace_front(containers_detail::false_)
+bool test_emplace_front(container_detail::false_)
{ return true; }
template
-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
-bool test_emplace_before(containers_detail::false_)
+bool test_emplace_before(container_detail::false_)
{ return true; }
template
-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
-bool test_emplace_after(containers_detail::false_)
+bool test_emplace_after(container_detail::false_)
{ return true; }
template
-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
-bool test_emplace_assoc(containers_detail::false_)
+bool test_emplace_assoc(container_detail::false_)
{ return true; }
template
-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
-bool test_emplace_hint(containers_detail::false_)
+bool test_emplace_hint(container_detail::false_)
{ return true; }
template
-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
-bool test_emplace_assoc_pair(containers_detail::false_)
+bool test_emplace_assoc_pair(container_detail::false_)
{ return true; }
template
-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
-bool test_emplace_hint_pair(containers_detail::false_)
+bool test_emplace_hint_pair(container_detail::false_)
{ return true; }
template
struct emplace_active
{
static const bool value = (0 != (O & Mask));
- typedef containers_detail::bool_ type;
+ typedef container_detail::bool_ type;
operator type() const{ return type(); }
};
template
bool test_emplace()
{
-// if(!test_emplace_back(emplace_active()))
-// return false;
+ if(!test_emplace_back(emplace_active()))
+ return false;
if(!test_emplace_front(emplace_active()))
- return false;/*
+ return false;
if(!test_emplace_before(emplace_active()))
return false;
if(!test_emplace_after(emplace_active()))
@@ -612,7 +570,7 @@ bool test_emplace()
if(!test_emplace_assoc_pair(emplace_active()))
return false;
if(!test_emplace_hint_pair(emplace_active()))
- return false;*/
+ return false;
return true;
}
diff --git a/test/expand_bwd_test_allocator.hpp b/test/expand_bwd_test_allocator.hpp
index 1b690e3..67aea9d 100644
--- a/test/expand_bwd_test_allocator.hpp
+++ b/test/expand_bwd_test_allocator.hpp
@@ -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
::type reference;
- typedef typename containers_detail::add_reference
+ typedef typename container_detail::add_reference
::type const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
- typedef boost::container::containers_detail::version_type version;
+ typedef boost::container::container_detail::version_type version;
template
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
diff --git a/test/flat_tree_test.cpp b/test/flat_tree_test.cpp
index e8f9173..4203704 100644
--- a/test/flat_tree_test.cpp
+++ b/test/flat_tree_test.cpp
@@ -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::dummy_test_allocator
+ < std::pair >
+ >;
+
+template class flat_map
+ < test::movable_and_copyable_int
+ , test::movable_and_copyable_int
+ , std::less
+ , test::simple_allocator
+ < std::pair >
+ >;
+
+template class flat_map
+ < test::movable_and_copyable_int
+ , test::movable_and_copyable_int
+ , std::less
+ , std::allocator
+ < std::pair >
+ >;
+
+//flat_multimap
+template class flat_multimap
+ < test::movable_and_copyable_int
+ , test::movable_and_copyable_int
+ , std::less
+ , test::dummy_test_allocator
+ < std::pair >
+ >;
+
+template class flat_multimap
+ < test::movable_and_copyable_int
+ , test::movable_and_copyable_int
+ , std::less
+ , test::simple_allocator
+ < std::pair >
+ >;
+
+template class flat_multimap
+ < test::movable_and_copyable_int
+ , test::movable_and_copyable_int
+ , std::less
+ , std::allocator
+ < std::pair >
+ >;
+//flat_set
+template class flat_set
+ < test::movable_and_copyable_int
+ , std::less
+ , test::dummy_test_allocator
+ >;
+
+template class flat_set
+ < test::movable_and_copyable_int
+ , std::less
+ , test::simple_allocator
+ >;
+
+template class flat_set
+ < test::movable_and_copyable_int
+ , std::less
+ , std::allocator
+ >;
+
+//flat_multiset
+template class flat_multiset
+ < test::movable_and_copyable_int
+ , std::less
+ , test::dummy_test_allocator
+ >;
+
+template class flat_multiset
+ < test::movable_and_copyable_int
+ , std::less
+ , test::simple_allocator
+ >;
+
+template class flat_multiset
+ < test::movable_and_copyable_int
+ , std::less
+ , std::allocator
+ >;
+
+}} //boost::container
+
+
//Alias allocator type
typedef std::allocator allocator_t;
typedef std::allocator
@@ -84,7 +180,6 @@ typedef flat_multimap MyCopyBoostMultiMap;
-
//Test recursive structures
class recursive_flat_set
{
@@ -178,6 +273,36 @@ void test_move()
move_assign.swap(original);
}
+template
+class flat_tree_propagate_test_wrapper
+ : public container_detail::flat_tree, std::less, A>
+{
+ BOOST_COPYABLE_AND_MOVABLE(flat_tree_propagate_test_wrapper)
+ typedef container_detail::flat_tree, std::less, 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(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(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, MapOptions>())
-// return 1;
+ if(!boost::container::test::test_emplace, MapOptions>())
+ return 1;
if(!boost::container::test::test_emplace, MapOptions>())
return 1;
if(!boost::container::test::test_emplace, SetOptions>())
return 1;
if(!boost::container::test::test_emplace, SetOptions>())
return 1;
+ if(!boost::container::test::test_propagate_allocator())
+ return 1;
+
return 0;
}
diff --git a/test/heap_allocator_v1.hpp b/test/heap_allocator_v1.hpp
index 1e572c3..32b46b5 100644
--- a/test/heap_allocator_v1.hpp
+++ b/test/heap_allocator_v1.hpp
@@ -18,7 +18,7 @@
#include
#include
-#include
+#include
#include
#include
diff --git a/test/list_test.cpp b/test/list_test.cpp
index 9127ee1..602f547 100644
--- a/test/list_test.cpp
+++ b/test/list_test.cpp
@@ -11,15 +11,29 @@
#include
#include
#include "dummy_test_allocator.hpp"
+#include
#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 >;
+
template class boost::container::list >;
+
+template class boost::container::list >;
+
+}}
+
typedef list MyList;
typedef list MyMoveList;
@@ -72,6 +86,9 @@ int main ()
if(!boost::container::test::test_emplace, Options>())
return 1;
+ if(!boost::container::test::test_propagate_allocator())
+ return 1;
+
return 0;
}
diff --git a/test/list_test.hpp b/test/list_test.hpp
index 121c287..c248231 100644
--- a/test/list_test.hpp
+++ b/test/list_test.hpp
@@ -26,14 +26,14 @@ namespace container {
namespace test{
template
-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
-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_::value>())){
+ ,container_detail::bool_::value>())){
return 1;
}
}
diff --git a/test/map_test.hpp b/test/map_test.hpp
index f41acba..5eee229 100644
--- a/test/map_test.hpp
+++ b/test/map_test.hpp
@@ -38,7 +38,7 @@ template IntPairType;
+ typedef container_detail::pair 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 IntPairType;
+ typedef container_detail::pair IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int max = 100;
diff --git a/test/movable_int.hpp b/test/movable_int.hpp
index 37bf71d..599dbbb 100644
--- a/test/movable_int.hpp
+++ b/test/movable_int.hpp
@@ -221,6 +221,45 @@ struct is_copyable
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 {
diff --git a/test/pair_test.cpp b/test/pair_test.cpp
new file mode 100644
index 0000000..c44b9d5
--- /dev/null
+++ b/test/pair_test.cpp
@@ -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
+#include
+#include "movable_int.hpp"
+#include "emplace_test.hpp"
+#include
+
+//non_copymovable_int
+//copyable_int
+//movable_int
+//movable_and_copyable_int
+
+
+using namespace ::boost::container;
+
+int main ()
+{
+ {
+ container_detail::pair p1;
+ container_detail::pair p2;
+ container_detail::pair p3;
+ container_detail::pair p4;
+ }
+ { //Constructible from two values
+ container_detail::pair p1(1, 2);
+ container_detail::pair p2(1, 2);
+ container_detail::pair p3(1, 2);
+ container_detail::pair p4(1, 2);
+ }
+
+ { //Constructible from internal types
+ container_detail::pair p2(test::copyable_int(1), test::copyable_int(2));
+ {
+ test::movable_int a(1), b(2);
+ container_detail::pair p3(::boost::move(a), ::boost::move(b));
+ }
+ {
+ test::movable_and_copyable_int a(1), b(2);
+ container_detail::pair p4(::boost::move(a), ::boost::move(b));
+ }
+ }
+ //piecewise_construct missing...
+ return 0;
+}
+
+#include
diff --git a/test/propagate_allocator_test.hpp b/test/propagate_allocator_test.hpp
new file mode 100644
index 0000000..8901d77
--- /dev/null
+++ b/test/propagate_allocator_test.hpp
@@ -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
+#include
+#include "dummy_test_allocator.hpp"
+
+#include
+
+namespace boost{
+namespace container {
+namespace test{
+
+template class ContainerWrapper>
+bool test_propagate_allocator()
+{
+ {
+ typedef propagation_test_allocator AlwaysPropagate;
+ typedef ContainerWrapper 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 NeverPropagate;
+ typedef ContainerWrapper 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
+
+#endif //#ifndef BOOST_CONTAINER_PROPAGATE_ALLOCATOR_TEST_HPP
diff --git a/test/set_test.hpp b/test/set_test.hpp
index e4061eb..5dd6a2a 100644
--- a/test/set_test.hpp
+++ b/test/set_test.hpp
@@ -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()++);
diff --git a/test/slist_test.cpp b/test/slist_test.cpp
index e18f0bb..fb9f28f 100644
--- a/test/slist_test.cpp
+++ b/test/slist_test.cpp
@@ -9,17 +9,29 @@
//////////////////////////////////////////////////////////////////////////////
#include
#include
+#include
#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 >;
+
template class boost::container::slist >;
+template class boost::container::slist >;
+}}
+
typedef slist MyList;
typedef slist MyMoveList;
typedef slist MyCopyMoveList;
@@ -76,6 +88,9 @@ int main ()
if(!boost::container::test::test_emplace
< slist, Options>())
return 1;
+
+ if(!boost::container::test::test_propagate_allocator())
+ return 1;
}
#include
diff --git a/test/stable_vector_test.cpp b/test/stable_vector_test.cpp
index bf42978..edcd404 100644
--- a/test/stable_vector_test.cpp
+++ b/test/stable_vector_test.cpp
@@ -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 >;
+template class stable_vector