diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 8e4eb2b..05bf622 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -36,8 +36,8 @@ doxygen autodoc "boost.doxygen.reftitle=Boost.Container Header Reference" ; -xml container : container.qbk - : +xml container : container.qbk + : ../../../tools/auto_index/include ; @@ -54,26 +54,26 @@ boostbook standalone pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html # Build requirements go here: - + # on (or off) one turns on (or off) indexing: on - + # Turns on (or off) auto-index-verbose for diagnostic info. # This is highly recommended until you have got all the many details correct! - on - + on + # Choose the indexing method (separately for html and PDF) - see manual. # Choose indexing method for PDFs: pdf:off - + # Choose indexing method for html: html:on - + # Set the name of the script file to use (index.idx is popular): index.idx # Commands in the script file should all use RELATIVE PATHS # otherwise the script will not be portable to other machines. - # Relative paths are normally taken as relative to the location + # Relative paths are normally taken as relative to the location # of the script file, but we can add a prefix to all # those relative paths using the feature. # The path specified by may be either relative or diff --git a/doc/container.qbk b/doc/container.qbk index c446e60..ee4cf42 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -225,7 +225,7 @@ want to advance it by n positions, we simply do: it.p = *(it.p->up+n); -That is, we go "up" to the pointer array, add n there and then go "down" to the resulting node. +That is, we go "up" to the pointer array, add n there and then go "down" to the resulting node. [*General properties]. `stable_vector` satisfies all the requirements of a container, a reversible container and a sequence and provides all the optional operations present in vector. Like vector, iterators are random access. `stable_vector` @@ -291,8 +291,8 @@ C++ world. Matt Austern's classic article ["['Red-black trees aren't the only way to organize data that permits lookup in logarithmic time. One of the basic algorithms of computer science is binary search, which works by successively dividing a range in half. Binary -search is log N and it doesn't require any fancy data structures, just a sorted collection of elements. -(...) You can use whatever data structure is convenient, so long as it provides STL iterator; +search is log N and it doesn't require any fancy data structures, just a sorted collection of elements. +(...) You can use whatever data structure is convenient, so long as it provides STL iterator; usually it's easiest to use a C array, or a vector.]] ["['Both std::lower_bound and set::find take time proportional to log N, but the constants of proportionality @@ -317,12 +317,12 @@ showed `AssocVector`, a `std::map` drop-in replacement designed in his [@http://loki-lib.sourceforge.net/ Loki] library: ["['It seems as if we're better off with a sorted vector. The disadvantages of a sorted -vector are linear-time insertions and linear-time deletions (...). In exchange, a vector -offers about twice the lookup speed and a much smaller working set (...). -Loki saves the trouble of maintaining a sorted vector by hand by defining an AssocVector class -template. AssocVector is a drop-in replacement for std::map (it supports the same set of member -functions), implemented on top of std::vector. AssocVector differs from a map in the behavior of -its erase functions (AssocVector::erase invalidates all iterators into the object) and in the +vector are linear-time insertions and linear-time deletions (...). In exchange, a vector +offers about twice the lookup speed and a much smaller working set (...). +Loki saves the trouble of maintaining a sorted vector by hand by defining an AssocVector class +template. AssocVector is a drop-in replacement for std::map (it supports the same set of member +functions), implemented on top of std::vector. AssocVector differs from a map in the behavior of +its erase functions (AssocVector::erase invalidates all iterators into the object) and in the complexity guarantees of insert and erase (linear as opposed to constant). ]] [*Boost.Container] `flat_[multi]map/set` containers are ordered-vector based associative containers @@ -380,7 +380,7 @@ should probably use list instead of slist.]] [*Boost.Container] updates the classic `slist` container with C++11 features like move semantics and placement insertion and implements it a bit differently than the standard C++ `forward_list`. `forward_list` has no `size()` method, so it's been designed to allow (or in practice, encourage) implementations without tracking list size -with every insertion/erasure, allowing constant-time +with every insertion/erasure, allowing constant-time `splice_after(iterator, forward_list &, iterator, iterator)`-based list merging. On the other hand `slist` offers constant-time `size()` for those that don't care about linear-time `splice_after(iterator, slist &, iterator, iterator)` `size()` and offers an additional `splice_after(iterator, slist &, iterator, iterator, size_type)` method that @@ -422,16 +422,16 @@ to suppose two allocators of the same type always compare equal (that means that by one allocator object could be deallocated by another instance of the same type) and allocators were not swapped when the container was swapped. -C++11 further improves stateful allocator support through +C++11 further improves stateful allocator support through [@http://en.cppreference.com/w/cpp/memory/allocator_traits `std::allocator_traits`]. `std::allocator_traits` is the protocol between a container and an allocator, and an allocator writer can customize its behaviour (should the container propagate it in move constructor, swap, etc.?) following `allocator_traits` requirements. [*Boost.Container] -not only supports this model with C++11 but also [*backports it to C++03]. +not only supports this model with C++11 but also [*backports it to C++03]. -If possible, a single allocator is hold to construct `value_type`. If the container needs an auxiliary -allocator (e.g. a array allocator used by `deque` or `stable_vector`), that allocator is also -constructed from the user-supplied allocator when the container is constructed (i.e. it's +If possible, a single allocator is hold to construct `value_type`. If the container needs an auxiliary +allocator (e.g. a array allocator used by `deque` or `stable_vector`), that allocator is also +constructed from the user-supplied allocator when the container is constructed (i.e. it's not constructed on the fly when auxiliary memory is needed). [endsect] @@ -453,14 +453,14 @@ container's elements, and, if the elements themselves are containers, the third elements' elements, and so on. [*Boost.Container] implements its own `scoped_allocator_adaptor` class and [*backports this feature also -to C++03 compilers]. Due to C++03 limitations, in those compilers +to C++03 compilers]. Due to C++03 limitations, in those compilers the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions will be based on traits([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix] and [classref boost::container::constructible_with_allocator_prefix constructible_with_allocator_prefix]) -proposed in [@http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2554.pdf +proposed in [@http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2554.pdf N2554: The Scoped Allocator Model (Rev 2) proposal]. In conforming C++11 compilers or compilers supporting SFINAE -expressions (when `BOOST_NO_SFINAE_EXPR` is NOT defined), traits are ignored and C++11 rules -(`is_constructible::value` and +expressions (when `BOOST_NO_SFINAE_EXPR` is NOT defined), traits are ignored and C++11 rules +(`is_constructible::value` and `is_constructible::value`) will be used to detect if the allocator must be propagated with suffix or prefix allocator arguments. @@ -487,7 +487,7 @@ versions. unsuccessful tries to deprecate or remove it from the standard. [*Boost.Container] does not implement it as there is a superior [@http://www.boost.org/libs/dynamic_bitset/ Boost.DynamicBitset] solution. For issues with `vector` see papers -[@http://www.gotw.ca/publications/N1211.pdf vector: N1211: More Problems, Better Solutions], +[@http://www.gotw.ca/publications/N1211.pdf vector: N1211: More Problems, Better Solutions], [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2160.html N2160: Library Issue 96: Fixing vector], [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2204.html N2204 A Specification to deprecate vector]. @@ -539,7 +539,7 @@ code tweaked to support non-raw `allocator::pointer` types and stateful allocato Shmem was accepted as [@http://www.boost.org/libs/interprocess/ Boost.Interprocess] and this library continued to refine and improve those containers. -In 2007, container code from node containers (`map`, `list`, `slist`) was rewritten, refactored +In 2007, container code from node containers (`map`, `list`, `slist`) was rewritten, refactored and expanded to build the intrusive container library [@http://www.boost.org/libs/intrusive/ Boost.Intrusive]. [*Boost.Interprocess] containers were refactored to take advantage of [*Boost.Intrusive] containers and code duplication was minimized. Both libraries continued to gain support and bug fixes for years. @@ -603,7 +603,7 @@ use [*Boost.Container]? There are several reasons for that: [@http://bannalia.blogspot.com/2008/09/introducing-stablevector.html Joaqu\u00EDn M. L\u00F3pez Mu\u00F1oz], then adapted for [*Boost.Interprocess]. Thanks for such a great container. -* Howard Hinnant's help and advices were essential when implementing move semantics, +* Howard Hinnant's help and advices were essential when implementing move semantics, improving allocator support or implementing small string optimization. Thanks Howard for your wonderful standard library implementations. diff --git a/doc/index.idx b/doc/index.idx index 9d0d126..b055432 100644 --- a/doc/index.idx +++ b/doc/index.idx @@ -1 +1 @@ -!scan-path "boost/container" ".*.hpp" false +!scan-path "boost/container" ".*.hpp" false diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index 1b4eb2d..2371b80 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -1,14 +1,14 @@ # Boost Container Library Example Jamfile # (C) Copyright Ion Gaztanaga 2009 -# Use, modification and distribution are subject to the -# Boost Software License, Version 1.0. (See accompanying file +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file # LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # Adapted from John Maddock's TR1 Jamfile.v2 # Copyright John Maddock 2005. -# Use, modification and distribution are subject to the -# Boost Software License, Version 1.0. (See accompanying file +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file # LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # this rule enumerates through all the sources and invokes @@ -31,4 +31,4 @@ rule test_all return $(all_rules) ; } -test-suite container_example : [ test_all r ] : multi ; \ No newline at end of file +test-suite container_example : [ test_all r ] : multi ; diff --git a/example/doc_recursive_containers.cpp b/example/doc_recursive_containers.cpp index e9e67d5..e486209 100644 --- a/example/doc_recursive_containers.cpp +++ b/example/doc_recursive_containers.cpp @@ -49,7 +49,7 @@ int main() stable_vector sv; sv.resize(100); - //Let's build a tree based in + //Let's build a tree based in //a recursive data type tree_node root; root.name = "root"; diff --git a/example/doc_type_erasure.cpp b/example/doc_type_erasure.cpp index 73c81f1..1c56f7f 100644 --- a/example/doc_type_erasure.cpp +++ b/example/doc_type_erasure.cpp @@ -15,7 +15,7 @@ //MyClassHolder.h //We don't need to include "MyClass.h" -//to store vector +//to store vector class MyClass; class MyClassHolder @@ -44,7 +44,7 @@ class MyClass MyClass(int val = 0) : value_(val){} friend bool operator==(const MyClass &l, const MyClass &r) - { return l.value_ == r.value_; } + { return l.value_ == r.value_; } //... }; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 6120122..af84010 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,14 +1,14 @@ # Boost Container Library Test Jamfile # (C) Copyright Ion Gaztanaga 2009. -# Use, modification and distribution are subject to the -# Boost Software License, Version 1.0. (See accompanying file +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file # LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # Adapted from John Maddock's TR1 Jamfile.v2 # Copyright John Maddock 2005. -# Use, modification and distribution are subject to the -# Boost Software License, Version 1.0. (See accompanying file +# Use, modification and distribution are subject to the +# Boost Software License, Version 1.0. (See accompanying file # LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # this rule enumerates through all the sources and invokes @@ -31,4 +31,4 @@ rule test_all return $(all_rules) ; } -test-suite container_test : [ test_all r ] ; +test-suite container_test : [ test_all r ] ; diff --git a/test/check_equal_containers.hpp b/test/check_equal_containers.hpp index ad89e6b..69d642c 100644 --- a/test/check_equal_containers.hpp +++ b/test/check_equal_containers.hpp @@ -23,17 +23,17 @@ namespace test{ //Function to check if both containers are equal template -bool CheckEqualContainers(MyBoostCont *boostcont, MyStdCont *stdcont) +bool CheckEqualContainers(const MyBoostCont *boostcont, const MyStdCont *stdcont) { if(boostcont->size() != stdcont->size()) return false; typedef typename MyBoostCont::value_type value_type; - typename MyBoostCont::iterator itboost(boostcont->begin()), itboostend(boostcont->end()); - typename MyStdCont::iterator itstd(stdcont->begin()); + typename MyBoostCont::const_iterator itboost(boostcont->begin()), itboostend(boostcont->end()); + typename MyStdCont::const_iterator itstd(stdcont->begin()); typename MyStdCont::size_type dist = (typename MyStdCont::size_type)std::distance(itboost, itboostend); - if(dist != boostcont->size()){ + if(dist != boostcont->size()){ return false; } std::size_t i = 0; @@ -48,7 +48,7 @@ bool CheckEqualContainers(MyBoostCont *boostcont, MyStdCont *stdcont) template -bool CheckEqualPairContainers(MyBoostCont *boostcont, MyStdCont *stdcont) +bool CheckEqualPairContainers(const MyBoostCont *boostcont, const MyStdCont *stdcont) { if(boostcont->size() != stdcont->size()) return false; @@ -56,8 +56,8 @@ bool CheckEqualPairContainers(MyBoostCont *boostcont, MyStdCont *stdcont) typedef typename MyBoostCont::key_type key_type; typedef typename MyBoostCont::mapped_type mapped_type; - typename MyBoostCont::iterator itboost(boostcont->begin()), itboostend(boostcont->end()); - typename MyStdCont::iterator itstd(stdcont->begin()); + typename MyBoostCont::const_iterator itboost(boostcont->begin()), itboostend(boostcont->end()); + typename MyStdCont::const_iterator itstd(stdcont->begin()); for(; itboost != itboostend; ++itboost, ++itstd){ if(itboost->first != key_type(itstd->first)) return false; diff --git a/test/deque_test.cpp b/test/deque_test.cpp index 7190e0a..53f17a3 100644 --- a/test/deque_test.cpp +++ b/test/deque_test.cpp @@ -259,11 +259,11 @@ bool do_test() cntdeque->resize(100); stddeque->resize(100); - if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1; + if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1; cntdeque->resize(200); stddeque->resize(200); - if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1; + if(!test::CheckEqualContainers(cntdeque, stddeque)) return 1; delete cntdeque; delete stddeque; @@ -272,7 +272,7 @@ bool do_test() std::cout << ex.what() << std::endl; return false; } - + std::cout << std::endl << "Test OK!" << std::endl; return true; } diff --git a/test/dummy_test_allocator.hpp b/test/dummy_test_allocator.hpp index 394b5a9..332892e 100644 --- a/test/dummy_test_allocator.hpp +++ b/test/dummy_test_allocator.hpp @@ -69,7 +69,7 @@ class simple_allocator //Version 2 allocator with rebind template -class dummy_test_allocator +class dummy_test_allocator { private: typedef dummy_test_allocator self_t; @@ -100,7 +100,7 @@ class dummy_test_allocator //!Default constructor. Never throws dummy_test_allocator() - {} + {} //!Constructor from other dummy_test_allocator. Never throws dummy_test_allocator(const dummy_test_allocator &) @@ -111,7 +111,7 @@ class dummy_test_allocator dummy_test_allocator(const dummy_test_allocator &) {} - pointer address(reference value) + pointer address(reference value) { return pointer(container_detail::addressof(value)); } const_pointer address(const_reference value) const @@ -140,7 +140,7 @@ class dummy_test_allocator std::pair allocation_command(boost::container::allocation_type, - size_type, + size_type, size_type, size_type &, const pointer & = 0) { return std::pair(pointer(), true); } @@ -192,19 +192,19 @@ class dummy_test_allocator //!Equality test for same type of dummy_test_allocator template inline -bool operator==(const dummy_test_allocator &, +bool operator==(const dummy_test_allocator &, const dummy_test_allocator &) { return true; } //!Inequality test for same type of dummy_test_allocator template inline -bool operator!=(const dummy_test_allocator &, +bool operator!=(const dummy_test_allocator &, const dummy_test_allocator &) { return false; } template< class T - , bool PropagateOnContCopyAssign + , bool PropagateOnContCopyAssign , bool PropagateOnContMoveAssign , bool PropagateOnContSwap , bool CopyOnPropagateOnContSwap @@ -335,7 +335,7 @@ class propagation_test_allocator }; template< class T - , bool PropagateOnContCopyAssign + , bool PropagateOnContCopyAssign , bool PropagateOnContMoveAssign , bool PropagateOnContSwap , bool CopyOnPropagateOnContSwap diff --git a/test/expand_bwd_test_allocator.hpp b/test/expand_bwd_test_allocator.hpp index 3f499d2..fbab8c7 100644 --- a/test/expand_bwd_test_allocator.hpp +++ b/test/expand_bwd_test_allocator.hpp @@ -36,11 +36,11 @@ namespace boost { namespace container { namespace test { -//This allocator just allows two allocations. The first one will return +//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. template -class expand_bwd_test_allocator +class expand_bwd_test_allocator { private: typedef expand_bwd_test_allocator self_t; @@ -70,12 +70,12 @@ class expand_bwd_test_allocator { typedef expand_bwd_test_allocator other; }; //!Constructor from the segment manager. Never throws - expand_bwd_test_allocator(T *buffer, size_type size, difference_type offset) + expand_bwd_test_allocator(T *buffer, size_type size, difference_type offset) : mp_buffer(buffer), m_size(size) , m_offset(offset), m_allocations(0){ } //!Constructor from other expand_bwd_test_allocator. Never throws - expand_bwd_test_allocator(const expand_bwd_test_allocator &other) + expand_bwd_test_allocator(const expand_bwd_test_allocator &other) : mp_buffer(other.mp_buffer), m_size(other.m_size) , m_offset(other.m_offset), m_allocations(0){ } @@ -108,7 +108,7 @@ class expand_bwd_test_allocator { return m_size; } friend void swap(self_t &alloc1, self_t &alloc2) - { + { 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); @@ -118,14 +118,14 @@ class expand_bwd_test_allocator std::pair allocation_command(boost::container::allocation_type command, - size_type limit_size, + size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse = 0) { (void)preferred_size; (void)reuse; (void)command; //This allocator only expands backwards! assert(m_allocations == 0 || (command & boost::container::expand_bwd)); - + received_size = limit_size; if(m_allocations == 0){ @@ -173,13 +173,13 @@ class expand_bwd_test_allocator //!Equality test for same type of expand_bwd_test_allocator template inline -bool operator==(const expand_bwd_test_allocator &alloc1, +bool operator==(const expand_bwd_test_allocator &alloc1, const expand_bwd_test_allocator &alloc2) { return false; } //!Inequality test for same type of expand_bwd_test_allocator template inline -bool operator!=(const expand_bwd_test_allocator &alloc1, +bool operator!=(const expand_bwd_test_allocator &alloc1, const expand_bwd_test_allocator &alloc2) { return true; } diff --git a/test/expand_bwd_test_template.hpp b/test/expand_bwd_test_template.hpp index 7dadcf9..0f06e23 100644 --- a/test/expand_bwd_test_template.hpp +++ b/test/expand_bwd_test_template.hpp @@ -114,19 +114,19 @@ bool test_insert_with_expand_bwd() const int MemorySize = 1000; //Distance old and new buffer - const int Offset[] = + const int Offset[] = { 350, 250, 150, 150, 150, 50, 50, 50 }; //Insert position - const int Position[] = + const int Position[] = { 100, 100, 100, 100, 100, 100, 100, 100 }; //Initial vector size - const int InitialSize[] = + const int InitialSize[] = { 200, 200, 200, 200, 200, 200, 200, 200 }; //Size of the data to insert - const int InsertSize[] = + const int InsertSize[] = { 100, 100, 100, 200, 300, 25, 100, 200 }; //Number of tests @@ -159,7 +159,7 @@ bool test_insert_with_expand_bwd() , data_to_insert.begin(), data_to_insert.end()); //Now check that values are equal if(!CheckEqualVector(vector, initial_data)){ - std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl + std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl << " Iteration: " << iteration << std::endl; return false; @@ -215,13 +215,13 @@ bool test_assign_with_expand_bwd() vector.insert( vector.begin() , initial_data.begin(), initial_data.end()); - //Assign data + //Assign data vector.assign(data_to_assign.begin(), data_to_assign.end()); initial_data.assign(data_to_assign.begin(), data_to_assign.end()); //Now check that values are equal if(!CheckEqualVector(vector, initial_data)){ - std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl + std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl << " Iteration: " << iteration << std::endl; return false; diff --git a/test/flat_tree_test.cpp b/test/flat_tree_test.cpp index 645a124..ba3d450 100644 --- a/test/flat_tree_test.cpp +++ b/test/flat_tree_test.cpp @@ -19,12 +19,14 @@ #include "map_test.hpp" #include "propagate_allocator_test.hpp" #include "emplace_test.hpp" +#include +#include using namespace boost::container; namespace boost { namespace container { - +/* //Explicit instantiation to detect compilation errors //flat_map @@ -113,25 +115,25 @@ template class flat_multiset , std::less , std::allocator >; - +*/ }} //boost::container //Alias allocator type typedef std::allocator allocator_t; -typedef std::allocator +typedef std::allocator movable_allocator_t; -typedef std::allocator > +typedef std::allocator > pair_allocator_t; -typedef std::allocator > +typedef std::allocator > movable_pair_allocator_t; -typedef std::allocator +typedef std::allocator move_copy_allocator_t; -typedef std::allocator > +typedef std::allocator > move_copy_pair_allocator_t; -typedef std::allocator +typedef std::allocator copy_allocator_t; -typedef std::allocator > +typedef std::allocator > copy_pair_allocator_t; @@ -302,6 +304,169 @@ class flat_tree_propagate_test_wrapper { this->Base::swap(x); } }; +namespace boost{ +namespace container { +namespace test{ + +bool flat_tree_ordered_insertion_test() +{ + using namespace boost::container; + const std::size_t NumElements = 100; + + //Ordered insertion multiset + { + std::multiset int_mset; + for(std::size_t i = 0; i != NumElements; ++i){ + int_mset.insert(static_cast(i)); + } + //Construction insertion + flat_multiset fmset(ordered_range, int_mset.begin(), int_mset.end()); + if(!CheckEqualContainers(&int_mset, &fmset)) + return false; + //Insertion when empty + fmset.clear(); + fmset.insert(ordered_range, int_mset.begin(), int_mset.end()); + if(!CheckEqualContainers(&int_mset, &fmset)) + return false; + //Re-insertion + fmset.insert(ordered_range, int_mset.begin(), int_mset.end()); + std::multiset int_mset2(int_mset); + int_mset2.insert(int_mset.begin(), int_mset.end()); + if(!CheckEqualContainers(&int_mset2, &fmset)) + return false; + //Re-re-insertion + fmset.insert(ordered_range, int_mset2.begin(), int_mset2.end()); + std::multiset int_mset4(int_mset2); + int_mset4.insert(int_mset2.begin(), int_mset2.end()); + if(!CheckEqualContainers(&int_mset4, &fmset)) + return false; + //Re-re-insertion of even + std::multiset int_even_mset; + for(std::size_t i = 0; i < NumElements; i+=2){ + int_mset.insert(static_cast(i)); + } + fmset.insert(ordered_range, int_even_mset.begin(), int_even_mset.end()); + int_mset4.insert(int_even_mset.begin(), int_even_mset.end()); + if(!CheckEqualContainers(&int_mset4, &fmset)) + return false; + } + //Ordered insertion multimap + { + std::multimap int_mmap; + for(std::size_t i = 0; i != NumElements; ++i){ + int_mmap.insert(std::multimap::value_type(static_cast(i), static_cast(i))); + } + //Construction insertion + flat_multimap fmmap(ordered_range, int_mmap.begin(), int_mmap.end()); + if(!CheckEqualContainers(&int_mmap, &fmmap)) + return false; + //Insertion when empty + fmmap.clear(); + fmmap.insert(ordered_range, int_mmap.begin(), int_mmap.end()); + if(!CheckEqualContainers(&int_mmap, &fmmap)) + return false; + //Re-insertion + fmmap.insert(ordered_range, int_mmap.begin(), int_mmap.end()); + std::multimap int_mmap2(int_mmap); + int_mmap2.insert(int_mmap.begin(), int_mmap.end()); + if(!CheckEqualContainers(&int_mmap2, &fmmap)) + return false; + //Re-re-insertion + fmmap.insert(ordered_range, int_mmap2.begin(), int_mmap2.end()); + std::multimap int_mmap4(int_mmap2); + int_mmap4.insert(int_mmap2.begin(), int_mmap2.end()); + if(!CheckEqualContainers(&int_mmap4, &fmmap)) + return false; + //Re-re-insertion of even + std::multimap int_even_mmap; + for(std::size_t i = 0; i < NumElements; i+=2){ + int_mmap.insert(std::multimap::value_type(static_cast(i), static_cast(i))); + } + fmmap.insert(ordered_range, int_even_mmap.begin(), int_even_mmap.end()); + int_mmap4.insert(int_even_mmap.begin(), int_even_mmap.end()); + if(!CheckEqualContainers(&int_mmap4, &fmmap)) + return false; + } + + //Ordered insertion set + { + std::set int_set; + for(std::size_t i = 0; i != NumElements; ++i){ + int_set.insert(static_cast(i)); + } + //Construction insertion + flat_set fset(ordered_unique_range, int_set.begin(), int_set.end()); + if(!CheckEqualContainers(&int_set, &fset)) + return false; + //Insertion when empty + fset.clear(); + fset.insert(ordered_unique_range, int_set.begin(), int_set.end()); + if(!CheckEqualContainers(&int_set, &fset)) + return false; + //Re-insertion + fset.insert(ordered_unique_range, int_set.begin(), int_set.end()); + std::set int_set2(int_set); + int_set2.insert(int_set.begin(), int_set.end()); + if(!CheckEqualContainers(&int_set2, &fset)) + return false; + //Re-re-insertion + fset.insert(ordered_unique_range, int_set2.begin(), int_set2.end()); + std::set int_set4(int_set2); + int_set4.insert(int_set2.begin(), int_set2.end()); + if(!CheckEqualContainers(&int_set4, &fset)) + return false; + //Re-re-insertion of even + std::set int_even_set; + for(std::size_t i = 0; i < NumElements; i+=2){ + int_set.insert(static_cast(i)); + } + fset.insert(ordered_unique_range, int_even_set.begin(), int_even_set.end()); + int_set4.insert(int_even_set.begin(), int_even_set.end()); + if(!CheckEqualContainers(&int_set4, &fset)) + return false; + } + //Ordered insertion map + { + std::map int_map; + for(std::size_t i = 0; i != NumElements; ++i){ + int_map.insert(std::map::value_type(static_cast(i), static_cast(i))); + } + //Construction insertion + flat_map fmap(ordered_unique_range, int_map.begin(), int_map.end()); + if(!CheckEqualContainers(&int_map, &fmap)) + return false; + //Insertion when empty + fmap.clear(); + fmap.insert(ordered_unique_range, int_map.begin(), int_map.end()); + if(!CheckEqualContainers(&int_map, &fmap)) + return false; + //Re-insertion + fmap.insert(ordered_unique_range, int_map.begin(), int_map.end()); + std::map int_map2(int_map); + int_map2.insert(int_map.begin(), int_map.end()); + if(!CheckEqualContainers(&int_map2, &fmap)) + return false; + //Re-re-insertion + fmap.insert(ordered_unique_range, int_map2.begin(), int_map2.end()); + std::map int_map4(int_map2); + int_map4.insert(int_map2.begin(), int_map2.end()); + if(!CheckEqualContainers(&int_map4, &fmap)) + return false; + //Re-re-insertion of even + std::map int_even_map; + for(std::size_t i = 0; i < NumElements; i+=2){ + int_map.insert(std::map::value_type(static_cast(i), static_cast(i))); + } + fmap.insert(ordered_unique_range, int_even_map.begin(), int_even_map.end()); + int_map4.insert(int_even_map.begin(), int_even_map.end()); + if(!CheckEqualContainers(&int_map4, &fmap)) + return false; + } + + return true; +} + +}}} int main() { @@ -315,6 +480,9 @@ int main() test_move >(); } + if(!flat_tree_ordered_insertion_test()){ + return 1; + } if (0 != set_test< MyBoostSet @@ -459,3 +627,55 @@ int main() } #include + +/* +#include +#include +#include +#include +#include + +struct Request +{ + Request() {}; + + //Move semantics... + Request(BOOST_RV_REF(Request) r) : rvals() //Move constructor + { + rvals.swap(r.rvals); + }; + + Request& operator=(BOOST_RV_REF(Request) r) //Move assignment + { + if (this != &r){ + rvals.swap(r.rvals); + } + return *this; + }; + + // Values I want to be moved, not copied. + boost::container::vector rvals; + + private: + // Mark this class movable but not copyable + BOOST_MOVABLE_BUT_NOT_COPYABLE(Request) +}; + +typedef boost::container::flat_map Requests; +//typedef boost::container::map Requests2; + +int +main() { + Requests req; + + Requests::value_type v; + std::pair ret = req.insert( boost::move(v)); + //std::cout << "Insert success for req: " << ret.second << std::endl; + + //Requests2 req2; + //std::pair ret2 = req2.insert( Requests2::value_type( 7, Request() ) ); + //std::cout << "Insert success for req2: " << ret2.second << std::endl; + + return 0; +} +*/ diff --git a/test/heap_allocator_v1.hpp b/test/heap_allocator_v1.hpp index 10437b5..56fc1a2 100644 --- a/test/heap_allocator_v1.hpp +++ b/test/heap_allocator_v1.hpp @@ -38,19 +38,19 @@ namespace boost { namespace container { namespace test { -//!An STL compatible heap_allocator_v1 that uses a segment manager as +//!An STL compatible heap_allocator_v1 that uses a segment manager as //!memory source. The internal pointer type will of the same type (raw, smart) as //!"typename SegmentManager::void_pointer" type. This allows //!placing the heap_allocator_v1 in shared memory, memory mapped-files, etc...*/ template -class heap_allocator_v1 +class heap_allocator_v1 { private: typedef heap_allocator_v1 self_t; typedef SegmentManager segment_manager; typedef typename segment_manager::void_pointer aux_pointer_t; - typedef typename + typedef typename boost::pointer_to_other ::type cvoid_ptr; @@ -80,7 +80,7 @@ class heap_allocator_v1 //!Obtains an heap_allocator_v1 of other type template struct rebind - { + { typedef heap_allocator_v1 other; }; @@ -97,19 +97,19 @@ class heap_allocator_v1 { return const_pointer(addressof(value)); } */ //!Constructor from the segment manager. Never throws - heap_allocator_v1(segment_manager *segment_mngr) + heap_allocator_v1(segment_manager *segment_mngr) : mp_mngr(segment_mngr) { } //!Constructor from other heap_allocator_v1. Never throws - heap_allocator_v1(const heap_allocator_v1 &other) + heap_allocator_v1(const heap_allocator_v1 &other) : mp_mngr(other.get_segment_manager()){ } //!Constructor from related heap_allocator_v1. Never throws template - heap_allocator_v1(const heap_allocator_v1 &other) + heap_allocator_v1(const heap_allocator_v1 &other) : mp_mngr(other.get_segment_manager()){} - //!Allocates memory for an array of count elements. + //!Allocates memory for an array of count elements. //!Throws boost::container::bad_alloc if there is no enough memory pointer allocate(size_type count, cvoid_ptr hint = 0) { (void)hint; return ::new value_type[count]; } @@ -118,7 +118,7 @@ class heap_allocator_v1 void deallocate(const pointer &ptr, size_type) { return ::delete[] detail::get_pointer(ptr) ; } - //!Construct object, calling constructor. + //!Construct object, calling constructor. //!Throws if T(const T&) throws void construct(const pointer &ptr, const_reference value) { new((void*)detail::get_pointer(ptr)) value_type(value); } @@ -139,13 +139,13 @@ class heap_allocator_v1 //!Equality test for same type of heap_allocator_v1 template inline -bool operator==(const heap_allocator_v1 &alloc1, +bool operator==(const heap_allocator_v1 &alloc1, const heap_allocator_v1 &alloc2) { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); } //!Inequality test for same type of heap_allocator_v1 template inline -bool operator!=(const heap_allocator_v1 &alloc1, +bool operator!=(const heap_allocator_v1 &alloc1, const heap_allocator_v1 &alloc2) { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); } diff --git a/test/list_test.cpp b/test/list_test.cpp index b3fe6b2..2abcdec 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -23,13 +23,13 @@ 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 >; }} diff --git a/test/list_test.hpp b/test/list_test.hpp index c248231..6862ffe 100644 --- a/test/list_test.hpp +++ b/test/list_test.hpp @@ -258,7 +258,7 @@ int list_test (bool copied_allocators_equal = true) boostlist->splice(boostlist->begin(), otherboostlist); stdlist->splice(stdlist->begin(), otherstdlist); if(!CheckEqualContainers(boostlist, stdlist)) - return 1; + return 1; } listsize = (int)boostlist->size(); diff --git a/test/map_test.hpp b/test/map_test.hpp index 45efc31..66dc800 100644 --- a/test/map_test.hpp +++ b/test/map_test.hpp @@ -48,7 +48,7 @@ int map_test () MyBoostMultiMap *boostmultimap = new MyBoostMultiMap; MyStdMultiMap *stdmultimap = new MyStdMultiMap; - //Test construction from a range + //Test construction from a range { //This is really nasty, but we have no other simple choice IntPairType aux_vect[50]; @@ -105,7 +105,7 @@ int map_test () if(!CheckEqualContainers(boostmultimap2, stdmultimap2)) return 1; /* - MyBoostMap *boostmap3 = new MyBoostMap + MyBoostMap *boostmap3 = new MyBoostMap ( ordered_unique_range , boost::make_move_iterator(&aux_vect[0]) , boost::make_move_iterator(aux_vect + 50)); @@ -393,7 +393,7 @@ int map_test () std::pair sret = stdmultimap->equal_range(stdmultimap->begin()->first); - + if( std::distance(bret.first, bret.second) != std::distance(sret.first, sret.second) ){ return 1; @@ -523,7 +523,7 @@ int map_test_copyable () stdmapcopy = *stdmap; boostmmapcopy = *boostmultimap; stdmmapcopy = *stdmultimap; - + if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy)) return 1; if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy)) diff --git a/test/movable_int.hpp b/test/movable_int.hpp index 599dbbb..9402b16 100644 --- a/test/movable_int.hpp +++ b/test/movable_int.hpp @@ -77,8 +77,8 @@ class movable_int int m_int; }; -template -std::basic_ostream & operator<< +template +std::basic_ostream & operator<< (std::basic_ostream & os, movable_int const & p) { @@ -109,7 +109,7 @@ class movable_and_copyable_int movable_and_copyable_int(const movable_and_copyable_int& mmi) : m_int(mmi.m_int) {} - + movable_and_copyable_int(BOOST_RV_REF(movable_and_copyable_int) mmi) : m_int(mmi.m_int) { mmi.m_int = 0; } @@ -148,8 +148,8 @@ class movable_and_copyable_int int m_int; }; -template -std::basic_ostream & operator<< +template +std::basic_ostream & operator<< (std::basic_ostream & os, movable_and_copyable_int const & p) { @@ -177,7 +177,7 @@ class copyable_int copyable_int(const copyable_int& mmi) : m_int(mmi.m_int) {} - + copyable_int & operator= (int i) { this->m_int = i; return *this; } @@ -206,8 +206,8 @@ class copyable_int int m_int; }; -template -std::basic_ostream & operator<< +template +std::basic_ostream & operator<< (std::basic_ostream & os, copyable_int const & p) { diff --git a/test/print_container.hpp b/test/print_container.hpp index f34a9f3..a3de94e 100644 --- a/test/print_container.hpp +++ b/test/print_container.hpp @@ -48,8 +48,8 @@ void PrintContainers(MyBoostCont *boostcont, MyStdCont *stdcont) for(; itboost != itboostend; ++itboost){ std::cout << *itboost << std::endl; } - std::cout << "MyStdCont" << std::endl; - + std::cout << "MyStdCont" << std::endl; + for(; itstd != itstdend; ++itstd){ std::cout << *itstd << std::endl; } diff --git a/test/scoped_allocator_adaptor_test.cpp b/test/scoped_allocator_adaptor_test.cpp index cecfade..6afca6e 100644 --- a/test/scoped_allocator_adaptor_test.cpp +++ b/test/scoped_allocator_adaptor_test.cpp @@ -644,7 +644,7 @@ int main() } { - vector > > dummy; + vector > > dummy; dummy.push_back(0); } @@ -682,15 +682,15 @@ int main() BOOST_STATIC_ASSERT(( !boost::container::uses_allocator < ::mark_on_scoped_allocation - , test_allocator + , test_allocator >::value )); BOOST_STATIC_ASSERT(( boost::container::uses_allocator < ::mark_on_scoped_allocation - , test_allocator + , test_allocator >::value )); BOOST_STATIC_ASSERT(( boost::container::uses_allocator < ::mark_on_scoped_allocation - , test_allocator + , test_allocator >::value )); BOOST_STATIC_ASSERT(( boost::container::constructible_with_allocator_prefix < ::mark_on_scoped_allocation >::value )); diff --git a/test/scoped_allocator_usage_test.cpp b/test/scoped_allocator_usage_test.cpp index 1fbd2ce..bb841a2 100644 --- a/test/scoped_allocator_usage_test.cpp +++ b/test/scoped_allocator_usage_test.cpp @@ -240,7 +240,7 @@ struct container_wrapper : public Container { typedef typename Container::allocator_type allocator_type; - + container_wrapper(const allocator_type &a) : Container(a) {} diff --git a/test/set_test.hpp b/test/set_test.hpp index 95dfee0..2afe4ce 100644 --- a/test/set_test.hpp +++ b/test/set_test.hpp @@ -40,7 +40,7 @@ int set_test () MyBoostMultiSet *boostmultiset = new MyBoostMultiSet; MyStdMultiSet *stdmultiset = new MyStdMultiSet; - //Test construction from a range + //Test construction from a range { IntType aux_vect[50]; for(int i = 0; i < 50; ++i){ @@ -483,7 +483,7 @@ int set_test_copyable () boostmsetcopy = *boostmultiset; stdmsetcopy = *stdmultiset; - + if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy)) return 1; } diff --git a/test/slist_test.cpp b/test/slist_test.cpp index d1c80e3..46d6851 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -22,13 +22,13 @@ 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 >; }} diff --git a/test/stable_vector_test.cpp b/test/stable_vector_test.cpp index fe7d9e1..c69efe4 100644 --- a/test/stable_vector_test.cpp +++ b/test/stable_vector_test.cpp @@ -30,13 +30,13 @@ namespace boost { namespace container { //Explicit instantiation to detect compilation errors -template class stable_vector >; -template class stable_vector >; -template class stable_vector >; }} diff --git a/test/string_test.cpp b/test/string_test.cpp index c51e80b..ce0e9c6 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -26,10 +26,10 @@ using namespace boost::container; -typedef test::dummy_test_allocator DummyCharAllocator; +typedef test::dummy_test_allocator DummyCharAllocator; typedef basic_string, DummyCharAllocator> DummyString; typedef test::dummy_test_allocator DummyStringAllocator; -typedef test::dummy_test_allocator DummyWCharAllocator; +typedef test::dummy_test_allocator DummyWCharAllocator; typedef basic_string, DummyWCharAllocator> DummyWString; typedef test::dummy_test_allocator DummyWStringAllocator; @@ -67,7 +67,7 @@ template bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2) { StringEqual comp; - return std::equal(strvect1->begin(), strvect1->end(), + return std::equal(strvect1->begin(), strvect1->end(), strvect2->begin(), comp); } @@ -159,7 +159,7 @@ int string_test() return 1; } - //Now push back moving + //Now push back moving for(int i = 0; i < MaxSize; ++i){ auxBoostString = string_literals::String(); auxStdString = string_literals::String(); @@ -189,7 +189,7 @@ int string_test() return 1; } - //Now push front moving + //Now push front moving for(int i = 0; i < MaxSize; ++i){ auxBoostString = string_literals::String(); auxStdString = string_literals::String(); @@ -214,15 +214,15 @@ int string_test() boost_swapper.swap(auxBoostString); std_swapper.swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) - return 1; + return 1; if(!StringEqual()(boost_swapper, std_swapper)) - return 1; + return 1; boost_swapper.swap(auxBoostString); std_swapper.swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) - return 1; + return 1; if(!StringEqual()(boost_swapper, std_swapper)) - return 1; + return 1; //Shrink_to_fit auxBoostString.shrink_to_fit(); @@ -249,7 +249,7 @@ int string_test() boost_swapper.swap(auxBoostString); std_swapper.swap(auxStdString); if(!StringEqual()(auxBoostString, auxStdString)) - return 1; + return 1; if(!StringEqual()(boost_swapper, std_swapper)) return 1; boost_swapper.swap(auxBoostString); @@ -280,9 +280,9 @@ int string_test() for(int i = 0; i < MaxSize; ++i){ (*boostStringVect)[i].append(sufix); (*stdStringVect)[i].append(sufix); - (*boostStringVect)[i].insert((*boostStringVect)[i].begin(), + (*boostStringVect)[i].insert((*boostStringVect)[i].begin(), prefix, prefix + prefix_size); - (*stdStringVect)[i].insert((*stdStringVect)[i].begin(), + (*stdStringVect)[i].insert((*stdStringVect)[i].begin(), prefix, prefix + prefix_size); } @@ -310,10 +310,10 @@ int string_test() if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; for(int i = 0; i < MaxSize; ++i){ - (*boostStringVect)[i].replace((*boostStringVect)[i].begin(), + (*boostStringVect)[i].replace((*boostStringVect)[i].begin(), (*boostStringVect)[i].end(), string_literals::String()); - (*stdStringVect)[i].replace((*stdStringVect)[i].begin(), + (*stdStringVect)[i].replace((*stdStringVect)[i].begin(), (*stdStringVect)[i].end(), string_literals::String()); } @@ -330,7 +330,7 @@ int string_test() { typedef std::basic_string StdString; typedef basic_string BoostString; - + BoostString bs2 = string_literals::String(); StdString ss2 = string_literals::String(); BoostString bs3 = string_literals::Suffix(); diff --git a/test/vector_test.cpp b/test/vector_test.cpp index d7fc47c..afc03b8 100644 --- a/test/vector_test.cpp +++ b/test/vector_test.cpp @@ -30,13 +30,13 @@ 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 >; }} diff --git a/test/vector_test.hpp b/test/vector_test.hpp index 847e9e8..a46d42b 100644 --- a/test/vector_test.hpp +++ b/test/vector_test.hpp @@ -90,15 +90,15 @@ int vector_test() MyStdVector *stdvector = new MyStdVector; boostvector->resize(100); stdvector->resize(100); - if(!test::CheckEqualContainers(boostvector, stdvector)) return 1; + if(!test::CheckEqualContainers(boostvector, stdvector)) return 1; boostvector->resize(200); stdvector->resize(200); - if(!test::CheckEqualContainers(boostvector, stdvector)) return 1; + if(!test::CheckEqualContainers(boostvector, stdvector)) return 1; boostvector->resize(0); stdvector->resize(0); - if(!test::CheckEqualContainers(boostvector, stdvector)) return 1; + if(!test::CheckEqualContainers(boostvector, stdvector)) return 1; for(int i = 0; i < max; ++i){ IntType new_int(i);