From e7bae623012da072d568abe40e3b989db3e042b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 22 Dec 2011 20:15:57 +0000 Subject: [PATCH] Introducing allocator_traits and pointer_traits changes into several libraries. [SVN r76107] --- proj/vc7ide/allocator_traits_test.vcproj | 139 +++++++ proj/vc7ide/container.sln | 52 ++- proj/vc7ide/container.vcproj | 282 +++++++------- .../{list_ex.vcproj => list_test.vcproj} | 0 proj/vc7ide/pair_test.vcproj | 133 +++++++ test/allocator_traits_test.cpp | 355 ++++++++++++++++++ test/check_equal_containers.hpp | 6 +- test/deque_test.cpp | 44 ++- test/dummy_test_allocator.hpp | 232 +++++++++++- test/emplace_test.hpp | 92 ++--- test/expand_bwd_test_allocator.hpp | 12 +- test/flat_tree_test.cpp | 148 +++++++- test/heap_allocator_v1.hpp | 2 +- test/list_test.cpp | 17 + test/list_test.hpp | 6 +- test/map_test.hpp | 25 +- test/movable_int.hpp | 39 ++ test/pair_test.cpp | 54 +++ test/propagate_allocator_test.hpp | 181 +++++++++ test/set_test.hpp | 1 + test/slist_test.cpp | 15 + test/stable_vector_test.cpp | 27 +- test/string_test.cpp | 221 +++++++++-- test/tree_test.cpp | 157 +++++++- test/vector_test.cpp | 19 +- test/vector_test.hpp | 7 +- 26 files changed, 1953 insertions(+), 313 deletions(-) create mode 100644 proj/vc7ide/allocator_traits_test.vcproj rename proj/vc7ide/{list_ex.vcproj => list_test.vcproj} (100%) create mode 100644 proj/vc7ide/pair_test.vcproj create mode 100644 test/allocator_traits_test.cpp create mode 100644 test/pair_test.cpp create mode 100644 test/propagate_allocator_test.hpp 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 >; + +template class stable_vector >; + +template class stable_vector >; + +}} 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 sv; + sv.emplace_back(); + sv.resize(10); + sv.resize(1); + } typedef stable_vector MyVector; typedef stable_vector MyMoveVector; typedef stable_vector MyCopyMoveVector; @@ -80,6 +100,9 @@ int main() < stable_vector, Options>()) return 1; + if(!boost::container::test::test_propagate_allocator()) + return 1; + return 0; } diff --git a/test/string_test.cpp b/test/string_test.cpp index 8c873ce..3799d4a 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -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 DummyWCharAllocator; typedef basic_string, DummyWCharAllocator> DummyWString; typedef test::dummy_test_allocator DummyWStringAllocator; +namespace boost { +namespace container { + //Explicit instantiations of container::basic_string -template class basic_string, DummyCharAllocator>; +template class basic_string, DummyCharAllocator>; template class basic_string, DummyWCharAllocator>; +template class basic_string, test::simple_allocator >; +template class basic_string, test::simple_allocator >; +template class basic_string, std::allocator >; +template class basic_string, std::allocator >; + //Explicit instantiation of container::vectors of container::strings template class vector; template class vector; +}} + struct StringEqual { template @@ -60,10 +71,64 @@ bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2) strvect2->begin(), comp); } +template +struct string_literals; + +template<> +struct string_literals +{ + 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 +{ + 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 int string_test() { - typedef std::string StdString; + typedef std::basic_string StdString; typedef vector StdStringVector; typedef basic_string BoostString; typedef vector 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::String(); + auxStdString = string_literals::String(); + string_literals::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::String(); + auxStdString = string_literals::String(); + string_literals::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::String(); + auxStdString = string_literals::String(); + string_literals::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::String(); + auxStdString = string_literals::String(); + string_literals::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::String(); + auxStdString = string_literals::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::LongString(); + auxStdString = string_literals::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::Prefix(); + const int prefix_size = std::char_traits::length(prefix); + const CharType *sufix = string_literals::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::String()); (*stdStringVect)[i].replace((*stdStringVect)[i].begin(), (*stdStringVect)[i].end(), - "String"); + string_literals::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 StdString; + typedef basic_string BoostString; + + BoostString bs2 = string_literals::String(); + StdString ss2 = string_literals::String(); + BoostString bs3 = string_literals::Suffix(); + StdString ss3 = string_literals::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::String(); + ss2 = string_literals::String(); + bs4 = boost::move(bs2) + BoostString(); + ss4 = boost::move(ss2) + StdString(); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals::String(); + ss2 = string_literals::String(); + bs4 = string_literals::Prefix() + boost::move(bs2); + ss4 = string_literals::Prefix() + boost::move(ss2); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals::String(); + ss2 = string_literals::String(); + bs4 = boost::move(bs2) + string_literals::Suffix(); + ss4 = boost::move(ss2) + string_literals::Suffix(); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals::String(); + ss2 = string_literals::String(); + bs4 = string_literals::Prefix() + bs2; + ss4 = string_literals::Prefix() + ss2; + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals::String(); + ss2 = string_literals::String(); + bs4 = bs2 + string_literals::Suffix(); + ss4 = ss2 + string_literals::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(); } +template +class string_propagate_test_wrapper + : public basic_string, A> +{ + BOOST_COPYABLE_AND_MOVABLE(string_propagate_test_wrapper) + typedef basic_string, 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(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(x))); return *this; } + + void swap(string_propagate_test_wrapper &x) + { this->Base::swap(x); } +}; + int main() { if(string_test()){ return 1; } + if(string_test()){ + return 1; + } + if(!test_expand_bwd()) return 1; + if(!boost::container::test::test_propagate_allocator()) + return 1; + return 0; } diff --git a/test/tree_test.cpp b/test/tree_test.cpp index 0df3ac4..0717cce 100644 --- a/test/tree_test.cpp +++ b/test/tree_test.cpp @@ -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 MyCopyBoostMap; typedef multimap 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::dummy_test_allocator + < std::pair > + >; + +template class map + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , std::less + , test::simple_allocator + < std::pair > + >; + +template class map + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , std::less + , std::allocator + < std::pair > + >; + +//multimap +template class multimap + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , std::less + , test::dummy_test_allocator + < std::pair > + >; + +template class multimap + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , std::less + , test::simple_allocator + < std::pair > + >; + +template class multimap + < test::movable_and_copyable_int + , test::movable_and_copyable_int + , std::less + , std::allocator + < std::pair > + >; + +//set +template class set + < test::movable_and_copyable_int + , std::less + , test::dummy_test_allocator + >; + +template class set + < test::movable_and_copyable_int + , std::less + , test::simple_allocator + >; + +template class set + < test::movable_and_copyable_int + , std::less + , std::allocator + >; + +//multiset +template class multiset + < test::movable_and_copyable_int + , std::less + , test::dummy_test_allocator + >; + +template class multiset + < test::movable_and_copyable_int + , std::less + , test::simple_allocator + >; + +template class multiset + < test::movable_and_copyable_int + , std::less + , std::allocator + >; + +}} //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 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 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 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 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 tree_propagate_test_wrapper + : public container_detail::rbtree, std::less, A> +{ + BOOST_COPYABLE_AND_MOVABLE(tree_propagate_test_wrapper) + typedef container_detail::rbtree, std::less, 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(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(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()){ -// return 1; -// } + if (0 != test::map_test()){ + return 1; + } if (0 != test::map_test, MapOptions>()) return 1; + if(!boost::container::test::test_propagate_allocator()) + return 1; return 0; } diff --git a/test/vector_test.cpp b/test/vector_test.cpp index 9bdc584..3be90ae 100644 --- a/test/vector_test.cpp +++ b/test/vector_test.cpp @@ -7,7 +7,6 @@ // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// - #include #include #include @@ -16,19 +15,32 @@ #include #include +#include #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 >; + template class boost::container::vector >; +template class boost::container::vector >; + +}} + 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 MyCopyVector; typedef vector MyEnumVector; - if(test::vector_test()) return 1; if(test::vector_test()) @@ -122,6 +132,9 @@ int main() < vector, Options>()) return 1; + if(!boost::container::test::test_propagate_allocator()) + return 1; + return 0; } #include diff --git a/test/vector_test.hpp b/test/vector_test.hpp index c57700e..4b6d7b7 100644 --- a/test/vector_test.hpp +++ b/test/vector_test.hpp @@ -30,14 +30,14 @@ namespace container { namespace test{ template -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 -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_::value>())){ + ,container_detail::bool_::value>())){ return 1; }