diff --git a/bench/Jamfile.v2 b/bench/Jamfile.v2 index cc1e715..2be27f5 100644 --- a/bench/Jamfile.v2 +++ b/bench/Jamfile.v2 @@ -21,7 +21,7 @@ rule test_all for local fileb in [ glob *.cpp ] { - all_rules += [ run $(fileb) /boost/timer//boost_timer + all_rules += [ run $(fileb) /boost/timer//boost_timer /boost/container//boost_container : # additional args : # test-files : # requirements diff --git a/bench/bench_set.cpp b/bench/bench_set.cpp index 662d11b..ac8c98a 100644 --- a/bench/bench_set.cpp +++ b/bench/bench_set.cpp @@ -10,6 +10,7 @@ #include "boost/container/set.hpp" #include "boost/container/flat_set.hpp" +#include "boost/container/allocator.hpp" #include #include #include @@ -22,9 +23,9 @@ using boost::timer::cpu_times; using boost::timer::nanosecond_type; #ifdef NDEBUG -static const std::size_t N = 5000; -#else static const std::size_t N = 500; +#else +static const std::size_t N = 50; #endif void compare_times(cpu_times time_numerator, cpu_times time_denominator){ @@ -334,15 +335,18 @@ int main() { //set vs std::set launch_tests< boost::container::set , std::set > - ("boost::container::set", "std::set");/* + ("boost::container::set", "std::set"); + //set vs set<..., allocator_v2> + launch_tests< boost::container::set , boost::container::set, boost::container::allocator > > + ("boost::container::set", "boost::container::set" ); //multiset vs std::set launch_tests< boost::container::multiset , std::multiset > - ("boost::container::multiset", "std::multiset");*/ + ("boost::container::multiset", "std::multiset"); //flat_set vs set - //launch_tests< boost::container::flat_set , boost::container::set > - //("boost::container::flat_set", "boost::container::set"); + launch_tests< boost::container::flat_set , boost::container::set > + ("boost::container::flat_set", "boost::container::set"); //flat_multiset vs multiset - //launch_tests< boost::container::flat_multiset , boost::container::multiset > - //("boost::container::flat_multiset", "boost::container::multiset"); - return 1; + launch_tests< boost::container::flat_multiset , boost::container::multiset > + ("boost::container::flat_multiset", "boost::container::multiset"); + return 0; } diff --git a/bench/bench_static_vector.cpp b/bench/bench_static_vector.cpp index 71e48a9..a331eb9 100644 --- a/bench/bench_static_vector.cpp +++ b/bench/bench_static_vector.cpp @@ -4,8 +4,8 @@ // @date Aug 14, 2011 // @author Andrew Hundt // -// (C) 2011-2012 Andrew Hundt -// (C) 2013 Ion Gaztanaga +// (C) 2011-2013 Andrew Hundt +// (C) 2013-2013 Ion Gaztanaga // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -28,7 +28,7 @@ using boost::timer::cpu_times; using boost::timer::nanosecond_type; #ifdef NDEBUG -static const std::size_t N = 1000; +static const std::size_t N = 300; #else static const std::size_t N = 100; #endif @@ -141,5 +141,5 @@ int main() }catch(std::exception e){ std::cout << e.what(); } - return 1; + return 0; } diff --git a/bench/detail/varray.hpp b/bench/detail/varray.hpp index 874daae..eb63470 100644 --- a/bench/detail/varray.hpp +++ b/bench/detail/varray.hpp @@ -10,7 +10,7 @@ #ifndef BOOST_CONTAINER_DETAIL_VARRAY_HPP #define BOOST_CONTAINER_DETAIL_VARRAY_HPP -#if (defined _MSC_VER) +#if defined(_MSC_VER) # pragma once #endif @@ -19,8 +19,8 @@ #include #include "varray_util.hpp" -#include "varray_concept.hpp" -#include +//#include "varray_concept.hpp" +//#include #ifndef BOOST_NO_EXCEPTIONS #include @@ -229,7 +229,7 @@ class varray (varray) ); - BOOST_CONCEPT_ASSERT((concept::VArrayStrategy)); + //BOOST_CONCEPT_ASSERT((concept::VArrayStrategy)); typedef boost::aligned_storage< sizeof(Value[Capacity]), @@ -353,7 +353,7 @@ public: varray(Iterator first, Iterator last) : m_size(0) { - BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal)); // Make sure you passed a ForwardIterator + //BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal)); // Make sure you passed a ForwardIterator this->assign(first, last); // may throw } @@ -890,7 +890,7 @@ public: template iterator insert(iterator position, Iterator first, Iterator last) { - BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal)); // Make sure you passed a ForwardIterator + //BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal)); // Make sure you passed a ForwardIterator typedef typename boost::iterator_traversal::type traversal; this->insert_dispatch(position, first, last, traversal()); @@ -975,7 +975,7 @@ public: template void assign(Iterator first, Iterator last) { - BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal)); // Make sure you passed a ForwardIterator + //BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal)); // Make sure you passed a ForwardIterator typedef typename boost::iterator_traversal::type traversal; this->assign_dispatch(first, last, traversal()); // may throw @@ -1728,7 +1728,7 @@ private: template void insert_dispatch(iterator position, Iterator first, Iterator last, boost::random_access_traversal_tag const&) { - BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal)); // Make sure you passed a RandomAccessIterator + //BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversal)); // Make sure you passed a RandomAccessIterator errh::check_iterator_end_eq(*this, position); @@ -2015,7 +2015,7 @@ public: void insert(iterator, Iterator first, Iterator last) { // TODO - add MPL_ASSERT, check if Iterator is really an iterator - typedef typename boost::iterator_traversal::type traversal; + //typedef typename boost::iterator_traversal::type traversal; errh::check_capacity(*this, std::distance(first, last)); // may throw } @@ -2039,7 +2039,7 @@ public: void assign(Iterator first, Iterator last) { // TODO - add MPL_ASSERT, check if Iterator is really an iterator - typedef typename boost::iterator_traversal::type traversal; + //typedef typename boost::iterator_traversal::type traversal; errh::check_capacity(*this, std::distance(first, last)); // may throw } diff --git a/bench/detail/varray_util.hpp b/bench/detail/varray_util.hpp index 23f0d24..01b533b 100644 --- a/bench/detail/varray_util.hpp +++ b/bench/detail/varray_util.hpp @@ -566,13 +566,6 @@ template inline void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p) { - typedef typename - ::boost::mpl::and_< - is_corresponding_value, - ::boost::has_trivial_copy

- >::type - use_memcpy; - typedef typename boost::iterator_value::type V; new (static_cast(boost::addressof(*pos))) V(::boost::move(p)); // may throw } diff --git a/bench/varray.hpp b/bench/varray.hpp index 8dcb5de..8022b9a 100644 --- a/bench/varray.hpp +++ b/bench/varray.hpp @@ -10,13 +10,14 @@ #ifndef BOOST_CONTAINER_VARRAY_HPP #define BOOST_CONTAINER_VARRAY_HPP -#if (defined _MSC_VER) +#if defined(_MSC_VER) # pragma once #endif #include #include "detail/varray.hpp" +#include namespace boost { namespace container { diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index fe7f054..3e3b32a 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -1,6 +1,6 @@ # Boost.Container library documentation Jamfile --------------------------------- # -# Copyright Ion Gaztanaga 2009-2012. Use, modification and +# Copyright Ion Gaztanaga 2009-2013. Use, modification and # distribution is 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) diff --git a/doc/container.qbk b/doc/container.qbk index 0c88b82..1bf5290 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -49,9 +49,13 @@ In short, what does [*Boost.Container] offer? [section:introduction_building_container Building Boost.Container] -There is no need to compile [*Boost.Container], since it's -a header only library. Just include your Boost header directory in your -compiler include path. +There is no need to compile [*Boost.Container] if you don't use [link container.extended_functionality.extended_allocators Extended Allocators] +since in that case it's a header-only library. Just include your Boost header directory in your compiler include path. + +[link container.extended_functionality.extended_allocators Extended Allocators] are +implemented as a separately compiled library, so you must install binaries in a location that can be found by your linker +when using these classes. If you followed the [@http://www.boost.org/doc/libs/release/more/getting_started/index.html Boost Getting Started] instructions, +that's already been done for you. [endsect] @@ -148,12 +152,19 @@ today, in fact, implementors would have to go out of their way to prohibit it!]] C++11 standard is also cautious about incomplete types and STL: ["['17.6.4.8 Other functions (...) 2. the effects are undefined in the following cases: (...) In particular - if an incomplete type (3.9) is used as a template argument when instantiating a template component, -unless specifically allowed for that component]]. Fortunately [*Boost.Container] containers are designed -to support type erasure and recursive types, so let's see some examples: +unless specifically allowed for that component]]. + +Fortunately all [*Boost.Container] containers except +[classref boost::container::static_vector static_vector] and +[classref boost::container::basic_string basic_string] are designed to support incomplete types. +[classref boost::container::static_vector static_vector] is special because +it statically allocates memory for `value_type` and this requires complete types and +[classref boost::container::basic_string basic_string] implements Small String Optimization which +also requires complete types. [section:recursive_containers Recursive containers] -All containers offered by [*Boost.Container] can be used to define recursive containers: +Most [*Boost.Container] containers can be used to define recursive containers: [import ../example/doc_recursive_containers.cpp] [doc_recursive_containers] @@ -261,8 +272,8 @@ When dealing with user-defined classes, (e.g. when constructing user-defined cla propagate error situations internally as no error will be propagated through [*Boost.Container]. * If `BOOST_NO_EXCEPTIONS` is *not* defined, the library propagates exceptions offering the exception guarantees detailed in the documentation. -When the library needs to throw an exception (such as `out_of_range` when an incorrect index is used in `vector::at`)], the library calls -a throw callback declared in ``: +When the library needs to throw an exception (such as `out_of_range` when an incorrect index is used in `vector::at`), the library calls +a throw-callback declared in [headerref boost/container/throw_exception.hpp]: * If `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` is defined, then the programmer must provide its own definition for all `throw_xxx` functions. Those functions can't return, they must throw an exception or call `std::exit` or `std::abort`. @@ -522,6 +533,123 @@ using [@http://en.cppreference.com/w/cpp/language/default_initialization default [endsect] +[section:ordered_range_insertion Ordered range insertion for associative containers (['ordered_unique_range], ['ordered_range]) ] + +When filling associative containers big performance gains can be achieved if the input range to be inserted +is guaranteed by the user to be ordered according to the predicate. This can happen when inserting values from a `set` to +a `multiset` or between different associative container families (`[multi]set/map` vs. `flat_[multi]set/map`). + +[*Boost.Container] has some overloads for constructors and insertions taking an `ordered_unique_range_t` or +an `ordered_range_t` tag parameters as the first argument. When an `ordered_unique_range_t` overload is used, the +user notifies the container that the input range is ordered according to the container predicate and has no +duplicates. When an `ordered_range_t` overload is used, the +user notifies the container that the input range is ordered according to the container predicate but it might +have duplicates. With this information, the container can avoid multiple predicate calls and improve insertion +times. + +[endsect] + +[section:constant_time_range_splice Constant-time range splice for `(s)list`] + +In the first C++ standard `list::size()` was not required to be constant-time, +and that caused some controversy in the C++ community. Quoting Howard Hinnant's +[@http://home.roadrunner.com/~hinnant/On_list_size.html ['On List Size]] paper: + +[: ['There is a considerable debate on whether `std::list::size()` should be O(1) or O(N). +The usual argument notes that it is a tradeoff with:] + +`splice(iterator position, list& x, iterator first, iterator last);` + +['If size() is O(1) and this != &x, then this method must perform a linear operation so that it +can adjust the size member in each list]] + +C++11 definitely required `size()` to be O(1), so range splice became O(N). However, +Howard Hinnant's paper proposed a new `splice` overload so that even O(1) `list:size()` +implementations could achieve O(1) range splice when the range size was known to the caller: + +[: `void splice(iterator position, list& x, iterator first, iterator last, size_type n);` + + [*Effects]: Inserts elements in the range [first, last) before position and removes the elements from x. + + [*Requires]: [first, last) is a valid range in x. The result is undefined if position is an iterator in the range [first, last). Invalidates only the iterators and references to the spliced elements. n == distance(first, last). + + [*Throws]: Nothing. + + [*Complexity]: Constant time. +] + +This new splice signature allows the client to pass the distance of the input range in. +This information is often available at the call site. If it is passed in, +then the operation is constant time, even with an O(1) size. + +[*Boost.Container] implements this overload for `list` and a modified version of it for `slist` +(as `slist::size()` is also `O(1)`). + +[endsect] + +[section:extended_allocators Extended allocators] + +Many C++ programmers have ever wondered where does good old realloc fit in C++. And that's a good question. +Could we improve [classref boost::container::vector vector] performance using memory expansion mechanisms +to avoid too many copies? But [classref boost::container::vector vector] is not the only container that +could benefit from an improved allocator interface: we could take advantage of the insertion of multiple +elements in [classref boost::container::list list] using a burst allocation mechanism that could amortize +costs (mutex locks, free memory searches...) that can't be amortized when using single node allocation +strategies. + +These improvements require extending the STL allocator interface and use make use of a new +general purpose allocator since new and delete don't offer expansion and burst capabilities. + +* [*Boost.Container] containers support an extended allocator interface based on an evolution of proposals +[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1953.html N1953: Upgrading the Interface of Allocators using API Versioning], +[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2045.html N2045: Improving STL allocators] +and the article +[@http://www.drivehq.com/web/igaztanaga/allocplus/ Applying classic memory allocation strategies to C++ containers]. +The extended allocator interface is implemented by [classref boost::container::allocator allocator], +[classref boost::container::adaptive_pool adaptive_pool] and [classref boost::container::node_allocator node_allocator] +classes. + +* Extended allocators use a modified [@http://g.oswego.edu/dl/html/malloc.html Doug Lea Malloc (DLMalloc)] low-level +allocator and offers an C API to implement memory expansion and burst allocations. DLmalloc is known to be very size +and speed efficient, and this allocator is used as the basis of many malloc implementations, including multithreaded +allocators built above DLmalloc (See [@http://www.malloc.de/en/ ptmalloc2, ptmalloc3] or +[@http://www.nedprod.com/programs/portable/nedmalloc/ nedmalloc]). This low-level allocator is implemented as +a separately compiled library whereas [classref boost::container::allocator allocator], +[classref boost::container::adaptive_pool adaptive_pool] and [classref boost::container::node_allocator node_allocator] +are header-only classes. + +The following extended allocators are provided: + +* [classref boost::container::allocator allocator]: This extended allocator offers expansion, shrink-in place + and burst allocation capabilities implemented as a thin wrapper around the modified DLMalloc. + It can be used with all containers and it should be the default choice when the programmer wants to use + extended allocator capabilities. + +* [classref boost::container::node_allocator node_allocator]: It's a + [@http://www.boost.org/doc/libs/1_55_0/libs/pool/doc/html/boost_pool/pool/pooling.html#boost_pool.pool.pooling.simple Simple Segregated Storage] + allocator, similar to [*Boost.Pool] that takes advantage of the modified DLMalloc burst interface. It does not return + memory to the DLMalloc allocator (and thus, to the system), unless explicitly requested. It does offer a very small + memory overhead so it's suitable for node containers ([boost::container::list list], [boost::container::slist slist] + [boost::container::set set]...) that allocate very small `value_type`s and it offers improved node allocation times + for single node allocations with respecto to [classref boost::container::allocator allocator]. + +* [classref boost::container::adaptive_pool adaptive_pool]: It's a low-overhead node allocator that can return memory + to the system. The overhead can be very low (< 5% for small nodes) and it's nearly as fast as [classref boost::container::node_allocator node_allocator]. + It's also suitable for node containers. + +[endsect] + +[/ +/a__section:previous_element_slist Previous element for slist__a +/ +/The C++11 `std::forward_list` class implement a singly linked list, similar to `slist`, and these +/containers only offer forward iterators and implement insertions and splice operations that operate with ranges +/to be inserted ['after] that position. In those cases, sometimes it's interesting to obtain an iterator pointing +/to the previous element of another element. This operation can be implemented +/ +/a__endsect__a +] + [/ /a__section:get_stored_allocator Obtain stored allocator__a / @@ -532,18 +660,6 @@ using [@http://en.cppreference.com/w/cpp/language/default_initialization default /http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html / /a__endsect__a -/ -/a__section:ordered_range_insertion Ordered range insertion (a__'ordered_unique_range__a, a__'ordered_range__a) __a -/ -/a__endsect__a -/ -/a__section:constant_time_range_splice Constant-time range splice__a -/ -/a__endsect__a -/ -/a__section:previous_element_slist Slist previous element__a -/ -/a__endsect__a /] [endsect] @@ -709,9 +825,10 @@ use [*Boost.Container]? There are several reasons for that: * Default constructors don't allocate memory at all, which improves performance and usually implies a no-throw guarantee (if predicate's or allocator's default constructor doesn't throw). * Small string optimization for [classref boost::container::basic_string basic_string]. -* New extensions beyond the standard based on user feedback to improve code performance. +* [link container.extended_functionality Extended functionality] beyond the standard based + on user feedback to improve code performance. * You need a portable implementation that works when compiling without exceptions support or - you need to customize the error handling when a container needs to signall an exceptional error. + you need to customize the error handling when a container needs to signal an exceptional error. [endsect] @@ -759,6 +876,15 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes Release Notes] +[section:release_notes_boost_1_56_00 Boost 1.56 Release] + +* Added DlMalloc-based [link container.extended_functionality.extended_allocators Extended Allocators]. + +* Fixed bugs: + * [@https://svn.boost.org/trac/boost/ticket/9338 #9338: ['"VS2005 compiler errors in swap() definition after including container/memory_util.hpp"]]. + +[endsect] + [section:release_notes_boost_1_55_00 Boost 1.55 Release] * Implemented [link container.main_features.scary_iterators SCARY iterators]. @@ -769,7 +895,8 @@ use [*Boost.Container]? There are several reasons for that: [@https://svn.boost.org/trac/boost/ticket/9009 #9009], [@https://svn.boost.org/trac/boost/ticket/9064 #9064], [@https://svn.boost.org/trac/boost/ticket/9092 #9092], - [@https://svn.boost.org/trac/boost/ticket/9108 #9108]. + [@https://svn.boost.org/trac/boost/ticket/9108 #9108], + [@https://svn.boost.org/trac/boost/ticket/9166 #9166], [endsect] diff --git a/example/doc_emplace.cpp b/example/doc_emplace.cpp index d494061..76b5939 100644 --- a/example/doc_emplace.cpp +++ b/example/doc_emplace.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2009-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/example/doc_move_containers.cpp b/example/doc_move_containers.cpp index 867db0b..ffb09de 100644 --- a/example/doc_move_containers.cpp +++ b/example/doc_move_containers.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2009-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/example/doc_recursive_containers.cpp b/example/doc_recursive_containers.cpp index e486209..8e6c33f 100644 --- a/example/doc_recursive_containers.cpp +++ b/example/doc_recursive_containers.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2009-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,9 +11,10 @@ #include //[doc_recursive_containers #include +#include +#include #include #include -#include #include using namespace boost::container; @@ -23,6 +24,10 @@ struct data int i_; //A vector holding still undefined class 'data' vector v_; + //A stable_vector holding still undefined class 'data' + stable_vector sv_; + //A stable_vector holding still undefined class 'data' + deque d_; //A list holding still undefined 'data' list l_; //A map holding still undefined 'data' diff --git a/example/doc_type_erasure.cpp b/example/doc_type_erasure.cpp index 1c56f7f..e776062 100644 --- a/example/doc_type_erasure.cpp +++ b/example/doc_type_erasure.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2009-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/include/boost/container/allocator_traits.hpp b/include/boost/container/allocator_traits.hpp index aa8194a..613d116 100644 --- a/include/boost/container/allocator_traits.hpp +++ b/include/boost/container/allocator_traits.hpp @@ -6,7 +6,7 @@ // ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -38,7 +38,7 @@ #include #endif -///@cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { namespace container { @@ -56,7 +56,7 @@ struct is_std_allocator< std::allocator > } //namespace container_detail { -///@endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! The class template allocator_traits supplies a uniform interface to all allocator types. //! This class is a C++03-compatible implementation of std::allocator_traits @@ -94,29 +94,29 @@ struct allocator_traits //! typedef see_documentation size_type; //! Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant - //! type with internal constant static member `value` == false. + //! type with internal constant static member value == false. typedef see_documentation propagate_on_container_copy_assignment; //! Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant - //! type with internal constant static member `value` == false. + //! type with internal constant static member value == false. typedef see_documentation propagate_on_container_move_assignment; //! Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant - //! type with internal constant static member `value` == false. + //! type with internal constant static member value == false. typedef see_documentation propagate_on_container_swap; //! Defines an allocator: Alloc::rebind::other if such a type exists; otherwise, Alloc //! if Alloc is a class template instantiation of the form Alloc, where Args is zero or //! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed. //! - //! In C++03 compilers `rebind_alloc` is a struct derived from an allocator + //! In C++03 compilers rebind_alloc is a struct derived from an allocator //! deduced by previously detailed rules. template using rebind_alloc = see_documentation; - //! In C++03 compilers `rebind_traits` is a struct derived from - //! `allocator_traits`, where `OtherAlloc` is - //! the allocator deduced by rules explained in `rebind_alloc`. + //! In C++03 compilers rebind_traits is a struct derived from + //! allocator_traits, where OtherAlloc is + //! the allocator deduced by rules explained in rebind_alloc. template using rebind_traits = allocator_traits >; //! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers. - //! `type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`. + //! type is an allocator related to Alloc deduced deduced by rules explained in rebind_alloc. template struct portable_rebind_alloc { typedef see_documentation type; }; @@ -206,19 +206,19 @@ struct allocator_traits { typedef typename boost::intrusive::detail::type_rebinder::type type; }; #endif //BOOST_CONTAINER_DOXYGEN_INVOKED - //! Returns: `a.allocate(n)` + //! Returns: a.allocate(n) //! static pointer allocate(Alloc &a, size_type n) { return a.allocate(n); } - //! Returns: `a.deallocate(p, n)` + //! Returns: a.deallocate(p, n) //! //! Throws: Nothing static void deallocate(Alloc &a, pointer p, size_type n) { a.deallocate(p, n); } - //! Effects: calls `a.allocate(n, p)` if that call is well-formed; - //! otherwise, invokes `a.allocate(n)` + //! Effects: calls a.allocate(n, p) if that call is well-formed; + //! otherwise, invokes a.allocate(n) static pointer allocate(Alloc &a, size_type n, const_void_pointer p) { const bool value = boost::container::container_detail:: @@ -228,10 +228,10 @@ struct allocator_traits return allocator_traits::priv_allocate(flag, a, n, p); } - //! Effects: calls `a.destroy(p)` if that call is well-formed; - //! otherwise, invokes `p->~T()`. + //! Effects: calls a.destroy(p) if that call is well-formed; + //! otherwise, invokes p->~T(). template - static void destroy(Alloc &a, T*p) + static void destroy(Alloc &a, T*p) BOOST_CONTAINER_NOEXCEPT { typedef T* destroy_pointer; const bool value = boost::container::container_detail:: @@ -241,9 +241,9 @@ struct allocator_traits allocator_traits::priv_destroy(flag, a, p); } - //! Returns: `a.max_size()` if that expression is well-formed; otherwise, - //! `numeric_limits::max()`. - static size_type max_size(const Alloc &a) + //! Returns: a.max_size() if that expression is well-formed; otherwise, + //! numeric_limits::max(). + static size_type max_size(const Alloc &a) BOOST_CONTAINER_NOEXCEPT { const bool value = boost::container::container_detail:: has_member_function_callable_with_max_size @@ -252,7 +252,7 @@ struct allocator_traits return allocator_traits::priv_max_size(flag, a); } - //! Returns: `a.select_on_container_copy_construction()` if that expression is well-formed; + //! Returns: a.select_on_container_copy_construction() if that expression is well-formed; //! otherwise, a. static #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -276,8 +276,8 @@ struct allocator_traits } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - //! Effects: calls `a.construct(p, std::forward(args)...)` if that call is well-formed; - //! otherwise, invokes `::new (static_cast(p)) T(std::forward(args)...)` + //! Effects: calls a.construct(p, std::forward(args)...) if that call is well-formed; + //! otherwise, invokes ::new (static_cast(p)) T(std::forward(args)...) template static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args) { @@ -285,7 +285,7 @@ struct allocator_traits allocator_traits::priv_construct(flag, a, p, ::boost::forward(args)...); } #endif - ///@cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) private: static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p) @@ -295,23 +295,23 @@ struct allocator_traits { return allocator_traits::allocate(a, n); } template - static void priv_destroy(boost::true_type, Alloc &a, T* p) + static void priv_destroy(boost::true_type, Alloc &a, T* p) BOOST_CONTAINER_NOEXCEPT { a.destroy(p); } template - static void priv_destroy(boost::false_type, Alloc &, T* p) + static void priv_destroy(boost::false_type, Alloc &, T* p) BOOST_CONTAINER_NOEXCEPT { p->~T(); (void)p; } - static size_type priv_max_size(boost::true_type, const Alloc &a) + static size_type priv_max_size(boost::true_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT { return a.max_size(); } - static size_type priv_max_size(boost::false_type, const Alloc &) + static size_type priv_max_size(boost::false_type, const Alloc &) BOOST_CONTAINER_NOEXCEPT { return (std::numeric_limits::max)(); } static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a) { return a.select_on_container_copy_construction(); } - static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a) + static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a) BOOST_CONTAINER_NOEXCEPT { return a; } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -394,7 +394,7 @@ struct allocator_traits { ::new((void*)p) T; } #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) - ///@endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; } //namespace container { diff --git a/include/boost/container/container_fwd.hpp b/include/boost/container/container_fwd.hpp index 271cc8b..493fd3b 100644 --- a/include/boost/container/container_fwd.hpp +++ b/include/boost/container/container_fwd.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,11 +15,35 @@ # pragma once #endif +//! \file +//! This header file forward declares the following classes: +//! - boost::container::vector +//! - boost::container::stable_vector +//! - boost::container::static_vector +//! - boost::container::slist +//! - boost::container::list +//! - boost::container::set +//! - boost::container::multiset +//! - boost::container::map +//! - boost::container::multimap +//! - boost::container::flat_set +//! - boost::container::flat_multiset +//! - boost::container::flat_map +//! - boost::container::flat_multimap +//! - boost::container::basic_string +//! - boost::container::string +//! - boost::container::wstring +//! - boost::container::allocator +//! - boost::container::node_allocator +//! - boost::container::adaptive_pool +//! +//! and defines the following types: + ////////////////////////////////////////////////////////////////////////////// // Standard predeclarations ////////////////////////////////////////////////////////////////////////////// -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost{ namespace intrusive{ @@ -32,13 +56,14 @@ namespace bi = boost::intrusive; }}} +#include #include #include #include #include #include -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED ////////////////////////////////////////////////////////////////////////////// // Containers @@ -47,89 +72,120 @@ namespace bi = boost::intrusive; namespace boost { namespace container { -//vector class +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + template > class vector; -//vector class template > class stable_vector; -//vector class +template +class static_vector; + template > class deque; -//list class template > class list; -//slist class template > class slist; -//set class template ,class Allocator = std::allocator > class set; -//multiset class template ,class Allocator = std::allocator > class multiset; -//map class template ,class Allocator = std::allocator > > class map; -//multimap class template ,class Allocator = std::allocator > > class multimap; -//flat_set class template ,class Allocator = std::allocator > class flat_set; -//flat_multiset class template ,class Allocator = std::allocator > class flat_multiset; -//flat_map class template ,class Allocator = std::allocator > > class flat_map; -//flat_multimap class template ,class Allocator = std::allocator > > class flat_multimap; -//basic_string class template ,class Allocator = std::allocator > class basic_string; +typedef basic_string + + ,std::allocator > +string; + +typedef basic_string + + ,std::allocator > +wstring; + +static const std::size_t ADP_nodes_per_block = 256u; +static const std::size_t ADP_max_free_blocks = 2u; +static const std::size_t ADP_overhead_percent = 1u; +static const std::size_t ADP_only_alignment = 0u; + +template < class T + , std::size_t NodesPerBlock = ADP_nodes_per_block + , std::size_t MaxFreeBlocks = ADP_max_free_blocks + , std::size_t OverheadPercent = ADP_overhead_percent + , unsigned Version = 2 + > +class adaptive_pool; + +template < class T + , unsigned Version = 2 + , unsigned int AllocationDisableMask = 0> +class allocator; + +static const std::size_t NodeAlloc_nodes_per_block = 256u; + +template + < class T + , std::size_t NodesPerBlock = NodeAlloc_nodes_per_block + , std::size_t Version = 2> +class node_allocator; + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Type used to tag that the input range is //! guaranteed to be ordered struct ordered_range_t @@ -149,17 +205,27 @@ struct ordered_unique_range_t //! guaranteed to be ordered and unique static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t(); -//! Type used to tag that the input range is -//! guaranteed to be ordered and unique +//! Type used to tag that the inserted values +//! should be default initialized struct default_init_t {}; -//! Value used to tag that the input range is -//! guaranteed to be ordered and unique +//! Value used to tag that the inserted values +//! should be default initialized static const default_init_t default_init = default_init_t(); -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -namespace detail_really_deep_namespace { +//! Type used to tag that the inserted values +//! should be value initialized +struct value_init_t +{}; + +//! Value used to tag that the inserted values +//! should be value initialized +static const value_init_t value_init = value_init_t(); + + +namespace container_detail_really_deep_namespace { //Otherwise, gcc issues a warning of previously defined //anonymous_instance and unique_instance @@ -175,7 +241,7 @@ struct dummy } //detail_really_deep_namespace { -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }} //namespace boost { namespace container { diff --git a/include/boost/container/deque.hpp b/include/boost/container/deque.hpp index 136b4f6..6358f20 100644 --- a/include/boost/container/deque.hpp +++ b/include/boost/container/deque.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -45,7 +45,7 @@ namespace boost { namespace container { -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED template > #else @@ -465,7 +465,7 @@ class deque_base const allocator_type &alloc() const BOOST_CONTAINER_NOEXCEPT { return members_; } }; -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! Deque class //! @@ -476,10 +476,10 @@ template #endif class deque : protected deque_base { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: typedef deque_base Base; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -503,7 +503,7 @@ class deque : protected deque_base typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: // Internal typedefs BOOST_COPYABLE_AND_MOVABLE(deque) @@ -512,7 +512,7 @@ class deque : protected deque_base { return Base::s_buffer_size(); } typedef allocator_traits allocator_traits_type; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -549,8 +549,8 @@ class deque : protected deque_base explicit deque(size_type n) : Base(n, allocator_type()) { - container_detail::insert_value_initialized_n_proxy proxy(this->alloc()); - proxy.uninitialized_copy_n_and_update(this->begin(), n); + container_detail::insert_value_initialized_n_proxy proxy; + proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n); //deque_base will deallocate in case of exception... } @@ -566,8 +566,8 @@ class deque : protected deque_base deque(size_type n, default_init_t) : Base(n, allocator_type()) { - container_detail::insert_default_initialized_n_proxy proxy(this->alloc()); - proxy.uninitialized_copy_n_and_update(this->begin(), n); + container_detail::insert_default_initialized_n_proxy proxy; + proxy.uninitialized_copy_n_and_update(this->alloc(), this->begin(), n); //deque_base will deallocate in case of exception... } @@ -978,7 +978,7 @@ class deque : protected deque_base this->priv_erase_last_n(len - new_size); else{ const size_type n = new_size - this->size(); - container_detail::insert_value_initialized_n_proxy proxy(this->alloc()); + container_detail::insert_value_initialized_n_proxy proxy; priv_insert_back_aux_impl(n, proxy); } } @@ -998,7 +998,7 @@ class deque : protected deque_base this->priv_erase_last_n(len - new_size); else{ const size_type n = new_size - this->size(); - container_detail::insert_default_initialized_n_proxy proxy(this->alloc()); + container_detail::insert_default_initialized_n_proxy proxy; priv_insert_back_aux_impl(n, proxy); } } @@ -1155,7 +1155,7 @@ class deque : protected deque_base } else{ typedef container_detail::insert_non_movable_emplace_proxy type; - this->priv_insert_front_aux_impl(1, type(this->alloc(), boost::forward(args)...)); + this->priv_insert_front_aux_impl(1, type(boost::forward(args)...)); } } @@ -1177,7 +1177,7 @@ class deque : protected deque_base } else{ typedef container_detail::insert_non_movable_emplace_proxy type; - this->priv_insert_back_aux_impl(1, type(this->alloc(), boost::forward(args)...)); + this->priv_insert_back_aux_impl(1, type(boost::forward(args)...)); } } @@ -1203,7 +1203,7 @@ class deque : protected deque_base } else{ typedef container_detail::insert_emplace_proxy type; - return this->priv_insert_aux_impl(p, 1, type(this->alloc(), boost::forward(args)...)); + return this->priv_insert_aux_impl(p, 1, type(boost::forward(args)...)); } } @@ -1222,10 +1222,10 @@ class deque : protected deque_base priv_push_front_simple_commit(); \ } \ else{ \ - container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \ - proxy \ - (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - priv_insert_front_aux_impl(1, proxy); \ + typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \ + type; \ + priv_insert_front_aux_impl \ + (1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ } \ } \ \ @@ -1240,10 +1240,10 @@ class deque : protected deque_base priv_push_back_simple_commit(); \ } \ else{ \ - container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \ - proxy \ - (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - priv_insert_back_aux_impl(1, proxy); \ + typedef container_detail::BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, n) \ + type; \ + priv_insert_back_aux_impl \ + (1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ } \ } \ \ @@ -1260,10 +1260,10 @@ class deque : protected deque_base return (this->end()-1); \ } \ else{ \ - container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \ - proxy \ - (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ - return this->priv_insert_aux_impl(p, 1, proxy); \ + typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \ + type; \ + return this->priv_insert_aux_impl \ + (p, 1, type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ } \ } \ //! @@ -1397,7 +1397,7 @@ class deque : protected deque_base #endif ) { - container_detail::insert_range_proxy proxy(this->alloc(), first); + container_detail::insert_range_proxy proxy(first); return priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy); } #endif @@ -1537,7 +1537,7 @@ class deque : protected deque_base this->members_.m_finish = this->members_.m_start; } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: void priv_erase_last_n(size_type n) @@ -1570,7 +1570,8 @@ class deque : protected deque_base } else { return priv_insert_aux_impl - (position, (size_type)1, container_detail::get_insert_value_proxy(this->alloc(), ::boost::forward(x))); + ( position, (size_type)1 + , container_detail::get_insert_value_proxy(::boost::forward(x))); } } @@ -1584,7 +1585,8 @@ class deque : protected deque_base } else{ priv_insert_aux_impl - (this->cbegin(), (size_type)1, container_detail::get_insert_value_proxy(this->alloc(), ::boost::forward(x))); + ( this->cbegin(), (size_type)1 + , container_detail::get_insert_value_proxy(::boost::forward(x))); } } @@ -1598,8 +1600,8 @@ class deque : protected deque_base } else{ priv_insert_aux_impl - (this->cend(), (size_type)1, container_detail::get_insert_value_proxy(this->alloc(), ::boost::forward(x))); - container_detail::insert_copy_proxy proxy(this->alloc(), x); + ( this->cend(), (size_type)1 + , container_detail::get_insert_value_proxy(::boost::forward(x))); } } @@ -1652,7 +1654,7 @@ class deque : protected deque_base } template - iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy interf) + iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy) { iterator pos(p.unconst()); const size_type pos_n = p - this->cbegin(); @@ -1667,7 +1669,7 @@ class deque : protected deque_base const iterator new_start = this->priv_reserve_elements_at_front(n); const iterator old_start = this->members_.m_start; if(!elemsbefore){ - interf.uninitialized_copy_n_and_update(new_start, n); + proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n); this->members_.m_start = new_start; } else{ @@ -1678,17 +1680,17 @@ class deque : protected deque_base (this->alloc(), this->members_.m_start, start_n, new_start); this->members_.m_start = new_start; boost::move(start_n, pos, old_start); - interf.copy_n_and_update(pos - n, n); + proxy.copy_n_and_update(this->alloc(), pos - n, n); } else { const size_type mid_count = n - elemsbefore; const iterator mid_start = old_start - mid_count; - interf.uninitialized_copy_n_and_update(mid_start, mid_count); + proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count); this->members_.m_start = mid_start; ::boost::container::uninitialized_move_alloc (this->alloc(), old_start, pos, new_start); this->members_.m_start = new_start; - interf.copy_n_and_update(old_start, elemsbefore); + proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore); } } } @@ -1697,7 +1699,7 @@ class deque : protected deque_base const iterator old_finish = this->members_.m_finish; const size_type elemsafter = length - elemsbefore; if(!elemsafter){ - interf.uninitialized_copy_n_and_update(old_finish, n); + proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n); this->members_.m_finish = new_finish; } else{ @@ -1708,15 +1710,15 @@ class deque : protected deque_base (this->alloc(), finish_n, old_finish, old_finish); this->members_.m_finish = new_finish; boost::move_backward(pos, finish_n, old_finish); - interf.copy_n_and_update(pos, n); + proxy.copy_n_and_update(this->alloc(), pos, n); } else { const size_type raw_gap = n - elemsafter; ::boost::container::uninitialized_move_alloc (this->alloc(), pos, old_finish, old_finish + raw_gap); BOOST_TRY{ - interf.copy_n_and_update(pos, elemsafter); - interf.uninitialized_copy_n_and_update(old_finish, raw_gap); + proxy.copy_n_and_update(this->alloc(), pos, elemsafter); + proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap); } BOOST_CATCH(...){ this->priv_destroy_range(old_finish, old_finish + elemsafter); @@ -1731,7 +1733,7 @@ class deque : protected deque_base } template - iterator priv_insert_back_aux_impl(size_type n, InsertProxy interf) + iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy) { if(!this->members_.m_map){ this->priv_initialize_map(0); @@ -1739,20 +1741,20 @@ class deque : protected deque_base iterator new_finish = this->priv_reserve_elements_at_back(n); iterator old_finish = this->members_.m_finish; - interf.uninitialized_copy_n_and_update(old_finish, n); + proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n); this->members_.m_finish = new_finish; return iterator(this->members_.m_finish - n); } template - iterator priv_insert_front_aux_impl(size_type n, InsertProxy interf) + iterator priv_insert_front_aux_impl(size_type n, InsertProxy proxy) { if(!this->members_.m_map){ this->priv_initialize_map(0); } iterator new_start = this->priv_reserve_elements_at_front(n); - interf.uninitialized_copy_n_and_update(new_start, n); + proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n); this->members_.m_start = new_start; return new_start; } @@ -1934,7 +1936,7 @@ class deque : protected deque_base this->members_.m_start.priv_set_node(new_nstart); this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1); } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; // Nonmember functions. @@ -1972,7 +1974,7 @@ inline void swap(deque& x, deque& y) }} -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { @@ -1985,7 +1987,7 @@ struct has_trivial_destructor_after_move > } -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #include diff --git a/include/boost/container/detail/adaptive_node_pool_impl.hpp b/include/boost/container/detail/adaptive_node_pool_impl.hpp index 4578ea8..13f9723 100644 --- a/include/boost/container/detail/adaptive_node_pool_impl.hpp +++ b/include/boost/container/detail/adaptive_node_pool_impl.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,9 +15,10 @@ # pragma once #endif -#include "config_begin.hpp" -#include +#include #include + +#include #include #include #include diff --git a/include/boost/container/detail/advanced_insert_int.hpp b/include/boost/container/detail/advanced_insert_int.hpp index e42bcb3..a3bbc23 100644 --- a/include/boost/container/detail/advanced_insert_int.hpp +++ b/include/boost/container/detail/advanced_insert_int.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,8 +15,373 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include + +#include +#include +#include +#include +#include //std::iterator_traits +#include +#include + +namespace boost { namespace container { namespace container_detail { + +template +struct move_insert_range_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + explicit move_insert_range_proxy(FwdIt first) + : first_(first) + {} + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) + { + this->first_ = ::boost::container::uninitialized_move_alloc_n_source + (a, this->first_, n, p); + } + + void copy_n_and_update(A &, Iterator p, size_type n) + { + this->first_ = ::boost::container::move_n_source(this->first_, n, p); + } + + FwdIt first_; +}; + + +template +struct insert_range_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + explicit insert_range_proxy(FwdIt first) + : first_(first) + {} + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) + { + this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p); + } + + void copy_n_and_update(A &, Iterator p, size_type n) + { + this->first_ = ::boost::container::copy_n_source(this->first_, n, p); + } + + FwdIt first_; +}; + + +template +struct insert_n_copies_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + explicit insert_n_copies_proxy(const value_type &v) + : v_(v) + {} + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + { boost::container::uninitialized_fill_alloc_n(a, v_, n, p); } + + void copy_n_and_update(A &, Iterator p, size_type n) const + { std::fill_n(p, n, v_); } + + const value_type &v_; +}; + +template +struct insert_value_initialized_n_proxy +{ + typedef ::boost::container::allocator_traits alloc_traits; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + { boost::container::uninitialized_value_init_alloc_n(a, n, p); } + + void copy_n_and_update(A &, Iterator, size_type) const + { BOOST_ASSERT(false); } +}; + +template +struct insert_default_initialized_n_proxy +{ + typedef ::boost::container::allocator_traits alloc_traits; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + { boost::container::uninitialized_default_init_alloc_n(a, n, p); } + + void copy_n_and_update(A &, Iterator, size_type) const + { BOOST_ASSERT(false); } +}; + +template +struct insert_copy_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + + explicit insert_copy_proxy(const value_type &v) + : v_(v) + {} + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, container_detail::to_raw_pointer(&*p), v_); + } + + void copy_n_and_update(A &, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + *p =v_; + } + + const value_type &v_; +}; + + +template +struct insert_move_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + + explicit insert_move_proxy(value_type &v) + : v_(v) + {} + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a + , container_detail::to_raw_pointer(&*p) + , ::boost::move(v_) + ); + } + + void copy_n_and_update(A &, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + *p = ::boost::move(v_); + } + + value_type &v_; +}; + +template +insert_move_proxy get_insert_value_proxy(BOOST_RV_REF(typename std::iterator_traits::value_type) v) +{ + return insert_move_proxy(v); +} + +template +insert_copy_proxy get_insert_value_proxy(const typename std::iterator_traits::value_type &v) +{ + return insert_copy_proxy(v); +} + +}}} //namespace boost { namespace container { namespace container_detail { + +#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + +#include +#include +#include +//#include //For debugging purposes + +namespace boost { +namespace container { +namespace container_detail { + +template +struct insert_non_movable_emplace_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + + typedef typename build_number_seq::type index_tuple_t; + + explicit insert_non_movable_emplace_proxy(Args&&... args) + : args_(args...) + {} + + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) + { this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); } + + private: + template + void priv_uninitialized_copy_some_and_update(A &a, const index_tuple&, Iterator p, size_type n) + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a + , container_detail::to_raw_pointer(&*p) + , ::boost::forward(get(this->args_))... + ); + } + + protected: + tuple args_; +}; + +template +struct insert_emplace_proxy + : public insert_non_movable_emplace_proxy +{ + typedef insert_non_movable_emplace_proxy base_t; + typedef boost::container::allocator_traits alloc_traits; + typedef typename base_t::value_type value_type; + typedef typename base_t::size_type size_type; + typedef typename base_t::index_tuple_t index_tuple_t; + + explicit insert_emplace_proxy(Args&&... args) + : base_t(::boost::forward(args)...) + {} + + void copy_n_and_update(A &a, Iterator p, size_type n) + { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); } + + private: + + template + void priv_copy_some_and_update(A &a, const index_tuple&, Iterator p, size_type n) + { + BOOST_ASSERT(n ==1); (void)n; + aligned_storage::value> v; + value_type *vp = static_cast(static_cast(&v)); + alloc_traits::construct(a, vp, + ::boost::forward(get(this->args_))...); + BOOST_TRY{ + *p = ::boost::move(*vp); + } + BOOST_CATCH(...){ + alloc_traits::destroy(a, vp); + BOOST_RETHROW + } + BOOST_CATCH_END + alloc_traits::destroy(a, vp); + } +}; + +}}} //namespace boost { namespace container { namespace container_detail { + +#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + +#include +#include + +namespace boost { +namespace container { +namespace container_detail { + +#define BOOST_PP_LOCAL_MACRO(N) \ +template \ +struct BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ +{ \ + typedef boost::container::allocator_traits alloc_traits; \ + typedef typename alloc_traits::size_type size_type; \ + typedef typename alloc_traits::value_type value_type; \ + \ + explicit BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ + ( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ + BOOST_PP_EXPR_IF(N, :) BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_INIT, _) \ + {} \ + \ + void uninitialized_copy_n_and_update(A &a, Iterator p, size_type n) \ + { \ + BOOST_ASSERT(n == 1); (void)n; \ + alloc_traits::construct \ + ( a \ + , container_detail::to_raw_pointer(&*p) \ + BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) \ + ); \ + } \ + \ + void copy_n_and_update(A &, Iterator, size_type) \ + { BOOST_ASSERT(false); } \ + \ + protected: \ + BOOST_PP_REPEAT(N, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \ +}; \ + \ +template \ +struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) \ + : BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ + < A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(N, P) > \ +{ \ + typedef BOOST_PP_CAT(insert_non_movable_emplace_proxy_arg, N) \ + base_t; \ + typedef typename base_t::value_type value_type; \ + typedef typename base_t::size_type size_type; \ + typedef boost::container::allocator_traits alloc_traits; \ + \ + explicit BOOST_PP_CAT(insert_emplace_proxy_arg, N) \ + ( BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \ + : base_t(BOOST_PP_ENUM(N, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ) \ + {} \ + \ + void copy_n_and_update(A &a, Iterator p, size_type n) \ + { \ + BOOST_ASSERT(n == 1); (void)n; \ + aligned_storage::value> v; \ + value_type *vp = static_cast(static_cast(&v)); \ + alloc_traits::construct(a, vp \ + BOOST_PP_ENUM_TRAILING(N, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)); \ + BOOST_TRY{ \ + *p = ::boost::move(*vp); \ + } \ + BOOST_CATCH(...){ \ + alloc_traits::destroy(a, vp); \ + BOOST_RETHROW \ + } \ + BOOST_CATCH_END \ + alloc_traits::destroy(a, vp); \ + } \ +}; \ +//! +#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) +#include BOOST_PP_LOCAL_ITERATE() + +}}} //namespace boost { namespace container { namespace container_detail { + +#endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING + +#include + +#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP +/* +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP +#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + #include #include #include @@ -391,3 +756,4 @@ struct BOOST_PP_CAT(insert_emplace_proxy_arg, N) #include #endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP +*/ \ No newline at end of file diff --git a/include/boost/container/detail/algorithms.hpp b/include/boost/container/detail/algorithms.hpp index 7a4a868..9358995 100644 --- a/include/boost/container/detail/algorithms.hpp +++ b/include/boost/container/detail/algorithms.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. +// (C) Copyright Ion Gaztanaga 2005-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,7 +17,7 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include #include diff --git a/include/boost/container/detail/allocation_type.hpp b/include/boost/container/detail/allocation_type.hpp index 59ae922..6aa04ac 100644 --- a/include/boost/container/detail/allocation_type.hpp +++ b/include/boost/container/detail/allocation_type.hpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,13 +15,13 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include namespace boost { namespace container { -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED enum allocation_type_v { // constants for allocation commands @@ -37,7 +37,7 @@ enum allocation_type_v }; typedef int allocation_type; -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED static const allocation_type allocate_new = (allocation_type)allocate_new_v; static const allocation_type expand_fwd = (allocation_type)expand_fwd_v; static const allocation_type expand_bwd = (allocation_type)expand_bwd_v; diff --git a/include/boost/container/detail/allocator_version_traits.hpp b/include/boost/container/detail/allocator_version_traits.hpp index 6df79da..d4567da 100644 --- a/include/boost/container/detail/allocator_version_traits.hpp +++ b/include/boost/container/detail/allocator_version_traits.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -17,6 +17,7 @@ #include #include + #include //allocator_traits #include #include //multiallocation_chain diff --git a/include/boost/container/detail/config_begin.hpp b/include/boost/container/detail/config_begin.hpp index 664f092..6c54bef 100644 --- a/include/boost/container/detail/config_begin.hpp +++ b/include/boost/container/detail/config_begin.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -18,6 +18,10 @@ #define BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE #endif + #ifndef _SCL_SECURE_NO_WARNINGS + #define BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS + #define _SCL_SECURE_NO_WARNINGS + #endif #pragma warning (push) #pragma warning (disable : 4702) // unreachable code #pragma warning (disable : 4706) // assignment within conditional expression diff --git a/include/boost/container/detail/config_end.hpp b/include/boost/container/detail/config_end.hpp index 3451371..7217019 100644 --- a/include/boost/container/detail/config_end.hpp +++ b/include/boost/container/detail/config_end.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -13,5 +13,9 @@ #undef BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE #undef _CRT_SECURE_NO_DEPRECATE #endif + #ifdef BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS + #undef BOOST_CONTAINER_DETAIL_SCL_SECURE_NO_WARNINGS + #undef _SCL_SECURE_NO_WARNINGS + #endif #endif diff --git a/include/boost/container/detail/destroyers.hpp b/include/boost/container/detail/destroyers.hpp index fef8aa0..329a6ef 100644 --- a/include/boost/container/detail/destroyers.hpp +++ b/include/boost/container/detail/destroyers.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. +// (C) Copyright Ion Gaztanaga 2005-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,8 +17,9 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include + #include #include #include @@ -231,6 +232,9 @@ struct null_scoped_destructor_n void increment_size_backwards(size_type) {} + void shrink_forward(size_type) + {} + void release() {} }; diff --git a/include/boost/container/detail/flat_tree.hpp b/include/boost/container/detail/flat_tree.hpp index f214d19..160f6ef 100644 --- a/include/boost/container/detail/flat_tree.hpp +++ b/include/boost/container/detail/flat_tree.hpp @@ -1,6 +1,6 @@ //////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,7 +15,7 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include #include diff --git a/include/boost/container/detail/function_detector.hpp b/include/boost/container/detail/function_detector.hpp index 5a5f6fd..1fe6731 100644 --- a/include/boost/container/detail/function_detector.hpp +++ b/include/boost/container/detail/function_detector.hpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2009-2012. +// (C) Copyright Ion Gaztanaga 2009-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at diff --git a/include/boost/container/detail/iterators.hpp b/include/boost/container/detail/iterators.hpp index 5766a7c..be3c157 100644 --- a/include/boost/container/detail/iterators.hpp +++ b/include/boost/container/detail/iterators.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. +// (C) Copyright Ion Gaztanaga 2005-2013. // (C) Copyright Gennaro Prota 2003 - 2004. // // Distributed under the Boost Software License, Version 1.0. @@ -18,7 +18,7 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include #include #include diff --git a/include/boost/container/detail/math_functions.hpp b/include/boost/container/detail/math_functions.hpp index fe8386b..3eff6b1 100644 --- a/include/boost/container/detail/math_functions.hpp +++ b/include/boost/container/detail/math_functions.hpp @@ -1,7 +1,7 @@ ////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Stephen Cleary 2000. -// (C) Copyright Ion Gaztanaga 2007-2012. +// (C) Copyright Ion Gaztanaga 2007-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -16,7 +16,9 @@ #ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP #define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP -#include "config_begin.hpp" +#include +#include + #include #include diff --git a/include/boost/container/detail/mpl.hpp b/include/boost/container/detail/mpl.hpp index 08f3eae..e25d623 100644 --- a/include/boost/container/detail/mpl.hpp +++ b/include/boost/container/detail/mpl.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. +// (C) Copyright Ion Gaztanaga 2005-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,6 +17,9 @@ # pragma once #endif +#include +#include + #include namespace boost { @@ -156,5 +159,7 @@ template <> struct unvoid { struct type { }; }; } //namespace container { } //namespace boost { +#include + #endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP diff --git a/include/boost/container/detail/multiallocation_chain.hpp b/include/boost/container/detail/multiallocation_chain.hpp index bc9945a..38c331c 100644 --- a/include/boost/container/detail/multiallocation_chain.hpp +++ b/include/boost/container/detail/multiallocation_chain.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,7 +11,9 @@ #ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP #define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP -#include "config_begin.hpp" +#include +#include + #include #include #include diff --git a/include/boost/container/detail/node_alloc_holder.hpp b/include/boost/container/detail/node_alloc_holder.hpp index d94c2e9..4f20962 100644 --- a/include/boost/container/detail/node_alloc_holder.hpp +++ b/include/boost/container/detail/node_alloc_holder.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,7 +15,7 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include #include diff --git a/include/boost/container/detail/node_pool_impl.hpp b/include/boost/container/detail/node_pool_impl.hpp index 0c5c744..f10e9bc 100644 --- a/include/boost/container/detail/node_pool_impl.hpp +++ b/include/boost/container/detail/node_pool_impl.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,9 +15,10 @@ # pragma once #endif -#include "config_begin.hpp" -#include +#include #include + +#include #include #include #include diff --git a/include/boost/container/detail/pair.hpp b/include/boost/container/detail/pair.hpp index bfe7978..0d7e0a9 100644 --- a/include/boost/container/detail/pair.hpp +++ b/include/boost/container/detail/pair.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. +// (C) Copyright Ion Gaztanaga 2005-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,7 +17,7 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include #include diff --git a/include/boost/container/detail/pool_common.hpp b/include/boost/container/detail/pool_common.hpp index 6ab2d43..53a7427 100644 --- a/include/boost/container/detail/pool_common.hpp +++ b/include/boost/container/detail/pool_common.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -8,14 +8,16 @@ // ////////////////////////////////////////////////////////////////////////////// -#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP -#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP +#ifndef BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP +#define BOOST_CONTAINER_DETAIL_POOL_COMMON_HPP #if defined(_MSC_VER) # pragma once #endif -#include "config_begin.hpp" +#include +#include + #include #include diff --git a/include/boost/container/detail/preprocessor.hpp b/include/boost/container/detail/preprocessor.hpp index 41d1f55..7e4f5eb 100644 --- a/include/boost/container/detail/preprocessor.hpp +++ b/include/boost/container/detail/preprocessor.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/include/boost/container/detail/transform_iterator.hpp b/include/boost/container/detail/transform_iterator.hpp index c40ecc6..f10f3fe 100644 --- a/include/boost/container/detail/transform_iterator.hpp +++ b/include/boost/container/detail/transform_iterator.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. +// (C) Copyright Ion Gaztanaga 2005-2013. // (C) Copyright Gennaro Prota 2003 - 2004. // // Distributed under the Boost Software License, Version 1.0. @@ -18,8 +18,9 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include + #include #include diff --git a/include/boost/container/detail/tree.hpp b/include/boost/container/detail/tree.hpp index 7400a1a..bae87d0 100644 --- a/include/boost/container/detail/tree.hpp +++ b/include/boost/container/detail/tree.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_TREE_HPP #define BOOST_CONTAINER_TREE_HPP -#include "config_begin.hpp" +#include #include #include diff --git a/include/boost/container/detail/type_traits.hpp b/include/boost/container/detail/type_traits.hpp index 8dbd182..6f20bd5 100644 --- a/include/boost/container/detail/type_traits.hpp +++ b/include/boost/container/detail/type_traits.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // (C) Copyright John Maddock 2000. -// (C) Copyright Ion Gaztanaga 2005-2012. +// (C) Copyright Ion Gaztanaga 2005-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -19,7 +19,8 @@ # pragma once #endif -#include "config_begin.hpp" +#include +#include #include diff --git a/include/boost/container/detail/utilities.hpp b/include/boost/container/detail/utilities.hpp index 8aa020a..9298988 100644 --- a/include/boost/container/detail/utilities.hpp +++ b/include/boost/container/detail/utilities.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,8 +11,9 @@ #ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP #define BOOST_CONTAINER_DETAIL_UTILITIES_HPP -#include "config_begin.hpp" -#include "workaround.hpp" +#include +#include + #include #include //for ::memcpy #include @@ -110,18 +111,37 @@ template const T &min_value(const T &a, const T &b) { return a < b ? a : b; } -template -SizeType - get_next_capacity(const SizeType max_size - ,const SizeType capacity - ,const SizeType n) +enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent }; + +template +struct next_capacity_calculator; + +template +struct next_capacity_calculator { - const SizeType remaining = max_size - capacity; - if ( remaining < n ) - boost::container::throw_length_error("get_next_capacity, allocator's max_size reached"); - const SizeType additional = max_value(n, capacity); - return ( remaining < additional ) ? max_size : ( capacity + additional ); - #if 0 //Alternative for 50% grow + static SizeType get(const SizeType max_size + ,const SizeType capacity + ,const SizeType n) + { + const SizeType remaining = max_size - capacity; + if ( remaining < n ) + boost::container::throw_length_error("get_next_capacity, allocator's max_size reached"); + const SizeType additional = max_value(n, capacity); + return ( remaining < additional ) ? max_size : ( capacity + additional ); + } +}; + + +template +struct next_capacity_calculator +{ + static SizeType get(const SizeType max_size + ,const SizeType capacity + ,const SizeType n) + { + const SizeType remaining = max_size - capacity; + if ( remaining < n ) + boost::container::throw_length_error("get_next_capacity, allocator's max_size reached"); const SizeType m3 = max_size/3; if (capacity < m3) @@ -130,8 +150,8 @@ SizeType if (capacity < m3*2) return capacity + max_value((capacity+1)/2, n); return max_size; - #endif -} + } +}; template inline T* to_raw_pointer(T* p) diff --git a/include/boost/container/detail/value_init.hpp b/include/boost/container/detail/value_init.hpp index afe5b15..68f9678 100644 --- a/include/boost/container/detail/value_init.hpp +++ b/include/boost/container/detail/value_init.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. +// (C) Copyright Ion Gaztanaga 2005-2013. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,7 +17,7 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include namespace boost { diff --git a/include/boost/container/detail/variadic_templates_tools.hpp b/include/boost/container/detail/variadic_templates_tools.hpp index cce7fed..b07fe30 100644 --- a/include/boost/container/detail/variadic_templates_tools.hpp +++ b/include/boost/container/detail/variadic_templates_tools.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,8 +15,9 @@ # pragma once #endif -#include "config_begin.hpp" +#include #include + #include #include //std::size_t diff --git a/include/boost/container/detail/version_type.hpp b/include/boost/container/detail/version_type.hpp index e47ba26..66cafc9 100644 --- a/include/boost/container/detail/version_type.hpp +++ b/include/boost/container/detail/version_type.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -16,7 +16,8 @@ #ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP #define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP -#include "config_begin.hpp" +#include +#include #include #include @@ -87,6 +88,6 @@ struct version } //namespace container { } //namespace boost{ -#include "config_end.hpp" +#include #endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP diff --git a/include/boost/container/detail/workaround.hpp b/include/boost/container/detail/workaround.hpp index 49fe284..f919aa5 100644 --- a/include/boost/container/detail/workaround.hpp +++ b/include/boost/container/detail/workaround.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/include/boost/container/flat_map.hpp b/include/boost/container/flat_map.hpp index 8778de5..3da00b2 100644 --- a/include/boost/container/flat_map.hpp +++ b/include/boost/container/flat_map.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -34,7 +34,7 @@ namespace boost { namespace container { -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED // Forward declarations of operators == and <, needed for friend declarations. template class flat_map; @@ -63,7 +63,7 @@ static D force_copy(S s) } //namespace container_detail{ -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! A flat_map is a kind of associative container that supports unique keys (contains at //! most one of each key value) and provides for fast retrieval of values of another @@ -95,7 +95,7 @@ template #endif class flat_map { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(flat_map) //This is the tree that we should store if pair was movable @@ -129,7 +129,7 @@ class flat_map ::pointer>::reverse_iterator reverse_iterator_impl; typedef typename container_detail::get_flat_tree_iterators ::pointer>::const_reverse_iterator const_reverse_iterator_impl; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -842,7 +842,7 @@ class flat_map std::pair equal_range(const key_type& x) const { return container_detail::force_copy >(m_flat_tree.equal_range(x)); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template friend bool operator== (const flat_map&, const flat_map&); @@ -872,7 +872,7 @@ class flat_map } return (*i).second; } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -910,7 +910,7 @@ inline void swap(flat_map& x, flat_map& y) { x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED } //namespace container { @@ -935,7 +935,7 @@ inline bool operator==(const flat_multimap& x, template inline bool operator<(const flat_multimap& x, const flat_multimap& y); -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! A flat_multimap is a kind of associative container that supports equivalent keys //! (possibly containing multiple copies of the same key value) and provides for @@ -967,7 +967,7 @@ template #endif class flat_multimap { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(flat_multimap) typedef container_detail::flat_tree::pointer>::reverse_iterator reverse_iterator_impl; typedef typename container_detail::get_flat_tree_iterators ::pointer>::const_reverse_iterator const_reverse_iterator_impl; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -1637,7 +1637,7 @@ class flat_multimap std::pair equal_range(const key_type& x) const { return container_detail::force_copy >(m_flat_tree.equal_range(x)); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template friend bool operator== (const flat_multimap& x, const flat_multimap& y); @@ -1645,7 +1645,7 @@ class flat_multimap template friend bool operator< (const flat_multimap& x, const flat_multimap& y); - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -1684,7 +1684,7 @@ inline void swap(flat_multimap& x, flat_multimap diff --git a/include/boost/container/flat_set.hpp b/include/boost/container/flat_set.hpp index eda8fbd..34dd170 100644 --- a/include/boost/container/flat_set.hpp +++ b/include/boost/container/flat_set.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -31,7 +31,7 @@ namespace boost { namespace container { -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED // Forward declarations of operators < and ==, needed for friend declaration. #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -48,7 +48,7 @@ inline bool operator==(const flat_set& x, template inline bool operator<(const flat_set& x, const flat_set& y); -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! flat_set is a Sorted Associative Container that stores objects of type Key. //! It is also a Unique Associative Container, meaning that no two elements are the same. @@ -68,12 +68,12 @@ template #endif class flat_set { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(flat_set) typedef container_detail::flat_tree, Compare, Allocator> tree_t; tree_t m_flat_tree; // flat tree representing flat_set - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -678,7 +678,7 @@ class flat_set std::pair equal_range(const key_type& x) { return m_flat_tree.equal_range(x); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template friend bool operator== (const flat_set&, const flat_set&); @@ -693,7 +693,7 @@ class flat_set template iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) { return m_flat_tree.insert_unique(p, ::boost::forward(x)); } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -730,7 +730,7 @@ template inline void swap(flat_set& x, flat_set& y) { x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED } //namespace container { @@ -760,7 +760,7 @@ inline bool operator==(const flat_multiset& x, template inline bool operator<(const flat_multiset& x, const flat_multiset& y); -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! flat_multiset is a Sorted Associative Container that stores objects of type Key. //! @@ -781,12 +781,12 @@ template #endif class flat_multiset { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(flat_multiset) typedef container_detail::flat_tree, Compare, Allocator> tree_t; tree_t m_flat_tree; // flat tree representing flat_multiset - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -1353,7 +1353,7 @@ class flat_multiset std::pair equal_range(const key_type& x) { return m_flat_tree.equal_range(x); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template friend bool operator== (const flat_multiset&, const flat_multiset&); @@ -1368,7 +1368,7 @@ class flat_multiset template iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) { return m_flat_tree.insert_equal(p, ::boost::forward(x)); } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -1405,7 +1405,7 @@ template inline void swap(flat_multiset& x, flat_multiset& y) { x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED } //namespace container { @@ -1419,7 +1419,7 @@ struct has_trivial_destructor_after_move @@ -99,7 +99,7 @@ struct intrusive_list_type }; } //namespace container_detail { -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! A list is a doubly linked list. That is, it is a Sequence that supports both //! forward and backward traversal, and (amortized) constant time insertion and @@ -120,7 +120,7 @@ class list : protected container_detail::node_alloc_holder ::type> { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef typename container_detail::intrusive_list_type::type Icont; typedef container_detail::node_alloc_holder AllocHolder; @@ -167,7 +167,7 @@ class list typedef container_detail::iterator iterator_impl; typedef container_detail::iterator const_iterator_impl; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -1216,7 +1216,7 @@ class list void reverse() BOOST_CONTAINER_NOEXCEPT { this->icont().reverse(); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: bool priv_try_shrink(size_type new_size) @@ -1303,7 +1303,7 @@ class list bool operator()(const value_type &a, const value_type &b) const { return a == b; } }; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; @@ -1362,7 +1362,7 @@ inline void swap(list& x, list& y) x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED } //namespace container { @@ -1375,7 +1375,7 @@ struct has_trivial_destructor_after_move > namespace container { -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }} diff --git a/include/boost/container/map.hpp b/include/boost/container/map.hpp index f4776e8..da5f89a 100644 --- a/include/boost/container/map.hpp +++ b/include/boost/container/map.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -39,7 +39,7 @@ namespace boost { namespace container { -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED // Forward declarations of operators == and <, needed for friend declarations. template inline bool operator==(const map& x, @@ -48,7 +48,7 @@ inline bool operator==(const map& x, template inline bool operator<(const map& x, const map& y); -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! A map is a kind of associative container that supports unique keys (contains at //! most one of each key value) and provides for fast retrieval of values of another @@ -69,7 +69,7 @@ template #endif class map { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(map) @@ -81,7 +81,7 @@ class map < Key, value_type_impl, Compare, container_detail::select1st > value_compare_impl; tree_t m_tree; // red-black tree representing map - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -755,7 +755,7 @@ class map std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template friend bool operator== (const map&, const map&); @@ -790,7 +790,7 @@ class map return (*i).second; } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -827,7 +827,7 @@ template inline void swap(map& x, map& y) { x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED // Forward declaration of operators < and ==, needed for friend declaration. @@ -851,7 +851,7 @@ struct has_trivial_destructor_after_move #endif class multimap { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(multimap) @@ -885,7 +885,7 @@ class multimap < Key, value_type_impl, Compare, container_detail::select1st > value_compare_impl; tree_t m_tree; // red-black tree representing map - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -1463,7 +1463,7 @@ class multimap std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template friend bool operator== (const multimap& x, const multimap& y); @@ -1471,7 +1471,7 @@ class multimap template friend bool operator< (const multimap& x, const multimap& y); - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -1508,7 +1508,7 @@ template inline void swap(multimap& x, multimap& y) { x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED } //namespace container { @@ -1522,7 +1522,7 @@ struct has_trivial_destructor_after_move //! template > //! class Z { //! public: @@ -64,7 +64,7 @@ namespace boost { namespace container { //! template > //! struct constructible_with_allocator_suffix > //! : ::boost::true_type { }; -//! -- end example] +//! //! //! Note: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)" //! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as @@ -90,7 +90,7 @@ struct constructible_with_allocator_suffix //! called with these initial arguments, and if T is used in a context where a container must call such //! a constructor, then the program is ill-formed. //! -//! [Example: +//! //! template > //! class Y { //! public: @@ -115,7 +115,7 @@ struct constructible_with_allocator_suffix //! struct constructible_with_allocator_prefix > //! : ::boost::true_type { }; //! -//! -- end example] +//! //! //! Note: This trait is a workaround inspired by "N2554: The Scoped Allocator Model (Rev 2)" //! (Pablo Halpern, 2008-02-29) to backport the scoped allocator model to C++03, as @@ -130,7 +130,7 @@ struct constructible_with_allocator_prefix : ::boost::false_type {}; -///@cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace container_detail { @@ -159,7 +159,7 @@ struct uses_allocator_imp } //namespace container_detail { -///@endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! Remark: Automatically detects if T has a nested allocator_type that is convertible from //! Alloc. Meets the BinaryTypeTrait requirements ([meta.rqmts] 20.4.1). A program may @@ -173,7 +173,7 @@ struct uses_allocator : boost::integral_constant::value> {}; -///@cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace container_detail { @@ -675,16 +675,16 @@ class scoped_allocator_adaptor_base friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) { l.swap(r); } - inner_allocator_type& inner_allocator() + inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT { return m_inner; } - inner_allocator_type const& inner_allocator() const + inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT { return m_inner; } - outer_allocator_type & outer_allocator() + outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT { return static_cast(*this); } - const outer_allocator_type &outer_allocator() const + const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT { return static_cast(*this); } scoped_allocator_type select_on_container_copy_construction() const @@ -1008,7 +1008,7 @@ class scoped_allocator_adaptor_base } //namespace container_detail { -///@endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //Scoped allocator #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) @@ -1038,14 +1038,14 @@ class scoped_allocator_adaptor_base //! scoped_allocator_adaptor is derived from the outer allocator type so it can be //! substituted for the outer allocator type in most expressions. -end note] //! - //! In the construct member functions, `OUTERMOST(x)` is x if x does not have - //! an `outer_allocator()` member function and - //! `OUTERMOST(x.outer_allocator())` otherwise; `OUTERMOST_ALLOC_TRAITS(x)` is - //! `allocator_traits`. + //! In the construct member functions, OUTERMOST(x) is x if x does not have + //! an outer_allocator() member function and + //! OUTERMOST(x.outer_allocator()) otherwise; OUTERMOST_ALLOC_TRAITS(x) is + //! allocator_traits. //! - //! [Note: `OUTERMOST(x)` and - //! `OUTERMOST_ALLOC_TRAITS(x)` are recursive operations. It is incumbent upon - //! the definition of `outer_allocator()` to ensure that the recursion terminates. + //! [Note: OUTERMOST(x) and + //! OUTERMOST_ALLOC_TRAITS(x) are recursive operations. It is incumbent upon + //! the definition of outer_allocator() to ensure that the recursion terminates. //! It will terminate for all instantiations of scoped_allocator_adaptor. -end note] template class scoped_allocator_adaptor @@ -1076,7 +1076,7 @@ class scoped_allocator_adaptor BOOST_COPYABLE_AND_MOVABLE(scoped_allocator_adaptor) public: - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef container_detail::scoped_allocator_adaptor_base base_type; typedef typename base_type::internal_type_t internal_type_t; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef OuterAlloc outer_allocator_type; //! Type: For exposition only //! typedef allocator_traits outer_traits_type; - //! Type: `scoped_allocator_adaptor` if `sizeof...(InnerAllocs)` is zero; otherwise, - //! `scoped_allocator_adaptor`. + //! Type: scoped_allocator_adaptor if sizeof...(InnerAllocs) is zero; otherwise, + //! scoped_allocator_adaptor. typedef typename base_type::inner_allocator_type inner_allocator_type; typedef allocator_traits inner_traits_type; typedef typename outer_traits_type::value_type value_type; @@ -1102,23 +1102,23 @@ class scoped_allocator_adaptor typedef typename outer_traits_type::const_pointer const_pointer; typedef typename outer_traits_type::void_pointer void_pointer; typedef typename outer_traits_type::const_void_pointer const_void_pointer; - //! Type: `true_type` if `allocator_traits::propagate_on_container_copy_assignment::value` is - //! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. + //! Type: true_type if allocator_traits::propagate_on_container_copy_assignment::value is + //! true for any Allocator in the set of OuterAlloc and InnerAllocs...; otherwise, false_type. typedef typename base_type:: propagate_on_container_copy_assignment propagate_on_container_copy_assignment; - //! Type: `true_type` if `allocator_traits::propagate_on_container_move_assignment::value` is - //! true for any `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. + //! Type: true_type if allocator_traits::propagate_on_container_move_assignment::value is + //! true for any Allocator in the set of OuterAlloc and InnerAllocs...; otherwise, false_type. typedef typename base_type:: propagate_on_container_move_assignment propagate_on_container_move_assignment; - //! Type: `true_type` if `allocator_traits::propagate_on_container_swap::value` is true for any - //! `Allocator` in the set of `OuterAlloc` and `InnerAllocs...`; otherwise, false_type. + //! Type: true_type if allocator_traits::propagate_on_container_swap::value is true for any + //! Allocator in the set of OuterAlloc and InnerAllocs...; otherwise, false_type. typedef typename base_type:: propagate_on_container_swap propagate_on_container_swap; //! Type: Rebinds scoped allocator to - //! `typedef scoped_allocator_adaptor + //! typedef scoped_allocator_adaptor //! < typename outer_traits_type::template portable_rebind_alloc::type - //! , InnerAllocs... >` + //! , InnerAllocs... > template struct rebind { @@ -1224,55 +1224,55 @@ class scoped_allocator_adaptor friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r); //! Returns: - //! `static_cast(*this)`. - outer_allocator_type & outer_allocator(); + //! static_cast(*this). + outer_allocator_type & outer_allocator() BOOST_CONTAINER_NOEXCEPT; //! Returns: - //! `static_cast(*this)`. - const outer_allocator_type &outer_allocator() const; + //! static_cast(*this). + const outer_allocator_type &outer_allocator() const BOOST_CONTAINER_NOEXCEPT; //! Returns: - //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner. - inner_allocator_type& inner_allocator(); + //! *this if sizeof...(InnerAllocs) is zero; otherwise, inner. + inner_allocator_type& inner_allocator() BOOST_CONTAINER_NOEXCEPT; //! Returns: - //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner. - inner_allocator_type const& inner_allocator() const; + //! *this if sizeof...(InnerAllocs) is zero; otherwise, inner. + inner_allocator_type const& inner_allocator() const BOOST_CONTAINER_NOEXCEPT; #endif //BOOST_CONTAINER_DOXYGEN_INVOKED //! Returns: - //! `allocator_traits::max_size(outer_allocator())`. - size_type max_size() const + //! allocator_traits::max_size(outer_allocator()). + size_type max_size() const BOOST_CONTAINER_NOEXCEPT { return outer_traits_type::max_size(this->outer_allocator()); } //! Effects: - //! calls `OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p)`. + //! calls OUTERMOST_ALLOC_TRAITS(*this)::destroy(OUTERMOST(*this), p). template - void destroy(T* p) + void destroy(T* p) BOOST_CONTAINER_NOEXCEPT { allocator_traits::type> ::destroy(get_outermost_allocator(this->outer_allocator()), p); } //! Returns: - //! `allocator_traits::allocate(outer_allocator(), n)`. + //! allocator_traits::allocate(outer_allocator(), n). pointer allocate(size_type n) { return outer_traits_type::allocate(this->outer_allocator(), n); } //! Returns: - //! `allocator_traits::allocate(outer_allocator(), n, hint)`. + //! allocator_traits::allocate(outer_allocator(), n, hint). pointer allocate(size_type n, const_void_pointer hint) { return outer_traits_type::allocate(this->outer_allocator(), n, hint); } //! Effects: - //! `allocator_traits::deallocate(outer_allocator(), p, n)`. + //! allocator_traits::deallocate(outer_allocator(), p, n). void deallocate(pointer p, size_type n) { outer_traits_type::deallocate(this->outer_allocator(), p, n); @@ -1281,45 +1281,45 @@ class scoped_allocator_adaptor #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED //! Returns: Allocator new scoped_allocator_adaptor object where each allocator //! A in the adaptor is initialized from the result of calling - //! `allocator_traits::select_on_container_copy_construction()` on + //! allocator_traits::select_on_container_copy_construction() on //! the corresponding allocator in *this. scoped_allocator_adaptor select_on_container_copy_construction() const; #endif //BOOST_CONTAINER_DOXYGEN_INVOKED - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED base_type &base() { return *this; } const base_type &base() const { return *this; } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) //! Effects: - //! 1) If `uses_allocator::value` is false calls - //! `OUTERMOST_ALLOC_TRAITS(*this)::construct - //! (OUTERMOST(*this), p, std::forward(args)...)`. + //! 1) If uses_allocator::value is false calls + //! OUTERMOST_ALLOC_TRAITS(*this)::construct + //! (OUTERMOST(*this), p, std::forward(args)...). //! - //! 2) Otherwise, if `uses_allocator::value` is true and - //! `is_constructible::value` is true, calls - //! `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg, - //! inner_allocator(), std::forward(args)...)`. + //! 2) Otherwise, if uses_allocator::value is true and + //! is_constructible::value is true, calls + //! OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, allocator_arg, + //! inner_allocator(), std::forward(args)...). //! - //! [Note: In compilers without advanced decltype SFINAE support, `is_constructible` can't + //! [Note: In compilers without advanced decltype SFINAE support, is_constructible can't //! be implemented so that condition will be replaced by //! constructible_with_allocator_prefix::value. -end note] //! //! 3) Otherwise, if uses_allocator::value is true and - //! `is_constructible::value` is true, calls - //! `OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, - //! std::forward(args)..., inner_allocator())`. + //! is_constructible::value is true, calls + //! OUTERMOST_ALLOC_TRAITS(*this)::construct(OUTERMOST(*this), p, + //! std::forward(args)..., inner_allocator()). //! - //! [Note: In compilers without advanced decltype SFINAE support, `is_constructible` can't be + //! [Note: In compilers without advanced decltype SFINAE support, is_constructible can't be //! implemented so that condition will be replaced by - //! `constructible_with_allocator_suffix::value`. -end note] + //! constructible_with_allocator_suffix::value. -end note] //! //! 4) Otherwise, the program is ill-formed. //! - //! [Note: An error will result if `uses_allocator` evaluates + //! [Note: An error will result if uses_allocator evaluates //! to true but the specific constructor does not take an allocator. This definition prevents a silent //! failure to pass an inner allocator to a contained element. -end note] template < typename T, class ...Args> @@ -1395,7 +1395,7 @@ class scoped_allocator_adaptor , BOOST_RV_REF_BEG container_detail::pair BOOST_RV_REF_END x) { this->construct_pair(p, x); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: template void construct_pair(Pair* p) @@ -1463,7 +1463,7 @@ class scoped_allocator_adaptor : base_type(internal_type_t(), ::boost::forward(outer), inner) {} - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template inline bool operator==(const set& x, @@ -44,7 +44,7 @@ inline bool operator==(const set& x, template inline bool operator<(const set& x, const set& y); -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! A set is a kind of associative container that supports unique keys (contains at //! most one of each key value) and provides for fast retrieval of the keys themselves. @@ -60,13 +60,13 @@ template #endif class set { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(set) typedef container_detail::rbtree, Compare, Allocator> tree_t; tree_t m_tree; // red-black tree representing set - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -600,7 +600,7 @@ class set std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template friend bool operator== (const set&, const set&); @@ -615,7 +615,7 @@ class set template iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) { return m_tree.insert_unique(p, ::boost::forward(x)); } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -652,7 +652,7 @@ template inline void swap(set& x, set& y) { x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED } //namespace container { @@ -675,7 +675,7 @@ inline bool operator==(const multiset& x, template inline bool operator<(const multiset& x, const multiset& y); -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! A multiset is a kind of associative container that supports equivalent keys //! (possibly contains multiple copies of the same key value) and provides for @@ -691,13 +691,13 @@ template #endif class multiset { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(multiset) typedef container_detail::rbtree, Compare, Allocator> tree_t; tree_t m_tree; // red-black tree representing multiset - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -1221,7 +1221,7 @@ class multiset std::pair equal_range(const key_type& x) const { return m_tree.equal_range(x); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template friend bool operator== (const multiset&, const multiset&); @@ -1237,7 +1237,7 @@ class multiset iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x) { return m_tree.insert_equal(p, ::boost::forward(x)); } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -1274,7 +1274,7 @@ template inline void swap(multiset& x, multiset& y) { x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED } //namespace container { @@ -1288,7 +1288,7 @@ struct has_trivial_destructor_after_move class slist; @@ -106,7 +106,7 @@ struct intrusive_slist_type } //namespace container_detail { -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! An slist is a singly linked list: a list where each element is linked to the next //! element, but not to the previous element. That is, it is a Sequence that @@ -149,7 +149,7 @@ class slist : protected container_detail::node_alloc_holder ::type> { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef typename container_detail::intrusive_slist_type::type Icont; typedef container_detail::node_alloc_holder AllocHolder; @@ -195,7 +195,7 @@ class slist BOOST_COPYABLE_AND_MOVABLE(slist) typedef container_detail::iterator iterator_impl; typedef container_detail::iterator const_iterator_impl; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -1423,7 +1423,7 @@ class slist void splice(const_iterator p, BOOST_RV_REF(slist) x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT { this->splice(p, static_cast(x), first, last); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: void priv_push_front (const T &x) @@ -1505,7 +1505,7 @@ class slist const value_type &m_ref; }; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -1561,7 +1561,7 @@ inline void swap(slist& x, slist& y) }} -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { @@ -1574,14 +1574,14 @@ struct has_trivial_destructor_after_move > namespace container { -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }} //namespace boost{ namespace container { // Specialization of insert_iterator so that insertions will be constant // time rather than linear time. -///@cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //Ummm, I don't like to define things in namespace std, but //there is no other way @@ -1620,7 +1620,7 @@ class insert_iterator > } //namespace std; -///@endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #include diff --git a/include/boost/container/stable_vector.hpp b/include/boost/container/stable_vector.hpp index 23b3d4b..87fc030 100644 --- a/include/boost/container/stable_vector.hpp +++ b/include/boost/container/stable_vector.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -47,18 +47,18 @@ #include #include //placement new -///@cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #include //#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING -///@endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { namespace container { -///@cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace stable_vector_detail{ @@ -393,7 +393,7 @@ struct index_traits #endif //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector //! drop-in replacement implemented as a node container, offering iterator and reference @@ -433,7 +433,7 @@ template #endif class stable_vector { - ///@cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef allocator_traits allocator_traits_type; typedef boost::intrusive:: pointer_traits @@ -504,7 +504,7 @@ class stable_vector typedef stable_vector_detail::iterator < typename allocator_traits::pointer , false> const_iterator_impl; - ///@endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -526,7 +526,7 @@ class stable_vector typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; - ///@cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(stable_vector) static const size_type ExtraPointers = index_traits_type::ExtraPointers; @@ -536,7 +536,7 @@ class stable_vector class push_back_rollback; friend class push_back_rollback; - ///@endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -1510,7 +1510,7 @@ class stable_vector void clear() BOOST_CONTAINER_NOEXCEPT { this->erase(this->cbegin(),this->cend()); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: @@ -1836,7 +1836,7 @@ class stable_vector const node_allocator_type &priv_node_alloc() const { return internal_data; } index_type index; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -1883,11 +1883,11 @@ void swap(stable_vector& x,stable_vector& y) x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #undef STABLE_VECTOR_CHECK_INVARIANT -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED /* diff --git a/include/boost/container/static_vector.hpp b/include/boost/container/static_vector.hpp index 6ca0f4f..19e27f5 100644 --- a/include/boost/container/static_vector.hpp +++ b/include/boost/container/static_vector.hpp @@ -21,6 +21,8 @@ namespace boost { namespace container { +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + namespace container_detail { template @@ -61,46 +63,46 @@ class static_storage_allocator } //namespace container_detail { -/** - * @defgroup static_vector_non_member static_vector non-member functions - */ +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED -/** - * @brief A variable-size array container with fixed capacity. - * - * static_vector is a sequence container like boost::container::vector with contiguous storage that can - * change in size, along with the static allocation, low overhead, and fixed capacity of boost::array. - * - * A static_vector is a sequence that supports random access to elements, constant time insertion and - * removal of elements at the end, and linear time insertion and removal of elements at the beginning or - * in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity - * because elements are stored within the object itself similarly to an array. However, objects are - * initialized as they are inserted into static_vector unlike C arrays or std::array which must construct - * all elements on instantiation. The behavior of static_vector enables the use of statically allocated - * elements in cases with complex object lifetime requirements that would otherwise not be trivially - * possible. - * - * @par Error Handling - * Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or - * calling throw_bad_alloc() if not enabled. - * - * std::out_of_range is thrown if out of bound access is performed in `at()` if exceptions are - * enabled, throw_out_of_range() if not enabled. - * - * @tparam Value The type of element that will be stored. - * @tparam Capacity The maximum number of elements static_vector can store, fixed at compile time. - */ +//! +//!@brief A variable-size array container with fixed capacity. +//! +//!static_vector is a sequence container like boost::container::vector with contiguous storage that can +//!change in size, along with the static allocation, low overhead, and fixed capacity of boost::array. +//! +//!A static_vector is a sequence that supports random access to elements, constant time insertion and +//!removal of elements at the end, and linear time insertion and removal of elements at the beginning or +//!in the middle. The number of elements in a static_vector may vary dynamically up to a fixed capacity +//!because elements are stored within the object itself similarly to an array. However, objects are +//!initialized as they are inserted into static_vector unlike C arrays or std::array which must construct +//!all elements on instantiation. The behavior of static_vector enables the use of statically allocated +//!elements in cases with complex object lifetime requirements that would otherwise not be trivially +//!possible. +//! +//!@par Error Handling +//! Insertion beyond the capacity result in throwing std::bad_alloc() if exceptions are enabled or +//! calling throw_bad_alloc() if not enabled. +//! +//! std::out_of_range is thrown if out of bound access is performed in at() if exceptions are +//! enabled, throw_out_of_range() if not enabled. +//! +//!@tparam Value The type of element that will be stored. +//!@tparam Capacity The maximum number of elements static_vector can store, fixed at compile time. template class static_vector : public vector > { - typedef vector > base_t; + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + typedef vector > base_t; - BOOST_COPYABLE_AND_MOVABLE(static_vector) + BOOST_COPYABLE_AND_MOVABLE(static_vector) template friend class static_vector; + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + public: //! @brief The type of elements stored in the container. typedef typename base_t::value_type value_type; diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index e006326..715f169 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -52,7 +52,7 @@ namespace boost { namespace container { -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace container_detail { // ------------------------------------------------------------ // Class basic_string_base. @@ -268,7 +268,12 @@ class basic_string_base } size_type next_capacity(size_type additional_objects) const - { return get_next_capacity(allocator_traits_type::max_size(this->alloc()), this->priv_storage(), additional_objects); } + { + return next_capacity_calculator + :: + get( allocator_traits_type::max_size(this->alloc()) + , this->priv_storage(), additional_objects ); + } void deallocate(pointer p, size_type n) { @@ -433,7 +438,7 @@ class basic_string_base } //namespace container_detail { -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! The basic_string class represents a Sequence of characters. It contains all the //! usual operations of a Sequence, and, additionally, it contains standard string @@ -471,7 +476,7 @@ template class basic_string : private container_detail::basic_string_base { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: typedef allocator_traits allocator_traits_type; BOOST_COPYABLE_AND_MOVABLE(basic_string) @@ -509,7 +514,7 @@ class basic_string std::bind1st(Eq_traits(), x)) == m_last; } }; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -533,14 +538,14 @@ class basic_string typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; static const size_type npos = size_type(-1); - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: typedef constant_iterator cvalue_iterator; typedef typename base_t::allocator_v1 allocator_v1; typedef typename base_t::allocator_v2 allocator_v2; typedef typename base_t::alloc_version alloc_version; typedef ::boost::intrusive::pointer_traits pointer_traits; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: // Constructor, destructor, assignment. ////////////////////////////////////////////// @@ -548,7 +553,7 @@ class basic_string // construct/copy/destroy // ////////////////////////////////////////////// - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED struct reserve_t {}; basic_string(reserve_t, size_type n, @@ -559,7 +564,7 @@ class basic_string , n + 1) { this->priv_terminate_string(); } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //! Effects: Default constructs a basic_string. //! @@ -668,6 +673,15 @@ class basic_string this->assign(n, c); } + //! Effects: Constructs a basic_string taking the allocator as parameter, + //! and is initialized by n default-initialized characters. + basic_string(size_type n, default_init_t, const allocator_type& a = allocator_type()) + : base_t(a, n + 1) + { + this->priv_size(n); + this->priv_terminate_string(); + } + //! Effects: Constructs a basic_string taking the allocator as parameter, //! and a range of iterators. template @@ -945,6 +959,26 @@ class basic_string void resize(size_type n) { resize(n, CharT()); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are uninitialized. + //! + //! Throws: If memory allocation throws + //! + //! Complexity: Linear to the difference between size() and new_size. + //! + //! Note: Non-standard extension + void resize(size_type n, default_init_t) + { + if (n <= this->size()) + this->erase(this->begin() + n, this->end()); + else{ + this->priv_reserve(n, false); + this->priv_size(n); + this->priv_terminate_string(); + } + } + //! Effects: Number of elements for which memory has been allocated. //! capacity() is always greater than or equal to size(). //! @@ -961,29 +995,7 @@ class basic_string //! //! Throws: If memory allocation allocation throws void reserve(size_type res_arg) - { - if (res_arg > this->max_size()){ - throw_length_error("basic_string::reserve max_size() exceeded"); - } - - if (this->capacity() < res_arg){ - size_type n = container_detail::max_value(res_arg, this->size()) + 1; - size_type new_cap = this->next_capacity(n); - pointer new_start = this->allocation_command - (allocate_new, n, new_cap, new_cap).first; - size_type new_length = 0; - - const pointer addr = this->priv_addr(); - new_length += priv_uninitialized_copy - (addr, addr + this->priv_size(), new_start); - this->priv_construct_null(new_start + new_length); - this->deallocate_block(); - this->is_short(false); - this->priv_long_addr(new_start); - this->priv_long_size(new_length); - this->priv_storage(new_cap); - } - } + { this->priv_reserve(res_arg); } //! Effects: Tries to deallocate the excess of memory created //! with previous allocations. The size of the string is unchanged @@ -2296,8 +2308,35 @@ class basic_string int compare(size_type pos1, size_type n1, const CharT* s) const { return this->compare(pos1, n1, s, Traits::length(s)); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: + void priv_reserve(size_type res_arg, const bool null_terminate = true) + { + if (res_arg > this->max_size()){ + throw_length_error("basic_string::reserve max_size() exceeded"); + } + + if (this->capacity() < res_arg){ + size_type n = container_detail::max_value(res_arg, this->size()) + 1; + size_type new_cap = this->next_capacity(n); + pointer new_start = this->allocation_command + (allocate_new, n, new_cap, new_cap).first; + size_type new_length = 0; + + const pointer addr = this->priv_addr(); + new_length += priv_uninitialized_copy + (addr, addr + this->priv_size(), new_start); + if(null_terminate){ + this->priv_construct_null(new_start + new_length); + } + this->deallocate_block(); + this->is_short(false); + this->priv_long_addr(new_start); + this->priv_long_size(new_length); + this->priv_storage(new_cap); + } + } + static int s_compare(const_pointer f1, const_pointer l1, const_pointer f2, const_pointer l2) { @@ -2431,9 +2470,11 @@ class basic_string return this->priv_replace(first, last, f, l, Category()); } - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; +#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED + //!Typedef for a basic_string of //!narrow characters typedef basic_string @@ -2450,6 +2491,8 @@ typedef basic_string ,std::allocator > wstring; +#endif + // ------------------------------------------------------------ // Non-member functions. @@ -2663,7 +2706,7 @@ template inline void swap(basic_string& x, basic_string& y) { x.swap(y); } -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED // I/O. namespace container_detail { @@ -2683,7 +2726,7 @@ string_fill(std::basic_ostream& os, } } //namespace container_detail { -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED template std::basic_ostream& @@ -2814,7 +2857,7 @@ inline std::size_t hash_value(basic_string, Allocator> }} -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { @@ -2827,7 +2870,7 @@ struct has_trivial_destructor_after_move diff --git a/include/boost/container/throw_exception.hpp b/include/boost/container/throw_exception.hpp index 7c821c0..ab01c30 100644 --- a/include/boost/container/throw_exception.hpp +++ b/include/boost/container/throw_exception.hpp @@ -76,26 +76,82 @@ namespace container { #else //defined(BOOST_NO_EXCEPTIONS) + //! Exception callback called by Boost.Container when fails to allocate the requested storage space. + //!

inline void throw_bad_alloc() { throw std::bad_alloc(); } + //! Exception callback called by Boost.Container to signal arguments out of range. + //!
    + //!
  • If BOOST_NO_EXCEPTIONS is NOT defined std::out_of_range(str) is thrown.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str) is called + //! and std::abort() if the former returns.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
  • + //!
inline void throw_out_of_range(const char* str) { throw std::out_of_range(str); } + //! Exception callback called by Boost.Container to signal errors resizing. + //!
    + //!
  • If BOOST_NO_EXCEPTIONS is NOT defined std::length_error(str) is thrown.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container length_error thrown", str) is called + //! and std::abort() if the former returns.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
  • + //!
inline void throw_length_error(const char* str) { throw std::length_error(str); } + //! Exception callback called by Boost.Container to report errors in the internal logical + //! of the program, such as violation of logical preconditions or class invariants. + //!
    + //!
  • If BOOST_NO_EXCEPTIONS is NOT defined std::logic_error(str) is thrown.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str) is called + //! and std::abort() if the former returns.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
  • + //!
inline void throw_logic_error(const char* str) { throw std::logic_error(str); } + //! Exception callback called by Boost.Container to report errors that can only be detected during runtime. + //!
    + //!
  • If BOOST_NO_EXCEPTIONS is NOT defined std::runtime_error(str) is thrown.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str) is called + //! and std::abort() if the former returns.
  • + //! + //!
  • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
  • + //!
inline void throw_runtime_error(const char* str) { throw std::runtime_error(str); diff --git a/include/boost/container/vector.hpp b/include/boost/container/vector.hpp index 675ae12..44802b4 100644 --- a/include/boost/container/vector.hpp +++ b/include/boost/container/vector.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -53,7 +53,7 @@ namespace boost { namespace container { -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //#define BOOST_CONTAINER_VECTOR_ITERATOR_IS_POINTER @@ -80,7 +80,7 @@ class vec_iterator , value_type& >::type reference; - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: Pointer m_ptr; @@ -94,7 +94,7 @@ class vec_iterator explicit vec_iterator(Pointer ptr) BOOST_CONTAINER_NOEXCEPT : m_ptr(ptr) {} - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: @@ -245,17 +245,10 @@ struct vector_value_traits ,container_detail::scoped_destructor_n - >::type OldArrayDestructor; - //This is the anti-exception array destructor - //to destroy objects created with copy construction - typedef typename container_detail::if_c - - ,container_detail::scoped_destructor_n >::type ArrayDestructor; //This is the anti-exception array deallocator typedef typename container_detail::if_c - ,container_detail::scoped_array_deallocator >::type ArrayDeallocator; @@ -294,7 +287,7 @@ struct vector_alloc_holder //Constructor, does not throw template - explicit vector_alloc_holder(uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) + vector_alloc_holder(uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) : Allocator(boost::forward(a)) , m_start() , m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this @@ -306,7 +299,7 @@ struct vector_alloc_holder } //Constructor, does not throw - explicit vector_alloc_holder(uninitialized_size_t, size_type initial_size) + vector_alloc_holder(uninitialized_size_t, size_type initial_size) : Allocator() , m_start() , m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this @@ -347,7 +340,7 @@ struct vector_alloc_holder } std::pair - allocation_command(allocation_type command, + allocation_command(boost::container::allocation_type command, size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse = pointer()) @@ -358,8 +351,10 @@ struct vector_alloc_holder size_type next_capacity(size_type additional_objects) const { - return get_next_capacity( allocator_traits_type::max_size(this->alloc()) - , this->m_capacity, additional_objects); + return next_capacity_calculator + :: + get( allocator_traits_type::max_size(this->alloc()) + , this->m_capacity, additional_objects ); } pointer m_start; @@ -526,9 +521,8 @@ struct vector_alloc_holder #endif class vector { - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED typedef container_detail::integral_constant ::value > alloc_version; @@ -557,7 +551,7 @@ class vector typedef container_detail::vec_iterator iterator_impl; typedef container_detail::vec_iterator const_iterator_impl; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// // @@ -584,7 +578,7 @@ class vector typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) reverse_iterator; typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator) const_reverse_iterator; - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED private: BOOST_COPYABLE_AND_MOVABLE(vector) typedef container_detail::vector_value_traits value_traits; @@ -594,7 +588,7 @@ class vector typedef container_detail::integral_constant allocator_v2; typedef constant_iterator cvalue_iterator; - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED public: ////////////////////////////////////////////// @@ -645,7 +639,7 @@ class vector //! Complexity: Linear to n. //! //! Note: Non-standard extension - explicit vector(size_type n, default_init_t) + vector(size_type n, default_init_t) : m_holder(container_detail::uninitialized_size, n) { boost::container::uninitialized_default_init_alloc_n @@ -810,7 +804,7 @@ class vector vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x) { if (&x != this){ - this->priv_copy_assign(boost::move(x), alloc_version()); + this->priv_copy_assign(x, alloc_version()); } return *this; } @@ -860,8 +854,9 @@ class vector void assign(InIt first, InIt last #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) , typename container_detail::enable_if_c - < !container_detail::is_convertible::value - //&& container_detail::is_input_iterator::value + < !container_detail::is_convertible::value && + ( container_detail::is_input_iterator::value || + container_detail::is_same::value ) >::type * = 0 #endif ) @@ -885,6 +880,64 @@ class vector } } + //! Effects: Assigns the the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment or + //! T's constructor/assignment from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + void assign(FwdIt first, FwdIt last + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + , typename container_detail::enable_if_c + < !container_detail::is_convertible::value && + ( !container_detail::is_input_iterator::value && + !container_detail::is_same::value ) + >::type * = 0 + #endif + ) + { + //For Fwd iterators the standard only requires EmplaceConstructible and assignble from *first + //so we can't do any backwards allocation + const size_type input_sz = static_cast(std::distance(first, last)); + const size_type old_capacity = this->capacity(); + if(input_sz > old_capacity){ //If input range is too big, we need to reallocate + size_type real_cap; + std::pair ret = + this->m_holder.allocation_command(allocate_new, input_sz, input_sz, real_cap, this->m_holder.start()); + if(!ret.second){ //New allocation, just emplace new values + pointer const old_p = this->m_holder.start(); + if(old_p){ + this->priv_destroy_all(); + this->m_holder.alloc().deallocate(old_p, old_capacity); + } + this->m_holder.start(ret.first); + this->m_holder.capacity(real_cap); + this->m_holder.m_size = 0; + this->priv_uninitialized_construct_at_end(first, last); + return; + } + else{ + //Forward expansion, use assignment + back deletion/construction that comes later + } + } + //Overwrite all elements we can from [first, last) + iterator cur = this->begin(); + const iterator end_it = this->end(); + for ( ; first != last && cur != end_it; ++cur, ++first){ + *cur = *first; + } + + if (first == last){ + //There are no more elements in the sequence, erase remaining + this->priv_destroy_last_n(this->size() - input_sz); + } + else{ + //Uninitialized construct at end the remaining range + this->priv_uninitialized_construct_at_end(first, last); + } + } + //! Effects: Assigns the n copies of val to *this. //! //! Throws: If memory allocation throws or @@ -1067,18 +1120,7 @@ class vector //! //! Complexity: Linear to the difference between size() and new_size. void resize(size_type new_size) - { - const size_type sz = this->size(); - if (new_size < sz){ - //Destroy last elements - this->priv_destroy_last_n(sz - new_size); - } - else{ - const size_type n = new_size - this->size(); - container_detail::insert_value_initialized_n_proxy proxy(this->m_holder.alloc()); - this->priv_forward_range_insert_at_end(n, proxy, alloc_version()); - } - } + { this->priv_resize(new_size, value_init); } //! Effects: Inserts or erases elements at the end such that //! the size becomes n. New elements are value initialized. @@ -1089,18 +1131,7 @@ class vector //! //! Note: Non-standard extension void resize(size_type new_size, default_init_t) - { - const size_type sz = this->size(); - if (new_size < sz){ - //Destroy last elements - this->priv_destroy_last_n(sz - new_size); - } - else{ - const size_type n = new_size - this->size(); - container_detail::insert_default_initialized_n_proxy proxy(this->m_holder.alloc()); - this->priv_forward_range_insert_at_end(n, proxy, alloc_version()); - } - } + { this->priv_resize(new_size, default_init); } //! Effects: Inserts or erases elements at the end such that //! the size becomes n. New elements are copy constructed from x. @@ -1109,18 +1140,7 @@ class vector //! //! Complexity: Linear to the difference between size() and new_size. void resize(size_type new_size, const T& x) - { - const size_type sz = this->size(); - if (new_size < sz){ - //Destroy last elements - this->priv_destroy_last_n(sz - new_size); - } - else{ - const size_type n = new_size - this->size(); - container_detail::insert_n_copies_proxy proxy(this->m_holder.alloc(), x); - this->priv_forward_range_insert_at_end(n, proxy, alloc_version()); - } - } + { this->priv_resize(new_size, x); } //! Effects: Number of elements for which memory has been allocated. //! capacity() is always greater than or equal to size(). @@ -1297,7 +1317,7 @@ class vector else{ typedef container_detail::insert_emplace_proxy type; this->priv_forward_range_insert_no_capacity - (vector_iterator_get_ptr(this->cend()), 1, type(this->m_holder.alloc(), ::boost::forward(args)...), alloc_version()); + (vector_iterator_get_ptr(this->cend()), 1, type(::boost::forward(args)...), alloc_version()); } } @@ -1316,8 +1336,8 @@ class vector { //Just call more general insert(pos, size, value) and return iterator typedef container_detail::insert_emplace_proxy type; - return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1, type(this->m_holder.alloc() - , ::boost::forward(args)...), alloc_version()); + return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1 + , type(::boost::forward(args)...), alloc_version()); } #else @@ -1334,11 +1354,11 @@ class vector ++this->m_holder.m_size; \ } \ else{ \ - container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \ - proxy \ - (this->m_holder.alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ + typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \ + type; \ this->priv_forward_range_insert_no_capacity \ - (vector_iterator_get_ptr(this->cend()), 1, proxy, alloc_version()); \ + ( vector_iterator_get_ptr(this->cend()), 1 \ + , type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)), alloc_version()); \ } \ } \ \ @@ -1346,11 +1366,11 @@ class vector iterator emplace(const_iterator pos \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ { \ - container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \ - proxy \ - (this->m_holder.alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \ + typedef container_detail::BOOST_PP_CAT(insert_emplace_proxy_arg, n) \ + type; \ return this->priv_forward_range_insert \ - (container_detail::to_raw_pointer(vector_iterator_get_ptr(pos)), 1, proxy, alloc_version()); \ + ( container_detail::to_raw_pointer(vector_iterator_get_ptr(pos)), 1 \ + , type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)), alloc_version()); \ } \ //! #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) @@ -1414,7 +1434,7 @@ class vector //! Complexity: Linear to n. iterator insert(const_iterator p, size_type n, const T& x) { - container_detail::insert_n_copies_proxy proxy(this->m_holder.alloc(), x); + container_detail::insert_n_copies_proxy proxy(x); return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy, alloc_version()); } @@ -1456,7 +1476,7 @@ class vector >::type * = 0 ) { - container_detail::insert_range_proxy proxy(this->m_holder.alloc(), first); + container_detail::insert_range_proxy proxy(first); return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), std::distance(first, last), proxy, alloc_version()); } #endif @@ -1536,9 +1556,7 @@ class vector //! Note: non-standard extension. template void swap(vector & x) - { - this->m_holder.swap(x.m_holder); - } + { this->m_holder.swap(x.m_holder); } #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED @@ -1550,7 +1568,7 @@ class vector void clear() BOOST_CONTAINER_NOEXCEPT { this->priv_destroy_all(); } - /// @cond + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED //Absolutely experimental. This function might change, disappear or simply crash! template @@ -1590,9 +1608,7 @@ class vector < !container_detail::is_same::value || container_detail::is_same::value >::type * = 0) - { - this->priv_move_assign_impl(boost::move(x), AllocVersion()); - } + { this->priv_move_assign_impl(boost::move(x), AllocVersion()); } template void priv_move_assign_impl(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x @@ -1671,29 +1687,23 @@ class vector } void priv_reserve(size_type, allocator_v0) + { throw_bad_alloc(); } + + container_detail::insert_range_proxy, T*> priv_dummy_empty_proxy() { - throw_bad_alloc(); + return container_detail::insert_range_proxy, T*> + (::boost::make_move_iterator((T *)0)); } void priv_reserve(size_type new_cap, allocator_v1) { //There is not enough memory, allocate a new buffer pointer p = this->m_holder.allocate(new_cap); - //Backwards (and possibly forward) expansion - #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS - ++this->num_alloc; - #endif - T * const raw_beg = container_detail::to_raw_pointer(this->m_holder.start()); - const size_type sz = m_holder.m_size; - ::boost::container::uninitialized_move_alloc_n_source - ( this->m_holder.alloc(), raw_beg, sz, container_detail::to_raw_pointer(p) ); - if(this->m_holder.capacity()){ - if(!value_traits::trivial_dctr_after_move) - boost::container::destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz); - this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity()); - } - this->m_holder.start(p); - this->m_holder.capacity(new_cap); + //We will reuse insert code, so create a dummy input iterator + this->priv_forward_range_insert_new_allocation + ( container_detail::to_raw_pointer(p), new_cap + , container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size + , 0, this->priv_dummy_empty_proxy()); } void priv_reserve(size_type new_cap, allocator_v2) @@ -1702,10 +1712,8 @@ class vector //buffer or expand the old one. bool same_buffer_start; size_type real_cap = 0; - std::pair ret = - this->m_holder.allocation_command - (allocate_new | expand_fwd | expand_bwd, - new_cap, new_cap, real_cap, this->m_holder.start()); + std::pair ret = this->m_holder.allocation_command + (allocate_new | expand_fwd | expand_bwd, new_cap, new_cap, real_cap, this->m_holder.start()); //Check for forward expansion same_buffer_start = ret.second && this->m_holder.start() == ret.first; @@ -1715,52 +1723,26 @@ class vector #endif this->m_holder.capacity(real_cap); } - //If there is no forward expansion, move objects - else{ - //Backwards (and possibly forward) expansion - if(ret.second){ - //We will reuse insert code, so create a dummy input iterator - container_detail::insert_range_proxy, T*> - proxy(this->m_holder.alloc(), ::boost::make_move_iterator((T *)0)); + else{ //If there is no forward expansion, move objects, we will reuse insertion code + T * const new_mem = container_detail::to_raw_pointer(ret.first); + T * const ins_pos = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size; + if(ret.second){ //Backwards (and possibly forward) expansion #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_expand_bwd; #endif this->priv_forward_range_insert_expand_backwards - ( container_detail::to_raw_pointer(ret.first) - , real_cap - , container_detail::to_raw_pointer(this->m_holder.start()) - , 0 - , proxy); + ( new_mem , real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); } - //New buffer - else{ + else{ //New buffer #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_alloc; #endif - T * const raw_beg = container_detail::to_raw_pointer(this->m_holder.start()); - const size_type sz = m_holder.m_size; - ::boost::container::uninitialized_move_alloc_n_source - ( this->m_holder.alloc(), raw_beg, sz, container_detail::to_raw_pointer(ret.first) ); - if(this->m_holder.capacity()){ - if(!value_traits::trivial_dctr_after_move) - boost::container::destroy_alloc_n(this->m_holder.alloc(), raw_beg, sz); - this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity()); - } - this->m_holder.start(ret.first); - this->m_holder.capacity(real_cap); + this->priv_forward_range_insert_new_allocation + ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); } } } - template - void priv_uninitialized_fill(Proxy proxy, size_type n) const - { - //Copy first new elements in pos - proxy.uninitialized_copy_n_and_update - (container_detail::to_raw_pointer(this->m_holder.start()), n); - //m_holder.size was already initialized to n in vector_alloc_holder's constructor - } - void priv_destroy(value_type* p) BOOST_CONTAINER_NOEXCEPT { if(!value_traits::trivial_dctr) @@ -1774,6 +1756,16 @@ class vector this->m_holder.m_size -= n; } + template + void priv_uninitialized_construct_at_end(InpIt first, InpIt last) + { + T* end_pos = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size; + for(; first != last; ++first, ++end_pos, ++this->m_holder.m_size){ + //There is more memory, just construct a new object at the end + allocator_traits_type::construct(this->m_holder.alloc(), end_pos, *first); + } + } + void priv_destroy_all() BOOST_CONTAINER_NOEXCEPT { boost::container::destroy_alloc_n @@ -1785,39 +1777,54 @@ class vector iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x) { return this->priv_forward_range_insert - ( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy(this->m_holder.alloc() - , ::boost::forward(x)), alloc_version()); + ( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy + (::boost::forward(x)), alloc_version()); } - void priv_push_back(const T &x) + container_detail::insert_copy_proxy priv_single_insert_proxy(const T &x) + { return container_detail::insert_copy_proxy (x); } + + container_detail::insert_move_proxy priv_single_insert_proxy(BOOST_RV_REF(T) x) + { return container_detail::insert_move_proxy (x); } + + template + void priv_push_back(BOOST_FWD_REF(U) u) { if (this->m_holder.m_size < this->m_holder.capacity()){ //There is more memory, just construct a new object at the end allocator_traits_type::construct ( this->m_holder.alloc() , container_detail::to_raw_pointer(this->m_holder.start() + this->m_holder.m_size) - , x ); + , ::boost::forward(u) ); ++this->m_holder.m_size; } else{ - container_detail::insert_copy_proxy proxy(this->m_holder.alloc(), x); - this->priv_forward_range_insert_no_capacity(vector_iterator_get_ptr(this->cend()), 1, proxy, alloc_version()); + this->priv_forward_range_insert_no_capacity + ( vector_iterator_get_ptr(this->cend()), 1 + , this->priv_single_insert_proxy(::boost::forward(u)), alloc_version()); } } - void priv_push_back(BOOST_RV_REF(T) x) + container_detail::insert_n_copies_proxy priv_resize_proxy(const T &x) + { return container_detail::insert_n_copies_proxy(x); } + + container_detail::insert_default_initialized_n_proxy priv_resize_proxy(default_init_t) + { return container_detail::insert_default_initialized_n_proxy(); } + + container_detail::insert_value_initialized_n_proxy priv_resize_proxy(value_init_t) + { return container_detail::insert_value_initialized_n_proxy(); } + + template + void priv_resize(size_type new_size, const U& u) { - if (this->m_holder.m_size < this->m_holder.capacity()){ - //There is more memory, just construct a new object at the end - allocator_traits_type::construct - ( this->m_holder.alloc() - , container_detail::to_raw_pointer(this->m_holder.start() + this->m_holder.m_size) - , ::boost::move(x) ); - ++this->m_holder.m_size; + const size_type sz = this->size(); + if (new_size < sz){ + //Destroy last elements + this->priv_destroy_last_n(sz - new_size); } else{ - container_detail::insert_move_proxy proxy(this->m_holder.alloc(), x); - this->priv_forward_range_insert_no_capacity(vector_iterator_get_ptr(this->cend()), 1, proxy, alloc_version()); + const size_type n = new_size - this->size(); + this->priv_forward_range_insert_at_end(n, this->priv_resize_proxy(u), alloc_version()); } } @@ -1839,17 +1846,13 @@ class vector pointer p = this->m_holder.allocate(sz); //We will reuse insert code, so create a dummy input iterator - container_detail::insert_range_proxy, T*> - proxy(this->m_holder.alloc(), ::boost::make_move_iterator((T *)0)); #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS ++this->num_alloc; #endif this->priv_forward_range_insert_new_allocation - ( container_detail::to_raw_pointer(p) - , sz + ( container_detail::to_raw_pointer(p), sz , container_detail::to_raw_pointer(this->m_holder.start()) - , 0 - , proxy); + , 0, this->priv_dummy_empty_proxy()); } } } @@ -1981,8 +1984,7 @@ class vector if (n <= remaining){ const size_type n_pos = raw_pos - container_detail::to_raw_pointer(this->m_holder.start()); - this->priv_forward_range_insert_expand_forward - (raw_pos, n, insert_range_proxy); + this->priv_forward_range_insert_expand_forward(raw_pos, n, insert_range_proxy); return iterator(this->m_holder.start() + n_pos); } else{ @@ -2164,7 +2166,7 @@ class vector T* const last_ptr = begin_ptr + last_pos; size_type hole_size = 0; - //Case Allocator: + //Case A: if((last_pos + shift_count) <= limit_pos){ //All move assigned boost::move_backward(first_ptr, last_ptr, last_ptr + shift_count); @@ -2193,7 +2195,7 @@ class vector void priv_forward_range_insert_at_end_expand_forward(const size_type n, InsertionProxy insert_range_proxy) { T* const old_finish = container_detail::to_raw_pointer(this->m_holder.start()) + this->m_holder.m_size; - insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n); + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); this->m_holder.m_size += n; } @@ -2207,7 +2209,7 @@ class vector const size_type elems_after = old_finish - pos; if (!elems_after){ - insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n); + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); this->m_holder.m_size += n; } else if (elems_after >= n){ @@ -2219,7 +2221,7 @@ class vector //Copy previous to last objects to the initialized end boost::move_backward(pos, old_finish - n, old_finish); //Insert new objects in the pos - insert_range_proxy.copy_n_and_update(pos, n); + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n); } else { //The new elements don't fit in the [pos, end()) range. @@ -2228,9 +2230,9 @@ class vector ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pos, old_finish, pos + n); BOOST_TRY{ //Copy first new elements in pos (gap is still there) - insert_range_proxy.copy_n_and_update(pos, elems_after); + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elems_after); //Copy to the beginning of the unallocated zone the last new elements (the gap is closed). - insert_range_proxy.uninitialized_copy_n_and_update(old_finish, n - elems_after); + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n - elems_after); this->m_holder.m_size += n; } BOOST_CATCH(...){ @@ -2249,21 +2251,22 @@ class vector T *new_finish = new_start; T *old_finish; //Anti-exception rollbacks - typename value_traits::ArrayDeallocator scoped_alloc(new_start, this->m_holder.alloc(), new_cap); - typename value_traits::ArrayDestructor constructed_values_destroyer(new_start, this->m_holder.alloc(), 0u); + typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, this->m_holder.alloc(), new_cap); + typename value_traits::ArrayDestructor new_values_destroyer(new_start, this->m_holder.alloc(), 0u); //Initialize with [begin(), pos) old buffer //the start of the new buffer - T *old_buffer = container_detail::to_raw_pointer(this->m_holder.start()); + T * const old_buffer = container_detail::to_raw_pointer(this->m_holder.start()); if(old_buffer){ new_finish = ::boost::container::uninitialized_move_alloc (this->m_holder.alloc(), container_detail::to_raw_pointer(this->m_holder.start()), pos, old_finish = new_finish); - constructed_values_destroyer.increment_size(new_finish - old_finish); + new_values_destroyer.increment_size(new_finish - old_finish); } //Initialize new objects, starting from previous point - insert_range_proxy.uninitialized_copy_n_and_update(old_finish = new_finish, n); + old_finish = new_finish; + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, n); new_finish += n; - constructed_values_destroyer.increment_size(new_finish - old_finish); + new_values_destroyer.increment_size(new_finish - old_finish); //Initialize from the rest of the old buffer, //starting from previous point if(old_buffer){ @@ -2279,8 +2282,8 @@ class vector this->m_holder.m_size = new_finish - new_start; this->m_holder.capacity(new_cap); //All construction successful, disable rollbacks - constructed_values_destroyer.release(); - scoped_alloc.release(); + new_values_destroyer.release(); + new_buffer_deallocator.release(); } template @@ -2291,8 +2294,8 @@ class vector //n can be zero to just expand capacity //Backup old data T* const old_start = container_detail::to_raw_pointer(this->m_holder.start()); - T* const old_finish = old_start + this->m_holder.m_size; const size_type old_size = this->m_holder.m_size; + T* const old_finish = old_start + old_size; //We can have 8 possibilities: const size_type elemsbefore = static_cast(pos - old_start); @@ -2306,17 +2309,18 @@ class vector //If anything goes wrong, this object will destroy //all the old objects to fulfill previous vector state - typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->m_holder.alloc(), old_size); + typename value_traits::ArrayDestructor old_values_destroyer(old_start, this->m_holder.alloc(), old_size); //Check if s_before is big enough to hold the beginning of old data + new data if(s_before >= before_plus_new){ //Copy first old values before pos, after that the new objects - T *const new_elem_pos = ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), old_start, pos, new_start); + T *const new_elem_pos = + ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), old_start, pos, new_start); this->m_holder.m_size = elemsbefore; - insert_range_proxy.uninitialized_copy_n_and_update(new_elem_pos, n); - this->m_holder.m_size += n; + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_elem_pos, n); + this->m_holder.m_size = before_plus_new; + const size_type new_size = old_size + n; //Check if s_before is so big that even copying the old data + new data //there is a gap between the new data and the old data - const size_type new_size = old_size + n; if(s_before >= new_size){ //Old situation: // _________________________________________________________ @@ -2329,10 +2333,12 @@ class vector //|___________|__________|_________|________________________| // //Now initialize the rest of memory with the last old values - ::boost::container::uninitialized_move_alloc - (this->m_holder.alloc(), pos, old_finish, new_start + before_plus_new); - //All new elements correctly constructed, avoid new element destruction - this->m_holder.m_size = new_size; + if(before_plus_new != new_size){ //Special case to avoid operations in back insertion + ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), pos, old_finish, new_start + before_plus_new); + //All new elements correctly constructed, avoid new element destruction + this->m_holder.m_size = new_size; + } //Old values destroyed automatically with "old_values_destroyer" //when "old_values_destroyer" goes out of scope unless the have trivial //destructor after move. @@ -2354,22 +2360,28 @@ class vector //Now initialize the rest of memory with the last old values //All new elements correctly constructed, avoid new element destruction const size_type raw_gap = s_before - before_plus_new; - //Now initialize the rest of s_before memory with the - //first of elements after new values - ::boost::container::uninitialized_move_alloc_n - (this->m_holder.alloc(), pos, raw_gap, new_start + before_plus_new); - //Update size since we have a contiguous buffer - this->m_holder.m_size = old_size + s_before; - //All new elements correctly constructed, avoid old element destruction - old_values_destroyer.release(); - //Now copy remaining last objects in the old buffer begin - T * const to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start); - //Now destroy redundant elements except if they were moved and - //they have trivial destructor after move - size_type n_destroy = old_finish - to_destroy; - if(!value_traits::trivial_dctr_after_move) - boost::container::destroy_alloc_n(this->get_stored_allocator(), to_destroy, n_destroy); - this->m_holder.m_size -= n_destroy; + if(!value_traits::trivial_dctr){ + //Now initialize the rest of s_before memory with the + //first of elements after new values + ::boost::container::uninitialized_move_alloc_n + (this->m_holder.alloc(), pos, raw_gap, new_start + before_plus_new); + //Now we have a contiguous buffer so program trailing element destruction + //and update size to the final size. + old_values_destroyer.shrink_forward(elemsbefore + raw_gap); + this->m_holder.m_size = new_size; + //Now move remaining last objects in the old buffer begin + ::boost::move(pos + raw_gap, old_finish, old_start); + //Once moved, avoid calling the destructors if trivial after move + if(value_traits::trivial_dctr_after_move){ + old_values_destroyer.release(); + } + } + else{ //If trivial destructor, we can uninitialized copy + copy in a single uninitialized copy + ::boost::container::uninitialized_move_alloc_n + (this->m_holder.alloc(), pos, old_finish - pos, new_start + before_plus_new); + this->m_holder.m_size = new_size; + old_values_destroyer.release(); + } } } else{ @@ -2423,27 +2435,30 @@ class vector //Copy the first part of old_begin to raw_mem ::boost::container::uninitialized_move_alloc_n (this->m_holder.alloc(), old_start, s_before, new_start); - //The buffer is all constructed until old_end, - //release destroyer and update size - old_values_destroyer.release(); - this->m_holder.m_size = old_size + s_before; - //Now copy the second part of old_begin overwriting itself - T *const next = ::boost::move(old_start + s_before, pos, old_start); + //The buffer is all constructed until old_end if(do_after){ + //release destroyer and update size + old_values_destroyer.release(); + this->m_holder.m_size = old_size + s_before; + //Now copy the second part of old_begin overwriting itself + T *const next = ::boost::move(old_start + s_before, pos, old_start); //Now copy the new_beg elements - insert_range_proxy.copy_n_and_update(next, s_before); + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, s_before); } else{ - //Now copy the all the new elements - insert_range_proxy.copy_n_and_update(next, n); - //Now displace old_end elements - T* const move_end = ::boost::move(pos, old_finish, next + n); - //Destroy remaining moved elements from old_end except if - //they have trivial destructor after being moved + //The buffer is all constructed until old_end, + //so program trailing destruction and assign final size + this->m_holder.m_size = old_size + n; const size_type n_destroy = s_before - n; - if(!value_traits::trivial_dctr_after_move) - boost::container::destroy_alloc_n(this->get_stored_allocator(), move_end, n_destroy); - this->m_holder.m_size -= n_destroy; + old_values_destroyer.shrink_forward(old_size - n_destroy); + //Now copy the second part of old_begin overwriting itself + T *const next = ::boost::move(old_start + s_before, pos, old_start); + //Now copy the all the new elements + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), next, n); + //Now displace old_end elements + ::boost::move(pos, old_finish, next + n); + if(value_traits::trivial_dctr_after_move) + old_values_destroyer.release(); } } else { @@ -2477,7 +2492,7 @@ class vector (this->m_holder.alloc(), old_start, pos, new_start); this->m_holder.m_size = elemsbefore; const size_type mid_n = s_before - elemsbefore; - insert_range_proxy.uninitialized_copy_n_and_update(new_pos, mid_n); + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), new_pos, mid_n); //The buffer is all constructed until old_end, //release destroyer this->m_holder.m_size = old_size + s_before; @@ -2485,15 +2500,15 @@ class vector if(do_after){ //Copy new_beg part - insert_range_proxy.copy_n_and_update(old_start, elemsbefore); + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, elemsbefore); } else{ //Copy all new elements const size_type rest_new = n - mid_n; - insert_range_proxy.copy_n_and_update(old_start, rest_new); - T* move_start = old_start + rest_new; + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), old_start, rest_new); + T* const move_start = old_start + rest_new; //Displace old_end - T* move_end = ::boost::move(pos, old_finish, move_start); + T* const move_end = ::boost::move(pos, old_finish, move_start); //Destroy remaining moved elements from old_end except if they //have trivial destructor after being moved size_type n_destroy = s_before - n; @@ -2548,7 +2563,7 @@ class vector boost::move_backward(pos, finish_n, old_finish); //Now overwrite with new_end //The new_end part is [first + (n - n_after), last) - insert_range_proxy.copy_n_and_update(pos, n_after); + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, n_after); } else { //The raw_mem from end will divide new_end part @@ -2573,9 +2588,9 @@ class vector BOOST_TRY{ //Copy the first part to the already constructed old_end zone - insert_range_proxy.copy_n_and_update(pos, elemsafter); + insert_range_proxy.copy_n_and_update(this->m_holder.alloc(), pos, elemsafter); //Copy the rest to the uninitialized zone filling the gap - insert_range_proxy.uninitialized_copy_n_and_update(old_finish, mid_last_dist); + insert_range_proxy.uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, mid_last_dist); this->m_holder.m_size += n_after; } BOOST_CATCH(...){ @@ -2617,7 +2632,7 @@ class vector void reset_alloc_stats() { num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; } #endif - /// @endcond + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED }; template @@ -2649,7 +2664,7 @@ inline void swap(vector& x, vector& y) }} -/// @cond +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED namespace boost { @@ -2678,9 +2693,8 @@ inline void swap(boost::container::vector& x, boost::container::ve #endif -/// @endcond +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #include #endif // #ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP - diff --git a/index.html b/index.html index 1251783..fe55e4d 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ diff --git a/proj/vc7ide/allocator_traits_test.vcproj b/proj/vc7ide/allocator_traits_test.vcproj index 6e73236..dcb62fc 100644 --- a/proj/vc7ide/allocator_traits_test.vcproj +++ b/proj/vc7ide/allocator_traits_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" GeneratePreprocessedFile="0" MinimalRebuild="TRUE" BasicRuntimeChecks="3" @@ -74,7 +74,7 @@ - - - - diff --git a/proj/vc7ide/bench_set.vcproj b/proj/vc7ide/bench_set.vcproj index 327e6fe..42ab275 100644 --- a/proj/vc7ide/bench_set.vcproj +++ b/proj/vc7ide/bench_set.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" ExceptionHandling="TRUE" BasicRuntimeChecks="3" @@ -74,7 +74,7 @@ + RelativePath="..\..\..\..\boost\container\adaptive_pool.hpp"> + RelativePath="..\..\..\..\boost\container\allocator.hpp"> + + @@ -122,6 +125,9 @@ + + @@ -155,6 +161,9 @@ + + @@ -164,12 +173,21 @@ + + + + + + @@ -203,9 +221,15 @@ + + + + @@ -215,9 +239,15 @@ + + + + @@ -282,6 +312,9 @@ + + diff --git a/proj/vc7ide/deque_test.vcproj b/proj/vc7ide/deque_test.vcproj index b416a71..aab9341 100644 --- a/proj/vc7ide/deque_test.vcproj +++ b/proj/vc7ide/deque_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -73,7 +73,7 @@ - - diff --git a/proj/vc7ide/flat_tree_test.vcproj b/proj/vc7ide/flat_tree_test.vcproj deleted file mode 100644 index 4e05a16..0000000 --- a/proj/vc7ide/flat_tree_test.vcproj +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/proj/vc7ide/list_test.vcproj b/proj/vc7ide/list_test.vcproj index e3198de..4aa86f9 100644 --- a/proj/vc7ide/list_test.vcproj +++ b/proj/vc7ide/list_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" GeneratePreprocessedFile="0" KeepComments="FALSE" MinimalRebuild="TRUE" @@ -75,7 +75,7 @@ - - diff --git a/proj/vc7ide/scoped_allocator_usage_test.vcproj b/proj/vc7ide/scoped_allocator_usage_test.vcproj index a19b214..1b185c4 100644 --- a/proj/vc7ide/scoped_allocator_usage_test.vcproj +++ b/proj/vc7ide/scoped_allocator_usage_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" GeneratePreprocessedFile="0" MinimalRebuild="TRUE" BasicRuntimeChecks="3" @@ -74,7 +74,7 @@ - - diff --git a/proj/vc7ide/slist_test.vcproj b/proj/vc7ide/slist_test.vcproj index 2e813bb..386c09a 100644 --- a/proj/vc7ide/slist_test.vcproj +++ b/proj/vc7ide/slist_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -73,7 +73,7 @@ - - diff --git a/proj/vc7ide/stable_vector_test.vcproj b/proj/vc7ide/stable_vector_test.vcproj index fdc2192..8a05024 100644 --- a/proj/vc7ide/stable_vector_test.vcproj +++ b/proj/vc7ide/stable_vector_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -73,7 +73,7 @@ - - diff --git a/proj/vc7ide/string_test.vcproj b/proj/vc7ide/string_test.vcproj index 77f6f35..e49c2f5 100644 --- a/proj/vc7ide/string_test.vcproj +++ b/proj/vc7ide/string_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" GeneratePreprocessedFile="0" MinimalRebuild="TRUE" BasicRuntimeChecks="3" @@ -74,7 +74,7 @@ - - diff --git a/proj/vc7ide/throw_exception_test.vcproj b/proj/vc7ide/throw_exception_test.vcproj index 12b7bb8..521e9c5 100644 --- a/proj/vc7ide/throw_exception_test.vcproj +++ b/proj/vc7ide/throw_exception_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" ExceptionHandling="TRUE" BasicRuntimeChecks="3" @@ -74,7 +74,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/proj/vc7ide/vector_test.vcproj b/proj/vc7ide/vector_test.vcproj index 1076c97..10615e0 100644 --- a/proj/vc7ide/vector_test.vcproj +++ b/proj/vc7ide/vector_test.vcproj @@ -20,7 +20,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../../../.." - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" ExceptionHandling="TRUE" BasicRuntimeChecks="3" @@ -74,7 +74,7 @@ - - diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index af84010..074630b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,6 +1,6 @@ # Boost Container Library Test Jamfile -# (C) Copyright Ion Gaztanaga 2009. +# (C) Copyright Ion Gaztanaga 2009-2013. # 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) @@ -21,7 +21,7 @@ rule test_all for local fileb in [ glob *.cpp ] { - all_rules += [ run $(fileb) + all_rules += [ run $(fileb) /boost/container//boost_container /boost/timer//boost_timer : # additional args : # test-files : # requirements diff --git a/test/allocator_traits_test.cpp b/test/allocator_traits_test.cpp index 119ec72..ac6a1a1 100644 --- a/test/allocator_traits_test.cpp +++ b/test/allocator_traits_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/test/deque_test.cpp b/test/deque_test.cpp index f483fd6..4c87503 100644 --- a/test/deque_test.cpp +++ b/test/deque_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -17,6 +17,10 @@ #include #include +#include +#include +#include + #include "print_container.hpp" #include "check_equal_containers.hpp" #include "dummy_test_allocator.hpp" @@ -29,6 +33,7 @@ #include "emplace_test.hpp" #include "propagate_allocator_test.hpp" #include "vector_test.hpp" +#include "default_init_test.hpp" #include using namespace boost::container; @@ -49,6 +54,18 @@ template class boost::container::deque < test::movable_and_copyable_int , std::allocator >; +template class boost::container::deque + < test::movable_and_copyable_int + , allocator >; + +template class boost::container::deque + < test::movable_and_copyable_int + , adaptive_pool >; + +template class boost::container::deque + < test::movable_and_copyable_int + , node_allocator >; + }} //Function to check if both sets are equal @@ -145,11 +162,8 @@ bool do_test() typedef std::deque MyStdDeque; const int max = 100; BOOST_TRY{ - //Shared memory allocator must be always be initialized - //since it has no default constructor MyCntDeque *cntdeque = new MyCntDeque; MyStdDeque *stddeque = new MyStdDeque; - //Compare several shared memory deque operations with std::deque for(int i = 0; i < max*100; ++i){ IntType move_me(i); cntdeque->insert(cntdeque->end(), boost::move(move_me)); @@ -295,6 +309,38 @@ bool do_test() return true; } +template +struct GetAllocatorCont +{ + template + struct apply + { + typedef deque< ValueType + , typename allocator_traits + ::template portable_rebind_alloc::type + > type; + }; +}; + +template +int test_cont_variants() +{ + typedef typename GetAllocatorCont::template apply::type MyCont; + typedef typename GetAllocatorCont::template apply::type MyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyCont; + + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + return 0; +} + int main () { @@ -320,18 +366,26 @@ int main () } { - typedef deque MyDeque; - typedef deque MyMoveDeque; - typedef deque MyCopyMoveDeque; - typedef deque MyCopyDeque; - if(test::vector_test()) + if(test_cont_variants< std::allocator >()){ + std::cerr << "test_cont_variants< std::allocator > failed" << std::endl; return 1; - if(test::vector_test()) + } + + if(test_cont_variants< allocator >()){ + std::cerr << "test_cont_variants< allocator > failed" << std::endl; return 1; - if(test::vector_test()) + } + + if(test_cont_variants< node_allocator >()){ + std::cerr << "test_cont_variants< node_allocator > failed" << std::endl; return 1; - if(test::vector_test()) + } + + if(test_cont_variants< adaptive_pool >()){ + std::cerr << "test_cont_variants< adaptive_pool > failed" << std::endl; return 1; + } + if(!test::default_init_test< deque > >()){ std::cerr << "Default init test failed" << std::endl; return 1; diff --git a/test/dummy_test_allocator.hpp b/test/dummy_test_allocator.hpp index 29feec3..dd4872a 100644 --- a/test/dummy_test_allocator.hpp +++ b/test/dummy_test_allocator.hpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP #define BOOST_CONTAINER_DUMMY_TEST_ALLOCATOR_HPP -#if (defined _MSC_VER) +#if defined(_MSC_VER) # pragma once #endif @@ -33,9 +33,6 @@ #include #include -//!\file -//!Describes an allocator to test expand capabilities - namespace boost { namespace container { namespace test { diff --git a/test/expand_bwd_test_allocator.hpp b/test/expand_bwd_test_allocator.hpp index 1bd375a..745fc53 100644 --- a/test/expand_bwd_test_allocator.hpp +++ b/test/expand_bwd_test_allocator.hpp @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,7 +11,7 @@ #ifndef BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP #define BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP -#if (defined _MSC_VER) +#if defined(_MSC_VER) # pragma once #endif @@ -29,9 +29,6 @@ #include #include -//!\file -//!Describes an allocator to test expand capabilities - namespace boost { namespace container { namespace test { diff --git a/test/expand_bwd_test_template.hpp b/test/expand_bwd_test_template.hpp index 7014466..98c30f0 100644 --- a/test/expand_bwd_test_template.hpp +++ b/test/expand_bwd_test_template.hpp @@ -187,8 +187,8 @@ bool test_assign_with_expand_bwd() const int Offset[] = { 50, 50, 50}; const int InitialSize[] = { 25, 25, 25}; - const int AssignSize[] = { 40, 60, 80}; - const int Iterations = sizeof(AssignSize)/sizeof(int); + const int InsertSize[] = { 15, 35, 55}; + const int Iterations = sizeof(InsertSize)/sizeof(int); for(int iteration = 0; iteration data_to_assign; - data_to_assign.resize(AssignSize[iteration]); - for(int i = 0; i < AssignSize[iteration]; ++i){ - data_to_assign[i] = -i; + std::vector data_to_insert; + data_to_insert.resize(InsertSize[iteration]); + for(int i = 0; i < InsertSize[iteration]; ++i){ + data_to_insert[i] = -i; } //Insert initial data to the vector to test @@ -216,8 +216,8 @@ bool test_assign_with_expand_bwd() , initial_data.begin(), initial_data.end()); //Assign data - vector.assign(data_to_assign.begin(), data_to_assign.end()); - initial_data.assign(data_to_assign.begin(), data_to_assign.end()); + vector.insert(vector.cbegin(), data_to_insert.begin(), data_to_insert.end()); + initial_data.insert(initial_data.begin(), data_to_insert.begin(), data_to_insert.end()); //Now check that values are equal if(!CheckEqualVector(vector, initial_data)){ diff --git a/test/flat_tree_test.cpp b/test/flat_tree_test.cpp deleted file mode 100644 index aac8a27..0000000 --- a/test/flat_tree_test.cpp +++ /dev/null @@ -1,640 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2004-2012. 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 "print_container.hpp" -#include "dummy_test_allocator.hpp" -#include "movable_int.hpp" -#include "set_test.hpp" -#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 -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 - >; - -//As flat container iterators are typedefs for vector::[const_]iterator, -//no need to explicit instantiate them - -}} //boost::container - - -//Alias allocator type -typedef std::allocator allocator_t; -typedef std::allocator - movable_allocator_t; -typedef std::allocator > - pair_allocator_t; -typedef std::allocator > - movable_pair_allocator_t; -typedef std::allocator - move_copy_allocator_t; -typedef std::allocator > - move_copy_pair_allocator_t; -typedef std::allocator - copy_allocator_t; -typedef std::allocator > - copy_pair_allocator_t; - - -//Alias set types -typedef std::set MyStdSet; -typedef std::multiset MyStdMultiSet; -typedef std::map MyStdMap; -typedef std::multimap MyStdMultiMap; - -typedef flat_set, allocator_t> MyBoostSet; -typedef flat_multiset, allocator_t> MyBoostMultiSet; -typedef flat_map, pair_allocator_t> MyBoostMap; -typedef flat_multimap, pair_allocator_t> MyBoostMultiMap; - -typedef flat_set - ,movable_allocator_t> MyMovableBoostSet; -typedef flat_multiset - ,movable_allocator_t> MyMovableBoostMultiSet; -typedef flat_map - ,movable_pair_allocator_t> MyMovableBoostMap; -typedef flat_multimap - ,movable_pair_allocator_t> MyMovableBoostMultiMap; - -typedef flat_set - ,move_copy_allocator_t> MyMoveCopyBoostSet; -typedef flat_multiset - ,move_copy_allocator_t> MyMoveCopyBoostMultiSet; -typedef flat_map - ,move_copy_pair_allocator_t> MyMoveCopyBoostMap; -typedef flat_multimap - ,move_copy_pair_allocator_t> MyMoveCopyBoostMultiMap; - -typedef flat_set - ,copy_allocator_t> MyCopyBoostSet; -typedef flat_multiset - ,copy_allocator_t> MyCopyBoostMultiSet; -typedef flat_map - ,copy_pair_allocator_t> MyCopyBoostMap; -typedef flat_multimap - ,copy_pair_allocator_t> MyCopyBoostMultiMap; - - -//Test recursive structures -class recursive_flat_set -{ - public: - recursive_flat_set(const recursive_flat_set &c) - : id_(c.id_), flat_set_(c.flat_set_) - {} - - recursive_flat_set & operator =(const recursive_flat_set &c) - { - id_ = c.id_; - flat_set_= c.flat_set_; - return *this; - } - int id_; - flat_set flat_set_; - friend bool operator< (const recursive_flat_set &a, const recursive_flat_set &b) - { return a.id_ < b.id_; } -}; - - - -class recursive_flat_map -{ - public: - recursive_flat_map(const recursive_flat_map &c) - : id_(c.id_), map_(c.map_) - {} - - recursive_flat_map & operator =(const recursive_flat_map &c) - { - id_ = c.id_; - map_= c.map_; - return *this; - } - - int id_; - flat_map map_; - - friend bool operator< (const recursive_flat_map &a, const recursive_flat_map &b) - { return a.id_ < b.id_; } -}; - -//Test recursive structures -class recursive_flat_multiset -{ - public: - recursive_flat_multiset(const recursive_flat_multiset &c) - : id_(c.id_), flat_multiset_(c.flat_multiset_) - {} - - recursive_flat_multiset & operator =(const recursive_flat_multiset &c) - { - id_ = c.id_; - flat_multiset_= c.flat_multiset_; - return *this; - } - int id_; - flat_multiset flat_multiset_; - friend bool operator< (const recursive_flat_multiset &a, const recursive_flat_multiset &b) - { return a.id_ < b.id_; } -}; - -class recursive_flat_multimap -{ -public: - recursive_flat_multimap(const recursive_flat_multimap &c) - : id_(c.id_), map_(c.map_) - {} - - recursive_flat_multimap & operator =(const recursive_flat_multimap &c) - { - id_ = c.id_; - map_= c.map_; - return *this; - } - int id_; - flat_map map_; - friend bool operator< (const recursive_flat_multimap &a, const recursive_flat_multimap &b) - { return a.id_ < b.id_; } -}; - -template -void test_move() -{ - //Now test move semantics - C original; - C move_ctor(boost::move(original)); - C move_assign; - move_assign = boost::move(move_ctor); - 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); } -}; - -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() -{ - using namespace boost::container::test; - - //Allocator argument container - { - flat_set set_((std::allocator())); - flat_multiset multiset_((std::allocator())); - flat_map map_((std::allocator >())); - flat_multimap multimap_((std::allocator >())); - } - //Now test move semantics - { - test_move >(); - test_move >(); - test_move >(); - test_move >(); - } - - if(!flat_tree_ordered_insertion_test()){ - return 1; - } - - if (0 != set_test< - MyBoostSet - ,MyStdSet - ,MyBoostMultiSet - ,MyStdMultiSet>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != set_test_copyable< - MyBoostSet - ,MyStdSet - ,MyBoostMultiSet - ,MyStdMultiSet>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != set_test< - MyMovableBoostSet - ,MyStdSet - ,MyMovableBoostMultiSet - ,MyStdMultiSet>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != set_test< - MyMoveCopyBoostSet - ,MyStdSet - ,MyMoveCopyBoostMultiSet - ,MyStdMultiSet>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != set_test_copyable< - MyMoveCopyBoostSet - ,MyStdSet - ,MyMoveCopyBoostMultiSet - ,MyStdMultiSet>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != set_test< - MyCopyBoostSet - ,MyStdSet - ,MyCopyBoostMultiSet - ,MyStdMultiSet>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != set_test_copyable< - MyCopyBoostSet - ,MyStdSet - ,MyCopyBoostMultiSet - ,MyStdMultiSet>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != map_test< - MyBoostMap - ,MyStdMap - ,MyBoostMultiMap - ,MyStdMultiMap>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != map_test_copyable< - MyBoostMap - ,MyStdMap - ,MyBoostMultiMap - ,MyStdMultiMap>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != map_test< - MyMovableBoostMap - ,MyStdMap - ,MyMovableBoostMultiMap - ,MyStdMultiMap>()){ - return 1; - } - - if (0 != map_test< - MyMoveCopyBoostMap - ,MyStdMap - ,MyMoveCopyBoostMultiMap - ,MyStdMultiMap>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != map_test_copyable< - MyMoveCopyBoostMap - ,MyStdMap - ,MyMoveCopyBoostMultiMap - ,MyStdMultiMap>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != map_test< - MyCopyBoostMap - ,MyStdMap - ,MyCopyBoostMultiMap - ,MyStdMultiMap>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - if (0 != map_test_copyable< - MyCopyBoostMap - ,MyStdMap - ,MyCopyBoostMultiMap - ,MyStdMultiMap>()){ - std::cout << "Error in set_test" << std::endl; - return 1; - } - - 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, SetOptions>()) - return 1; - if(!boost::container::test::test_emplace, SetOptions>()) - return 1; - if(!boost::container::test::test_propagate_allocator()) - return 1; - - return 0; -} - -#include - diff --git a/test/heap_allocator_v1.hpp b/test/heap_allocator_v1.hpp deleted file mode 100644 index b6661d1..0000000 --- a/test/heap_allocator_v1.hpp +++ /dev/null @@ -1,158 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2005-2012. 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_HEAP_ALLOCATOR_V1_HPP -#define BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP - -#if (defined _MSC_VER) -# pragma once -#endif - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -//!\file -//!Describes an heap_allocator_v1 that allocates portions of fixed size -//!memory buffer (shared memory, mapped file...) - -namespace boost { -namespace container { -namespace test { - -//!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 -{ - private: - typedef heap_allocator_v1 self_t; - typedef SegmentManager segment_manager; - typedef typename segment_manager::void_pointer aux_pointer_t; - - typedef typename - boost::pointer_to_other - ::type cvoid_ptr; - - typedef typename boost::pointer_to_other - ::type alloc_ptr_t; - - template - heap_allocator_v1& operator=(const heap_allocator_v1&); - - heap_allocator_v1& operator=(const heap_allocator_v1&); - - alloc_ptr_t mp_mngr; - - public: - typedef T value_type; - typedef typename boost::pointer_to_other - ::type pointer; - typedef typename boost:: - pointer_to_other::type const_pointer; - typedef typename detail::add_reference - ::type reference; - typedef typename detail::add_reference - ::type const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - //!Obtains an heap_allocator_v1 of other type - template - struct rebind - { - typedef heap_allocator_v1 other; - }; - - //!Returns the segment manager. Never throws - segment_manager* get_segment_manager()const - { return detail::get_pointer(mp_mngr); } -/* - //!Returns address of mutable object. Never throws - pointer address(reference value) const - { return pointer(addressof(value)); } - - //!Returns address of non mutable object. Never throws - const_pointer address(const_reference value) const - { return const_pointer(addressof(value)); } -*/ - //!Constructor from the segment manager. Never throws - 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) - : mp_mngr(other.get_segment_manager()){ } - - //!Constructor from related heap_allocator_v1. Never throws - template - heap_allocator_v1(const heap_allocator_v1 &other) - : mp_mngr(other.get_segment_manager()){} - - //!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]; } - - //!Deallocates memory previously allocated. Never throws - void deallocate(const pointer &ptr, size_type) - { return ::delete[] detail::get_pointer(ptr) ; } - - //!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); } - - //!Destroys object. Throws if object's destructor throws - void destroy(const pointer &ptr) - { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); } - - //!Returns the number of elements that could be allocated. Never throws - size_type max_size() const - { return mp_mngr->get_size(); } - - //!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in - //!different memory segments, the result is undefined. - friend void swap(self_t &alloc1, self_t &alloc2) - { boost::container::boost::container::swap_dispatch(alloc1.mp_mngr, alloc2.mp_mngr); } -}; - -//!Equality test for same type of heap_allocator_v1 -template inline -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, - const heap_allocator_v1 &alloc2) - { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); } - -} //namespace test { -} //namespace container { -} //namespace boost { - -#include - -#endif //BOOST_CONTAINER_HEAP_ALLOCATOR_V1_HPP - diff --git a/test/input_from_forward_iterator.hpp b/test/input_from_forward_iterator.hpp index 348d144..ebc3973 100644 --- a/test/input_from_forward_iterator.hpp +++ b/test/input_from_forward_iterator.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/test/list_test.cpp b/test/list_test.cpp index c7198e7..ec9cc87 100644 --- a/test/list_test.cpp +++ b/test/list_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -10,6 +10,10 @@ #include #include +#include +#include +#include + #include "dummy_test_allocator.hpp" #include #include "movable_int.hpp" @@ -23,14 +27,29 @@ namespace boost { namespace container { //Explicit instantiation to detect compilation errors -template class boost::container::list >; +template class boost::container::list + < test::movable_and_copyable_int + , test::simple_allocator >; -template class boost::container::list >; +template class boost::container::list + < test::movable_and_copyable_int + , test::dummy_test_allocator >; -template class boost::container::list >; +template class boost::container::list + < test::movable_and_copyable_int + , std::allocator >; + +template class boost::container::list + < test::movable_and_copyable_int + , allocator >; + +template class boost::container::list + < test::movable_and_copyable_int + , adaptive_pool >; + +template class boost::container::list + < test::movable_and_copyable_int + , node_allocator >; namespace container_detail { @@ -43,12 +62,6 @@ template class iterator }} -typedef list MyList; - -typedef list MyMoveList; -typedef list MyCopyMoveList; -typedef list MyCopyList; - class recursive_list { public: @@ -67,6 +80,42 @@ void recursive_list_test()//Test for recursive types } } +template +struct GetAllocatorCont +{ + template + struct apply + { + typedef list< ValueType + , typename allocator_traits + ::template portable_rebind_alloc::type + > type; + }; +}; + +template +int test_cont_variants() +{ + typedef typename GetAllocatorCont::template apply::type MyCont; + typedef typename GetAllocatorCont::template apply::type MyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyCont; + + if(test::list_test()) + return 1; + if(test::list_test()) + return 1; + if(test::list_test()) + return 1; + if(test::list_test()) + return 1; + if(test::list_test()) + return 1; + + return 0; +} + + int main () { recursive_list_test(); @@ -78,17 +127,26 @@ int main () move_assign = boost::move(move_ctor); move_assign.swap(original); } - if(test::list_test()) - return 1; - if(test::list_test()) + if(test_cont_variants< std::allocator >()){ + std::cerr << "test_cont_variants< std::allocator > failed" << std::endl; return 1; + } - if(test::list_test()) + if(test_cont_variants< allocator >()){ + std::cerr << "test_cont_variants< allocator > failed" << std::endl; return 1; + } - if(test::list_test()) + if(test_cont_variants< node_allocator >()){ + std::cerr << "test_cont_variants< node_allocator > failed" << std::endl; return 1; + } + + if(test_cont_variants< adaptive_pool >()){ + std::cerr << "test_cont_variants< adaptive_pool > failed" << std::endl; + return 1; + } const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE); diff --git a/test/map_test.hpp b/test/map_test.hpp index 523eb37..2c6a7c9 100644 --- a/test/map_test.hpp +++ b/test/map_test.hpp @@ -37,7 +37,85 @@ template -int map_test () +int map_test_copyable(boost::container::container_detail::false_type) +{ return 0; } + +template +int map_test_copyable(boost::container::container_detail::true_type) +{ + typedef typename MyBoostMap::key_type IntType; + typedef container_detail::pair IntPairType; + typedef typename MyStdMap::value_type StdPairType; + + const int max = 100; + + BOOST_TRY{ + MyBoostMap *boostmap = new MyBoostMap; + MyStdMap *stdmap = new MyStdMap; + MyBoostMultiMap *boostmultimap = new MyBoostMultiMap; + MyStdMultiMap *stdmultimap = new MyStdMultiMap; + + int i; + for(i = 0; i < max; ++i){ + { + IntType i1(i), i2(i); + IntPairType intpair1(boost::move(i1), boost::move(i2)); + boostmap->insert(boost::move(intpair1)); + stdmap->insert(StdPairType(i, i)); + } + { + IntType i1(i), i2(i); + IntPairType intpair2(boost::move(i1), boost::move(i2)); + boostmultimap->insert(boost::move(intpair2)); + stdmultimap->insert(StdPairType(i, i)); + } + } + if(!CheckEqualContainers(boostmap, stdmap)) return 1; + if(!CheckEqualContainers(boostmultimap, stdmultimap)) return 1; + + { + //Now, test copy constructor + MyBoostMap boostmapcopy(*boostmap); + MyStdMap stdmapcopy(*stdmap); + MyBoostMultiMap boostmmapcopy(*boostmultimap); + MyStdMultiMap stdmmapcopy(*stdmultimap); + + if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy)) + return 1; + if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy)) + return 1; + + //And now assignment + boostmapcopy = *boostmap; + stdmapcopy = *stdmap; + boostmmapcopy = *boostmultimap; + stdmmapcopy = *stdmultimap; + + if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy)) + return 1; + if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy)) + return 1; + delete boostmap; + delete boostmultimap; + delete stdmap; + delete stdmultimap; + } + } + BOOST_CATCH(...){ + BOOST_RETHROW; + } + BOOST_CATCH_END + return 0; +} + +template +int map_test() { typedef typename MyBoostMap::key_type IntType; typedef container_detail::pair IntPairType; @@ -471,77 +549,11 @@ int map_test () BOOST_RETHROW; } BOOST_CATCH_END - return 0; -} -template -int map_test_copyable () -{ - typedef typename MyBoostMap::key_type IntType; - typedef container_detail::pair IntPairType; - typedef typename MyStdMap::value_type StdPairType; - - const int max = 100; - - BOOST_TRY{ - MyBoostMap *boostmap = new MyBoostMap; - MyStdMap *stdmap = new MyStdMap; - MyBoostMultiMap *boostmultimap = new MyBoostMultiMap; - MyStdMultiMap *stdmultimap = new MyStdMultiMap; - - int i; - for(i = 0; i < max; ++i){ - { - IntType i1(i), i2(i); - IntPairType intpair1(boost::move(i1), boost::move(i2)); - boostmap->insert(boost::move(intpair1)); - stdmap->insert(StdPairType(i, i)); - } - { - IntType i1(i), i2(i); - IntPairType intpair2(boost::move(i1), boost::move(i2)); - boostmultimap->insert(boost::move(intpair2)); - stdmultimap->insert(StdPairType(i, i)); - } + if(map_test_copyable + (container_detail::bool_::value>())){ + return 1; } - if(!CheckEqualContainers(boostmap, stdmap)) return 1; - if(!CheckEqualContainers(boostmultimap, stdmultimap)) return 1; - - { - //Now, test copy constructor - MyBoostMap boostmapcopy(*boostmap); - MyStdMap stdmapcopy(*stdmap); - MyBoostMultiMap boostmmapcopy(*boostmultimap); - MyStdMultiMap stdmmapcopy(*stdmultimap); - - if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy)) - return 1; - if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy)) - return 1; - - //And now assignment - boostmapcopy = *boostmap; - stdmapcopy = *stdmap; - boostmmapcopy = *boostmultimap; - stdmmapcopy = *stdmultimap; - - if(!CheckEqualContainers(&boostmapcopy, &stdmapcopy)) - return 1; - if(!CheckEqualContainers(&boostmmapcopy, &stdmmapcopy)) - return 1; - delete boostmap; - delete boostmultimap; - delete stdmap; - delete stdmultimap; - } - } - BOOST_CATCH(...){ - BOOST_RETHROW; - } - BOOST_CATCH_END return 0; } diff --git a/test/pair_test.cpp b/test/pair_test.cpp index 6b75b01..3560b74 100644 --- a/test/pair_test.cpp +++ b/test/pair_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/test/print_container.hpp b/test/print_container.hpp index a3de94e..1f7637d 100644 --- a/test/print_container.hpp +++ b/test/print_container.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/test/scoped_allocator_adaptor_test.cpp b/test/scoped_allocator_adaptor_test.cpp index f535a54..990f81e 100644 --- a/test/scoped_allocator_adaptor_test.cpp +++ b/test/scoped_allocator_adaptor_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // diff --git a/test/set_test.hpp b/test/set_test.hpp index a0a56e8..dea835f 100644 --- a/test/set_test.hpp +++ b/test/set_test.hpp @@ -1,6 +1,6 @@ //////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -25,6 +25,77 @@ namespace boost{ namespace container { namespace test{ +template +int set_test_copyable(boost::container::container_detail::false_type) +{ return 0; } + +template +int set_test_copyable(boost::container::container_detail::true_type) +{ + typedef typename MyBoostSet::value_type IntType; + const int max = 100; + + BOOST_TRY{ + MyBoostSet *boostset = new MyBoostSet; + MyStdSet *stdset = new MyStdSet; + MyBoostMultiSet *boostmultiset = new MyBoostMultiSet; + MyStdMultiSet *stdmultiset = new MyStdMultiSet; + + for(int i = 0; i < max; ++i){ + IntType move_me(i); + boostset->insert(boost::move(move_me)); + stdset->insert(i); + IntType move_me2(i); + boostmultiset->insert(boost::move(move_me2)); + stdmultiset->insert(i); + } + if(!CheckEqualContainers(boostset, stdset)) return 1; + if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1; + + { + //Now, test copy constructor + MyBoostSet boostsetcopy(*boostset); + MyStdSet stdsetcopy(*stdset); + + if(!CheckEqualContainers(&boostsetcopy, &stdsetcopy)) + return 1; + + MyBoostMultiSet boostmsetcopy(*boostmultiset); + MyStdMultiSet stdmsetcopy(*stdmultiset); + + if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy)) + return 1; + + //And now assignment + boostsetcopy = *boostset; + stdsetcopy = *stdset; + + if(!CheckEqualContainers(&boostsetcopy, &stdsetcopy)) + return 1; + + boostmsetcopy = *boostmultiset; + stdmsetcopy = *stdmultiset; + + if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy)) + return 1; + } + delete boostset; + delete boostmultiset; + } + BOOST_CATCH(...){ + BOOST_RETHROW; + } + BOOST_CATCH_END + return 0; +} + + template -int set_test_copyable () -{ - typedef typename MyBoostSet::value_type IntType; - const int max = 100; - - BOOST_TRY{ - //Shared memory allocator must be always be initialized - //since it has no default constructor - MyBoostSet *boostset = new MyBoostSet; - MyStdSet *stdset = new MyStdSet; - MyBoostMultiSet *boostmultiset = new MyBoostMultiSet; - MyStdMultiSet *stdmultiset = new MyStdMultiSet; - - for(int i = 0; i < max; ++i){ - IntType move_me(i); - boostset->insert(boost::move(move_me)); - stdset->insert(i); - IntType move_me2(i); - boostmultiset->insert(boost::move(move_me2)); - stdmultiset->insert(i); - } - if(!CheckEqualContainers(boostset, stdset)) return 1; - if(!CheckEqualContainers(boostmultiset, stdmultiset)) return 1; - - { - //Now, test copy constructor - MyBoostSet boostsetcopy(*boostset); - MyStdSet stdsetcopy(*stdset); - - if(!CheckEqualContainers(&boostsetcopy, &stdsetcopy)) - return 1; - - MyBoostMultiSet boostmsetcopy(*boostmultiset); - MyStdMultiSet stdmsetcopy(*stdmultiset); - - if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy)) - return 1; - - //And now assignment - boostsetcopy = *boostset; - stdsetcopy = *stdset; - - if(!CheckEqualContainers(&boostsetcopy, &stdsetcopy)) - return 1; - - boostmsetcopy = *boostmultiset; - stdmsetcopy = *stdmultiset; - - if(!CheckEqualContainers(&boostmsetcopy, &stdmsetcopy)) - return 1; - } - delete boostset; - delete boostmultiset; + if(set_test_copyable + (container_detail::bool_::value>())){ + return 1; } - BOOST_CATCH(...){ - BOOST_RETHROW; - } - BOOST_CATCH_END + return 0; } diff --git a/test/slist_test.cpp b/test/slist_test.cpp index 785bcc2..5fd6520 100644 --- a/test/slist_test.cpp +++ b/test/slist_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -9,6 +9,10 @@ ////////////////////////////////////////////////////////////////////////////// #include #include +#include +#include +#include + #include #include "dummy_test_allocator.hpp" #include "movable_int.hpp" @@ -22,22 +26,32 @@ namespace boost { namespace container { //Explicit instantiation to detect compilation errors -template class boost::container::slist >; +template class boost::container::slist + < test::movable_and_copyable_int + , test::simple_allocator >; -template class boost::container::slist >; +template class boost::container::slist + < test::movable_and_copyable_int + , test::dummy_test_allocator >; -template class boost::container::slist >; +template class boost::container::slist + < test::movable_and_copyable_int + , std::allocator >; + +template class boost::container::slist + < test::movable_and_copyable_int + , allocator >; + +template class boost::container::slist + < test::movable_and_copyable_int + , adaptive_pool >; + +template class boost::container::slist + < test::movable_and_copyable_int + , node_allocator >; }} -typedef slist MyList; -typedef slist MyMoveList; -typedef slist MyCopyMoveList; -typedef slist MyCopyList; - class recursive_slist { public: @@ -52,6 +66,42 @@ void recursive_slist_test()//Test for recursive types slist recursive_list_list; } +template +struct GetAllocatorCont +{ + template + struct apply + { + typedef slist< ValueType + , typename allocator_traits + ::template portable_rebind_alloc::type + > type; + }; +}; + +template +int test_cont_variants() +{ + typedef typename GetAllocatorCont::template apply::type MyCont; + typedef typename GetAllocatorCont::template apply::type MyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyCont; + + if(test::list_test()) + return 1; + if(test::list_test()) + return 1; + if(test::list_test()) + return 1; + if(test::list_test()) + return 1; + if(test::list_test()) + return 1; + + return 0; +} + + int main () { recursive_slist_test(); @@ -71,17 +121,25 @@ int main () } } - if(test::list_test()) + if(test_cont_variants< std::allocator >()){ + std::cerr << "test_cont_variants< std::allocator > failed" << std::endl; return 1; + } - if(test::list_test()) + if(test_cont_variants< allocator >()){ + std::cerr << "test_cont_variants< allocator > failed" << std::endl; return 1; + } - if(test::list_test()) + if(test_cont_variants< node_allocator >()){ + std::cerr << "test_cont_variants< node_allocator > failed" << std::endl; return 1; + } - if(test::list_test()) + if(test_cont_variants< adaptive_pool >()){ + std::cerr << "test_cont_variants< adaptive_pool > failed" << std::endl; return 1; + } const test::EmplaceOptions Options = (test::EmplaceOptions) (test::EMPLACE_FRONT | test::EMPLACE_AFTER | test::EMPLACE_BEFORE | test::EMPLACE_AFTER); diff --git a/test/stable_vector_test.cpp b/test/stable_vector_test.cpp index 6390d7e..2f86f16 100644 --- a/test/stable_vector_test.cpp +++ b/test/stable_vector_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -16,6 +16,10 @@ #include #include +#include +#include +#include + #include "check_equal_containers.hpp" #include "movable_int.hpp" #include "expand_bwd_test_allocator.hpp" @@ -23,6 +27,7 @@ #include "dummy_test_allocator.hpp" #include "propagate_allocator_test.hpp" #include "vector_test.hpp" +#include "default_init_test.hpp" using namespace boost::container; @@ -39,6 +44,18 @@ template class stable_vector >; +template class stable_vector + < test::movable_and_copyable_int + , allocator >; + +template class stable_vector + < test::movable_and_copyable_int + , adaptive_pool >; + +template class stable_vector + < test::movable_and_copyable_int + , node_allocator >; + namespace stable_vector_detail{ template class iterator; @@ -66,34 +83,37 @@ void recursive_vector_test()//Test for recursive types } } -bool default_init_test()//Test for default initialization +template +struct GetAllocatorCont { - typedef stable_vector > svector_t; - - const std::size_t Capacity = 100; - + template + struct apply { - test::default_init_allocator::reset_pattern(0); - svector_t v(Capacity, default_init); - svector_t::iterator it = v.begin(); - //Compare with the pattern - for(std::size_t i = 0; i != Capacity; ++i, ++it){ - if(*it != static_cast(i)) - return false; - } - } - { - test::default_init_allocator::reset_pattern(100); - svector_t v; - v.resize(Capacity, default_init); - svector_t::iterator it = v.begin(); - //Compare with the pattern - for(std::size_t i = 0; i != Capacity; ++i, ++it){ - if(*it != static_cast(i+100)) - return false; - } - } - return true; + typedef stable_vector< ValueType + , typename allocator_traits + ::template portable_rebind_alloc::type + > type; + }; +}; + +template +int test_cont_variants() +{ + typedef typename GetAllocatorCont::template apply::type MyCont; + typedef typename GetAllocatorCont::template apply::type MyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyCont; + + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + + return 0; } int main() @@ -115,22 +135,26 @@ int main() sv.resize(10); sv.resize(1); } - typedef stable_vector MyVector; - typedef stable_vector MyMoveVector; - typedef stable_vector MyCopyMoveVector; - typedef stable_vector MyCopyVector; - if(test::vector_test()) + if(test_cont_variants< std::allocator >()){ + std::cerr << "test_cont_variants< std::allocator > failed" << std::endl; return 1; + } - if(test::vector_test()) + if(test_cont_variants< allocator >()){ + std::cerr << "test_cont_variants< allocator > failed" << std::endl; return 1; + } - if(test::vector_test()) + if(test_cont_variants< node_allocator >()){ + std::cerr << "test_cont_variants< node_allocator > failed" << std::endl; return 1; + } - if(test::vector_test()) + if(test_cont_variants< adaptive_pool >()){ + std::cerr << "test_cont_variants< adaptive_pool > failed" << std::endl; return 1; + } if(!test::default_init_test< stable_vector > >()){ std::cerr << "Default init test failed" << std::endl; diff --git a/test/string_test.cpp b/test/string_test.cpp index f68482d..88bc0c2 100644 --- a/test/string_test.cpp +++ b/test/string_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -23,6 +23,7 @@ #include "expand_bwd_test_allocator.hpp" #include "expand_bwd_test_template.hpp" #include "propagate_allocator_test.hpp" +#include "default_init_test.hpp" using namespace boost::container; @@ -137,7 +138,6 @@ int string_test() const int MaxSize = 100; - //Create shared memory { BoostStringVector *boostStringVect = new BoostStringVector; StdStringVector *stdStringVect = new StdStringVector; @@ -477,6 +477,16 @@ int main() if(!boost::container::test::test_propagate_allocator()) return 1; + if(!test::default_init_test< basic_string, test::default_init_allocator > >()){ + std::cerr << "Default init test failed" << std::endl; + return 1; + } + + if(!test::default_init_test< basic_string, test::default_init_allocator > >()){ + std::cerr << "Default init test failed" << std::endl; + return 1; + } + return 0; } diff --git a/test/tree_test.cpp b/test/tree_test.cpp deleted file mode 100644 index 60d593f..0000000 --- a/test/tree_test.cpp +++ /dev/null @@ -1,380 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// -// (C) Copyright Ion Gaztanaga 2004-2012. 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 "print_container.hpp" -#include "movable_int.hpp" -#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; - -//Alias standard types -typedef std::set MyStdSet; -typedef std::multiset MyStdMultiSet; -typedef std::map MyStdMap; -typedef std::multimap MyStdMultiMap; - -//Alias non-movable types -typedef set MyBoostSet; -typedef multiset MyBoostMultiSet; -typedef map MyBoostMap; -typedef multimap MyBoostMultiMap; - -//Alias movable types -typedef set MyMovableBoostSet; -typedef multiset MyMovableBoostMultiSet; -typedef map MyMovableBoostMap; -typedef multimap MyMovableBoostMultiMap; -typedef set MyMoveCopyBoostSet; -typedef set MyCopyBoostSet; -typedef multiset MyMoveCopyBoostMultiSet; -typedef multiset MyCopyBoostMultiSet; -typedef map MyMoveCopyBoostMap; -typedef multimap MyMoveCopyBoostMultiMap; -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) - { return a.id_ < b.id_; } -}; - -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) - { return a.id_ < b.id_; } -}; - -//Test recursive structures -class recursive_multiset -{ - 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) - { return a.id_ < b.id_; } -}; - -class recursive_multimap -{ - 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) - { return a.id_ < b.id_; } -}; - -template -void test_move() -{ - //Now test move semantics - C original; - original.emplace(); - C move_ctor(boost::move(original)); - C move_assign; - move_assign.emplace(); - move_assign = boost::move(move_ctor); - 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 - { - set set_; - multiset multiset_; - map map_; - multimap multimap_; - } - //Allocator argument container - { - set set_((std::allocator())); - multiset multiset_((std::allocator())); - map map_((std::allocator >())); - multimap multimap_((std::allocator >())); - } - //Now test move semantics - { - test_move >(); - test_move >(); - test_move >(); - test_move >(); - } - - - if(0 != test::set_test()){ - return 1; - } - - if(0 != test::set_test_copyable()){ - return 1; - } - - if(0 != test::set_test()){ - return 1; - } - - if(0 != test::set_test()){ - return 1; - } - - if(0 != test::set_test_copyable()){ - return 1; - } - - if(0 != test::set_test()){ - return 1; - } - - if(0 != test::set_test_copyable()){ - return 1; - } - - if (0 != test::map_test()){ - return 1; - } - - if(0 != test::map_test_copyable()){ - return 1; - } - - if (0 != test::map_test()){ - return 1; - } - - if (0 != test::map_test()){ - return 1; - } - - if (0 != test::map_test_copyable()){ - return 1; - } - - if (0 != test::map_test()){ - return 1; - } - - if (0 != test::map_test_copyable()){ - return 1; - } - - const test::EmplaceOptions SetOptions = (test::EmplaceOptions)(test::EMPLACE_HINT | test::EMPLACE_ASSOC); - if(!boost::container::test::test_emplace, SetOptions>()) - return 1; - if(!boost::container::test::test_emplace, SetOptions>()) - return 1; - 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_propagate_allocator()) - return 1; - - return 0; -} - -#include diff --git a/test/vector_test.cpp b/test/vector_test.cpp index 80417c3..6561041 100644 --- a/test/vector_test.cpp +++ b/test/vector_test.cpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -15,6 +15,10 @@ #include #include +#include +#include +#include + #include #include "check_equal_containers.hpp" #include "movable_int.hpp" @@ -23,6 +27,7 @@ #include "dummy_test_allocator.hpp" #include "propagate_allocator_test.hpp" #include "vector_test.hpp" +#include "default_init_test.hpp" using namespace boost::container; @@ -30,14 +35,29 @@ namespace boost { namespace container { //Explicit instantiation to detect compilation errors -template class boost::container::vector >; +template class boost::container::vector + < test::movable_and_copyable_int + , test::simple_allocator >; -template class boost::container::vector >; +template class boost::container::vector + < test::movable_and_copyable_int + , test::dummy_test_allocator >; -template class boost::container::vector >; +template class boost::container::vector + < test::movable_and_copyable_int + , std::allocator >; + +template class boost::container::vector + < test::movable_and_copyable_int + , allocator >; + +template class boost::container::vector + < test::movable_and_copyable_int + , adaptive_pool >; + +template class boost::container::vector + < test::movable_and_copyable_int + , node_allocator >; namespace container_detail { @@ -104,6 +124,39 @@ enum Test zero, one, two, three, four, five, six }; +template +struct GetAllocatorCont +{ + template + struct apply + { + typedef vector< ValueType + , typename allocator_traits + ::template portable_rebind_alloc::type + > type; + }; +}; + +template +int test_cont_variants() +{ + typedef typename GetAllocatorCont::template apply::type MyCont; + typedef typename GetAllocatorCont::template apply::type MyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyMoveCont; + typedef typename GetAllocatorCont::template apply::type MyCopyCont; + + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + if(test::vector_test()) + return 1; + + return 0; +} + int main() { { @@ -135,33 +188,44 @@ int main() move_assign = boost::move(move_ctor); move_assign.swap(original); } - typedef vector MyVector; - typedef vector MyMoveVector; - typedef vector MyCopyMoveVector; - typedef vector MyCopyVector; - typedef vector MyEnumVector; - if(test::vector_test()) + if(test_cont_variants< std::allocator >()){ + std::cerr << "test_cont_variants< std::allocator > failed" << std::endl; return 1; - if(test::vector_test()) + } + + if(test_cont_variants< allocator >()){ + std::cerr << "test_cont_variants< allocator > failed" << std::endl; return 1; - if(test::vector_test()) + } + + if(test_cont_variants< node_allocator >()){ + std::cerr << "test_cont_variants< node_allocator > failed" << std::endl; return 1; - if(test::vector_test()) + } + + if(test_cont_variants< adaptive_pool >()){ + std::cerr << "test_cont_variants< adaptive_pool > failed" << std::endl; return 1; + } + + { + typedef vector > MyEnumCont; + MyEnumCont v; + Test t; + v.push_back(t); + v.push_back(::boost::move(t)); + v.push_back(Test()); + } + if(test_expand_bwd()) return 1; + if(!test::default_init_test< vector > >()){ std::cerr << "Default init test failed" << std::endl; return 1; } - MyEnumVector v; - Test t; - v.push_back(t); - v.push_back(::boost::move(t)); - v.push_back(Test()); - const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_BEFORE); if(!boost::container::test::test_emplace< vector, Options>()){ return 1; diff --git a/test/vector_test.hpp b/test/vector_test.hpp index 0eb229b..c3e92e6 100644 --- a/test/vector_test.hpp +++ b/test/vector_test.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -38,123 +38,6 @@ namespace boost{ namespace container { namespace test{ -// -template -class default_init_allocator_base -{ - protected: - static unsigned char s_pattern; - static bool s_ascending; - - public: - static void reset_pattern(unsigned char value) - { s_pattern = value; } - - static void set_ascending(bool enable) - { s_ascending = enable; } -}; - -template -unsigned char default_init_allocator_base::s_pattern = 0u; - -template -bool default_init_allocator_base::s_ascending = true; - -template -class default_init_allocator - : public default_init_allocator_base<0> -{ - typedef default_init_allocator_base<0> base_t; - public: - typedef T value_type; - - default_init_allocator() - {} - - template - default_init_allocator(default_init_allocator) - {} - - T* allocate(std::size_t n) - { - //Initialize memory to a pattern - const std::size_t max = sizeof(T)*n; - unsigned char *puc_raw = ::new unsigned char[max]; - - if(base_t::s_ascending){ - for(std::size_t i = 0; i != max; ++i){ - puc_raw[i] = static_cast(s_pattern++); - } - } - else{ - for(std::size_t i = 0; i != max; ++i){ - puc_raw[i] = static_cast(s_pattern--); - } - } - return (T*)puc_raw;; - } - - void deallocate(T *p, std::size_t) - { delete[] (unsigned char*)p; } -}; - -template -inline bool check_ascending_byte_pattern(const T&t) -{ - const unsigned char *pch = &reinterpret_cast(t); - const std::size_t max = sizeof(T); - for(std::size_t i = 1; i != max; ++i){ - if( (pch[i-1] != ((unsigned char)(pch[i]-1u))) ){ - return false; - } - } - return true; -} - -template -inline bool check_descending_byte_pattern(const T&t) -{ - const unsigned char *pch = &reinterpret_cast(t); - const std::size_t max = sizeof(T); - for(std::size_t i = 1; i != max; ++i){ - if( (pch[i-1] != ((unsigned char)(pch[i]+1u))) ){ - return false; - } - } - return true; -} - -template -bool default_init_test()//Test for default initialization -{ - const std::size_t Capacity = 100; - - { - test::default_init_allocator::reset_pattern(0); - test::default_init_allocator::set_ascending(true); - IntDefaultInitAllocVector v(Capacity, default_init); - typename IntDefaultInitAllocVector::iterator it = v.begin(); - //Compare with the pattern - for(std::size_t i = 0; i != Capacity; ++i, ++it){ - if(!test::check_ascending_byte_pattern(*it)) - return false; - } - } - { - test::default_init_allocator::reset_pattern(100); - test::default_init_allocator::set_ascending(false); - IntDefaultInitAllocVector v; - v.resize(Capacity, default_init); - typename IntDefaultInitAllocVector::iterator it = v.begin(); - //Compare with the pattern - for(std::size_t i = 0; i != Capacity; ++i, ++it){ - if(!test::check_descending_byte_pattern(*it)) - return false; - } - } - return true; -} - template bool vector_copyable_only(V1 *, V2 *, boost::container::container_detail::false_type) {