- Add configuration options to vector

- Cleanup tree configuration options
This commit is contained in:
Ion Gaztañaga
2017-12-10 23:33:41 +01:00
parent 82abe673fc
commit 2802a1f50d
26 changed files with 1122 additions and 511 deletions

View File

@ -40,7 +40,8 @@ doxygen autodoc
\"BOOST_RV_REF_END_IF_CXX11=&&\" \\ \"BOOST_RV_REF_END_IF_CXX11=&&\" \\
\"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\ \"BOOST_COPY_ASSIGN_REF(T)=const T &\" \\
\"BOOST_FWD_REF(a)=a &&\" \\ \"BOOST_FWD_REF(a)=a &&\" \\
\"BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) = template<TYPE VALUE> struct OPTION_NAME{};\" \\ \"BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) = template<TYPE VALUE> struct OPTION_NAME{};\" \\
\"BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) = template<class TYPE> struct OPTION_NAME{};\" \\
\"BOOST_CONTAINER_DOC1ST(T1, T2)=T1\" \\ \"BOOST_CONTAINER_DOC1ST(T1, T2)=T1\" \\
\"BOOST_CONTAINER_DOCIGN(T) \"\\ \"BOOST_CONTAINER_DOCIGN(T) \"\\
\"BOOST_CONTAINER_DOCONLY(T)=T\"\\ \"BOOST_CONTAINER_DOCONLY(T)=T\"\\

View File

@ -8,7 +8,7 @@
[library Boost.Container [library Boost.Container
[quickbook 1.5] [quickbook 1.5]
[authors [Gaztanaga, Ion]] [authors [Gaztanaga, Ion]]
[copyright 2009-2015 Ion Gaztanaga] [copyright 2009-2017 Ion Gaztanaga]
[id container] [id container]
[dirname container] [dirname container]
[purpose Containers library] [purpose Containers library]
@ -31,10 +31,13 @@ that don't comply with the latest C++ standard.
In short, what does [*Boost.Container] offer? In short, what does [*Boost.Container] offer?
* Move semantics are implemented, including move emulation for pre-C++11 compilers. * Emplacement and move semantics are implemented, including emulation for pre-C++11 compilers.
* New advanced features (e.g. placement insertion, recursive containers) are present. * Polymorphic allocators and memory resources, including implementation and emulation for pre-C++17 compilers
* New advanced features (e.g. recursive containers, configuration options for containers) are present.
* Containers support stateful allocators and are compatible with [*Boost.Interprocess] * Containers support stateful allocators and are compatible with [*Boost.Interprocess]
(they can be safely placed in shared memory). (they can be safely placed in shared memory).
* Users obtain a more uniform performance across all plataforms,
including [link container.main_features.scary_iterators SCARY iterators].
* The library offers new useful containers: * The library offers new useful containers:
* [classref boost::container::flat_map flat_map], * [classref boost::container::flat_map flat_map],
[classref boost::container::flat_set flat_set], [classref boost::container::flat_set flat_set],
@ -44,6 +47,12 @@ In short, what does [*Boost.Container] offer?
searches. searches.
* [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid * [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid
container: vector-like random-access iterators and list-like iterator stability in insertions and erasures. container: vector-like random-access iterators and list-like iterator stability in insertions and erasures.
* [classref boost::container::static_vector static_vector ]: a vector-like container that internally embeds
(statically allocates) all needed memory up to the maximum capacity. Maximum capacity can't be increased and
it's specified at compile time.
* [classref boost::container::small_vector small_vector ]: a vector-like container that internally embeds
(statically allocates) a minimum amount of memory, but dynamically allocates elements when capacity
has to be increased. This minimum capacity is specified at compile time.
* [classref boost::container::slist slist]: the classic pre-standard singly linked list implementation * [classref boost::container::slist slist]: the classic pre-standard singly linked list implementation
offering constant-time `size()`. Note that C++11 `forward_list` has no `size()`. offering constant-time `size()`. Note that C++11 `forward_list` has no `size()`.
@ -159,9 +168,11 @@ unless specifically allowed for that component]].
Fortunately all [*Boost.Container] containers except Fortunately all [*Boost.Container] containers except
[classref boost::container::static_vector static_vector] and [classref boost::container::static_vector static_vector] and
[classref boost::container::small_vector small_vector] and
[classref boost::container::basic_string basic_string] are designed to support incomplete types. [classref boost::container::basic_string basic_string] are designed to support incomplete types.
[classref boost::container::static_vector static_vector] is special because [classref boost::container::static_vector static_vector] and
it statically allocates memory for `value_type` and this requires complete types and [classref boost::container::small_vector small_vector] are special because
they statically allocates memory for `value_type` and this requires complete types.
[classref boost::container::basic_string basic_string] implements Small String Optimization which [classref boost::container::basic_string basic_string] implements Small String Optimization which
also requires complete types. also requires complete types.
@ -533,7 +544,7 @@ stateful allocators, etc.
[endsect] [endsect]
[section:extended_functionality Extended functionality] [section:extended_functionality Extended functionality: Basic extensions]
[section:default_initialialization Default initialization for vector-like containers] [section:default_initialialization Default initialization for vector-like containers]
@ -569,46 +580,6 @@ times.
[endsect] [endsect]
[section:configurable_tree_based_associative_containers Configurable tree-based associative ordered containers]
[classref boost::container::set set], [classref boost::container::multiset multiset],
[classref boost::container::map map] and [classref boost::container::multimap multimap] associative containers
are implemented as binary search trees which offer the needed complexity and stability guarantees required by the
C++ standard for associative containers.
[*Boost.Container] offers the possibility to configure at compile time some parameters of the binary search tree
implementation. This configuration is passed as the last template parameter and defined using the utility class
[classref boost::container::tree_assoc_options tree_assoc_options].
The following parameters can be configured:
* The underlying [*tree implementation] type ([classref boost::container::tree_type tree_type]).
By default these containers use a red-black tree but the user can use other tree types:
* [@http://en.wikipedia.org/wiki/Red%E2%80%93black_tree Red-Black Tree]
* [@http://en.wikipedia.org/wiki/Avl_trees AVL tree]
* [@http://en.wikipedia.org/wiki/Scapegoat_tree Scapegoat tree]. In this case Insertion and Deletion
are amortized O(log n) instead of O(log n).
* [@http://en.wikipedia.org/wiki/Splay_tree Splay tree]. In this case Searches, Insertions and Deletions
are amortized O(log n) instead of O(log n).
* Whether the [*size saving] mechanisms are used to implement the tree nodes
([classref boost::container::optimize_size optimize_size]). By default this option is activated and is only
meaningful to red-black and avl trees (in other cases, this option will be ignored).
This option will try to put rebalancing metadata inside the "parent" pointer of the node if the pointer
type has enough alignment. Usually, due to alignment issues, the metadata uses the size of a pointer yielding
to four pointer size overhead per node, whereas activating this option usually leads to 3 pointer size overhead.
Although some mask operations must be performed to extract
data from this special "parent" pointer, in several systems this option also improves performance due to the
improved cache usage produced by the node size reduction.
See the following example to see how [classref boost::container::tree_assoc_options tree_assoc_options] can be
used to customize these containers:
[import ../example/doc_custom_tree.cpp]
[doc_custom_tree]
[endsect]
[section:constant_time_range_splice Constant-time range splice for `(s)list`] [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, In the first C++ standard `list::size()` was not required to be constant-time,
@ -647,7 +618,81 @@ then the operation is constant time, even with an O(1) size.
[endsect] [endsect]
[section:extended_allocators Extended allocators] [endsect]
[section:configurable_containers Extended functionality: Configurable containers]
[section:configurable_tree_based_associative_containers Configurable tree-based associative ordered containers]
[classref boost::container::set set], [classref boost::container::multiset multiset],
[classref boost::container::map map] and [classref boost::container::multimap multimap] associative containers
are implemented as binary search trees which offer the needed complexity and stability guarantees required by the
C++ standard for associative containers.
[*Boost.Container] offers the possibility to configure at compile time some parameters of the binary search tree
implementation. This configuration is passed as the last template parameter and defined using the utility class
[classref boost::container::tree_assoc_options tree_assoc_options]. The following parameters can be configured:
* The underlying [*tree implementation] type ([classref boost::container::tree_type tree_type]).
By default these containers use a red-black tree but the user can use other tree types:
* [@http://en.wikipedia.org/wiki/Red%E2%80%93black_tree Red-Black Tree]
* [@http://en.wikipedia.org/wiki/Avl_trees AVL tree]
* [@http://en.wikipedia.org/wiki/Scapegoat_tree Scapegoat tree]. In this case Insertion and Deletion
are amortized O(log n) instead of O(log n).
* [@http://en.wikipedia.org/wiki/Splay_tree Splay tree]. In this case Searches, Insertions and Deletions
are amortized O(log n) instead of O(log n).
* Whether the [*size saving] mechanisms are used to implement the tree nodes
([classref boost::container::optimize_size optimize_size]). By default this option is activated and is only
meaningful to red-black and avl trees (in other cases, this option will be ignored).
This option will try to put rebalancing metadata inside the "parent" pointer of the node if the pointer
type has enough alignment. Usually, due to alignment issues, the metadata uses the size of a pointer yielding
to four pointer size overhead per node, whereas activating this option usually leads to 3 pointer size overhead.
Although some mask operations must be performed to extract
data from this special "parent" pointer, in several systems this option also improves performance due to the
improved cache usage produced by the node size reduction.
See the following example to see how [classref boost::container::tree_assoc_options tree_assoc_options] can be
used to customize these containers:
[import ../example/doc_custom_tree.cpp]
[doc_custom_tree]
[endsect]
[section:configurable_vectors Configurable vectors]
[*Boost.Container] offers the possibility to configure at compile time some parameters of
[classref boost::container::vector vector] implementation. This configuration is passed as
the last template parameter and defined using the utility class
[classref boost::container::vector_options vector_options]. The following parameters can be configured:
* [classref boost::container::growth_factor growth_factor]: the growth policy of the vector.
The rate at which the capacity of a vector grows is implementation dependent and
implementations choose exponential growth in order to meet the amortized constant time requirement for push_back.
A higher growth factor will make it faster as it will require less data movement, but it will have a greater memory
impact (on average, more memory will be unused). A user can provide it's own implementation and some predefined
policies are available: [classref boost::container::growth_factor_50 growth_factor_50],
[classref boost::container::growth_factor_60 growth_factor_60] and
[classref boost::container::growth_factor_50 growth_factor_100].
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
parameters inside of the vector. Sometimes, when the maximum capacity to be used is much less than the
theoretical maximum that a vector can hold, it's interesting to use smaller unsigned integer types to represent
`size()` and `capacity()` inside vector, so that the size of an empty vector is minimized and cache
performance might be improved. See [classref boost::container::stored_size stored_size] for more details.
See the following example to see how [classref boost::container::vector_options vector_options] can be
used to customize `vector` container:
[import ../example/doc_custom_vector.cpp]
[doc_custom_vector]
[endsect]
[endsect]
[section:extended_allocators Extended functionality: Extended allocators]
Many C++ programmers have ever wondered where does good old realloc fit in C++. And that's a good question. 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 Could we improve [classref boost::container::vector vector] performance using memory expansion mechanisms
@ -700,7 +745,7 @@ Use them simply specifying the new allocator in the corresponding template argum
[endsect] [endsect]
[section:polymorphic_memory_resources Polymorphic Memory Resources ] [section:polymorphic_memory_resources Extended Functionality: Polymorphic Memory Resources ]
The document The document
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html C++ Extensions for Library Fundamentals (Final draft: N4480)] [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html C++ Extensions for Library Fundamentals (Final draft: N4480)]
@ -818,31 +863,6 @@ type-erasured allocator-capable classes even in C++03 compilers.
[endsect] [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
/
/STL containers offer a `get_allocator()` member to obtain a copy of the allocator that
/the container is using to allocate and construct elements. For performance reasons, some
/applications need o
/
/http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html
/
/a__endsect__a
/]
[endsect]
[section:Cpp11_conformance C++11/C++14 Conformance] [section:Cpp11_conformance C++11/C++14 Conformance]
[*Boost.Container] aims for full C++11 conformance except reasoned deviations, [*Boost.Container] aims for full C++11 conformance except reasoned deviations,
@ -1212,6 +1232,13 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes Release Notes] [section:release_notes Release Notes]
[section:release_notes_boost_1_67_00 Boost 1.67 Release]
* ['vector] can now have options, using [classref boost::container::vector_options vector_options].
The growth factor and the stored size type can be specified.
[endsect]
[section:release_notes_boost_1_66_00 Boost 1.66 Release] [section:release_notes_boost_1_66_00 Boost 1.66 Release]
* ['flat_[multi]map/set] can now work as container adaptors, as proposed in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0429r1.pdf P0429R1]. * ['flat_[multi]map/set] can now work as container adaptors, as proposed in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0429r1.pdf P0429R1].
@ -1362,7 +1389,7 @@ use [*Boost.Container]? There are several reasons for that:
* Added DlMalloc-based [link container.extended_functionality.extended_allocators Extended Allocators]. * Added DlMalloc-based [link container.extended_functionality.extended_allocators Extended Allocators].
* [link container.extended_functionality.configurable_tree_based_associative_containers Improved configurability] * [link container.extended_functionality.configurable_containers.configurable_tree_based_associative_containers Improved configurability]
of tree-based ordered associative containers. AVL, Scapegoat and Splay trees are now available of tree-based ordered associative containers. AVL, Scapegoat and Splay trees are now available
to implement [classref boost::container::set set], [classref boost::container::multiset multiset], to implement [classref boost::container::set set], [classref boost::container::multiset multiset],
[classref boost::container::map map] and [classref boost::container::multimap multimap]. [classref boost::container::map map] and [classref boost::container::multimap multimap].

View File

@ -0,0 +1,54 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2013-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.
//
//////////////////////////////////////////////////////////////////////////////
//[doc_custom_vector
#include <boost/container/vector.hpp>
#include <boost/static_assert.hpp>
//Make sure assertions are active
#ifdef NDEBUG
#undef NDEBUG
#endif
#include <cassert>
int main ()
{
using namespace boost::container;
//This option specifies that a vector that will use "unsigned char" as
//the type to store capacity or size internally.
typedef vector_options< stored_size<unsigned char> >::type size_option_t;
//Size-optimized vector is smaller than the default one.
typedef vector<int, new_allocator<int>, size_option_t > size_optimized_vector_t;
BOOST_STATIC_ASSERT(( sizeof(size_optimized_vector_t) < sizeof(vector<int>) ));
//Requesting capacity for more elements than representable by "unsigned char"
//is an error in the size optimized vector.
bool exception_thrown = false;
try { size_optimized_vector_t v(256); }
catch(...){ exception_thrown = true; }
assert(exception_thrown == true);
//This option specifies that a vector will increase its capacity 50%
//each time the previous capacity was exhausted.
typedef vector_options< growth_factor<growth_factor_50> >::type growth_50_option_t;
//Fill the vector until full capacity is reached
vector<int, new_allocator<int>, growth_50_option_t > growth_50_vector(5, 0);
const std::size_t old_cap = growth_50_vector.capacity();
growth_50_vector.resize(old_cap);
//Now insert an additional item and check the new buffer is 50% bigger
growth_50_vector.push_back(1);
assert(growth_50_vector.capacity() == old_cap*3/2);
return 0;
}
//]

View File

@ -88,23 +88,14 @@ namespace boost{ namespace container{ namespace pmr{
namespace boost { namespace boost {
namespace container { namespace container {
//! Enumeration used to configure ordered associative containers
//! with a concrete tree implementation.
enum tree_type_enum
{
red_black_tree,
avl_tree,
scapegoat_tree,
splay_tree
};
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
template<class T> template<class T>
class new_allocator; class new_allocator;
template <class T template <class T
,class Allocator = new_allocator<T> > ,class Allocator = new_allocator<T>
,class Options = void>
class vector; class vector;
template <class T template <class T
@ -130,35 +121,30 @@ template <class T
,class Allocator = new_allocator<T> > ,class Allocator = new_allocator<T> >
class slist; class slist;
template<tree_type_enum TreeType, bool OptimizeSize>
struct tree_opt;
typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Allocator = new_allocator<Key> ,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults > ,class Options = void>
class set; class set;
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Allocator = new_allocator<Key> ,class Allocator = new_allocator<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
class multiset; class multiset;
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Allocator = new_allocator<std::pair<const Key, T> > ,class Allocator = new_allocator<std::pair<const Key, T> >
,class Options = tree_assoc_defaults > ,class Options = void >
class map; class map;
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Allocator = new_allocator<std::pair<const Key, T> > ,class Allocator = new_allocator<std::pair<const Key, T> >
,class Options = tree_assoc_defaults > ,class Options = void >
class multimap; class multimap;
template <class Key template <class Key
@ -246,13 +232,6 @@ class synchronized_pool_resource;
} //namespace pmr { } //namespace pmr {
#else
//! Default options for tree-based associative containers
//! - tree_type<red_black_tree>
//! - optimize_size<true>
typedef implementation_defined tree_assoc_defaults;
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
//! Type used to tag that the input range is //! Type used to tag that the input range is

View File

@ -108,6 +108,12 @@ namespace boost {
namespace container { namespace container {
namespace dtl { namespace dtl {
///////////////////////////////////////
//
// Helper functions to merge elements
//
///////////////////////////////////////
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(stored_allocator_type) BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(stored_allocator_type)
template<class SequenceContainer, class Iterator, class Compare> template<class SequenceContainer, class Iterator, class Compare>
@ -118,23 +124,25 @@ BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal
} }
template<class SequenceContainer, class Iterator, class Compare> template<class SequenceContainer, class Iterator, class Compare>
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal_non_merge_member void aux_flat_tree_merge_equal_non_merge_member //is_contiguous_container == true
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::true_) (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::true_)
{ {
typedef typename SequenceContainer::iterator iterator; typedef typename SequenceContainer::iterator iterator;
typedef typename SequenceContainer::value_type value_type; typedef typename SequenceContainer::value_type value_type;
typedef typename SequenceContainer::size_type size_type;
iterator const it = dest.insert( dest.end(), first, last ); iterator const it = dest.insert( dest.end(), first, last );
value_type *const braw = boost::movelib::iterator_to_raw_pointer(dest.begin()); value_type *const braw = boost::movelib::iterator_to_raw_pointer(dest.begin());
value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it); value_type *const iraw = boost::movelib::iterator_to_raw_pointer(it);
value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end()); value_type *const eraw = boost::movelib::iterator_to_raw_pointer(dest.end());
value_type *const sraw = boost::movelib::iterator_to_raw_pointer(dest.begin()+dest.size()); value_type *const sraw = boost::movelib::iterator_to_raw_pointer(dest.begin())+dest.size();
boost::movelib::adaptive_sort(iraw, eraw, comp, sraw, dest.capacity()); size_type const sraw_size = dest.capacity()- dest.size();
boost::movelib::adaptive_merge(braw, iraw, eraw, comp, sraw, dest.capacity()- dest.size()); boost::movelib::adaptive_sort(iraw, eraw, comp, sraw, sraw_size);
boost::movelib::adaptive_merge(braw, iraw, eraw, comp, sraw, sraw_size);
} }
template<class SequenceContainer, class Iterator, class Compare> template<class SequenceContainer, class Iterator, class Compare>
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal_non_merge_member void aux_flat_tree_merge_equal_non_merge_member //is_contiguous_container == false
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_) (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_)
{ {
typedef typename SequenceContainer::iterator iterator; typedef typename SequenceContainer::iterator iterator;
@ -145,22 +153,22 @@ BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal_non_merge_member
} }
template<class SequenceContainer, class Iterator, class Compare> template<class SequenceContainer, class Iterator, class Compare>
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_equal //has_merge_unique == false
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_) (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_)
{ {
(flat_tree_merge_equal_non_merge_member)( dest, first, last, comp (aux_flat_tree_merge_equal_non_merge_member)
, dtl::bool_<is_contiguous_container<SequenceContainer>::value>()); ( dest, first, last, comp, dtl::bool_<is_contiguous_container<SequenceContainer>::value>());
} }
template<class SequenceContainer, class Iterator, class Compare> template<class SequenceContainer, class Iterator, class Compare>
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique //has_merge_unique == true
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::true_) (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::true_)
{ {
dest.merge_unique(first, last, comp); dest.merge_unique(first, last, comp);
} }
template<class SequenceContainer, class Iterator, class Compare> template<class SequenceContainer, class Iterator, class Compare>
BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique //has_merge_unique == false
(SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_) (SequenceContainer& dest, Iterator first, Iterator last, Compare comp, dtl::false_)
{ {
(flat_tree_merge_equal)(dest, first, last, comp, dtl::false_()); (flat_tree_merge_equal)(dest, first, last, comp, dtl::false_());
@ -170,7 +178,7 @@ BOOST_CONTAINER_FORCEINLINE void flat_tree_merge_unique
template<class SequenceContainer, class Iterator> template<class SequenceContainer, class Iterator>
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
flat_tree_index_of flat_tree_index_of // has_index_of == true
(SequenceContainer& cont, Iterator p, dtl::true_) (SequenceContainer& cont, Iterator p, dtl::true_)
{ {
return cont.index_of(p); return cont.index_of(p);
@ -178,7 +186,7 @@ BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
template<class SequenceContainer, class Iterator> template<class SequenceContainer, class Iterator>
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
flat_tree_index_of flat_tree_index_of // has_index_of == false
(SequenceContainer& cont, Iterator p, dtl::false_) (SequenceContainer& cont, Iterator p, dtl::false_)
{ {
typedef typename SequenceContainer::size_type size_type; typedef typename SequenceContainer::size_type size_type;
@ -187,7 +195,7 @@ BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
template<class Iterator, class SequenceContainer> template<class Iterator, class SequenceContainer>
BOOST_CONTAINER_FORCEINLINE Iterator BOOST_CONTAINER_FORCEINLINE Iterator
flat_tree_nth flat_tree_nth // has_nth == true
(SequenceContainer& cont, typename SequenceContainer::size_type n, dtl::true_) (SequenceContainer& cont, typename SequenceContainer::size_type n, dtl::true_)
{ {
return cont.nth(n); return cont.nth(n);
@ -195,7 +203,7 @@ BOOST_CONTAINER_FORCEINLINE Iterator
template<class Iterator, class SequenceContainer> template<class Iterator, class SequenceContainer>
BOOST_CONTAINER_FORCEINLINE Iterator BOOST_CONTAINER_FORCEINLINE Iterator
flat_tree_nth flat_tree_nth // has_nth == false
(SequenceContainer& cont, typename SequenceContainer::size_type n, dtl::false_) (SequenceContainer& cont, typename SequenceContainer::size_type n, dtl::false_)
{ {
return cont.begin()+ n; return cont.begin()+ n;
@ -203,7 +211,7 @@ BOOST_CONTAINER_FORCEINLINE Iterator
template<class SequenceContainer> template<class SequenceContainer>
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::stored_allocator_type & BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::stored_allocator_type &
flat_tree_get_stored_allocator flat_tree_get_stored_allocator // has_get_stored_allocator == true
(SequenceContainer& cont, dtl::true_) (SequenceContainer& cont, dtl::true_)
{ {
return cont.get_stored_allocator(); return cont.get_stored_allocator();
@ -211,7 +219,7 @@ BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::stored_allocator_type &
template<class SequenceContainer> template<class SequenceContainer>
BOOST_CONTAINER_FORCEINLINE const typename SequenceContainer::stored_allocator_type & BOOST_CONTAINER_FORCEINLINE const typename SequenceContainer::stored_allocator_type &
flat_tree_get_stored_allocator flat_tree_get_stored_allocator // has_get_stored_allocator == true
(const SequenceContainer& cont, dtl::true_) (const SequenceContainer& cont, dtl::true_)
{ {
return cont.get_stored_allocator(); return cont.get_stored_allocator();
@ -219,14 +227,15 @@ BOOST_CONTAINER_FORCEINLINE const typename SequenceContainer::stored_allocator_t
template<class SequenceContainer> template<class SequenceContainer>
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::allocator_type BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::allocator_type
flat_tree_get_stored_allocator flat_tree_get_stored_allocator // has_get_stored_allocator == false
(SequenceContainer& cont, dtl::false_) (SequenceContainer& cont, dtl::false_)
{ {
return cont.get_allocator(); return cont.get_allocator();
} }
template<class SequenceContainer, class Compare> template<class SequenceContainer, class Compare>
void flat_tree_adopt_sequence_equal(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::true_) void flat_tree_adopt_sequence_equal // is_contiguous_container == true
(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::true_)
{ {
tseq.clear(); tseq.clear();
boost::movelib::adaptive_sort boost::movelib::adaptive_sort
@ -239,14 +248,16 @@ void flat_tree_adopt_sequence_equal(SequenceContainer &tseq, BOOST_RV_REF(Sequen
} }
template<class SequenceContainer, class Compare> template<class SequenceContainer, class Compare>
void flat_tree_adopt_sequence_equal(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::false_) void flat_tree_adopt_sequence_equal // is_contiguous_container == false
(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::false_)
{ {
boost::movelib::adaptive_sort(seq.begin(), seq.end(), comp); boost::movelib::adaptive_sort(seq.begin(), seq.end(), comp);
tseq = boost::move(seq); tseq = boost::move(seq);
} }
template<class SequenceContainer, class Compare> template<class SequenceContainer, class Compare>
void flat_tree_adopt_sequence_unique(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::true_) void flat_tree_adopt_sequence_unique// is_contiguous_container == true
(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::true_)
{ {
boost::movelib::adaptive_sort boost::movelib::adaptive_sort
( boost::movelib::iterator_to_raw_pointer(seq.begin()) ( boost::movelib::iterator_to_raw_pointer(seq.begin())
@ -261,7 +272,8 @@ void flat_tree_adopt_sequence_unique(SequenceContainer &tseq, BOOST_RV_REF(Seque
} }
template<class SequenceContainer, class Compare> template<class SequenceContainer, class Compare>
void flat_tree_adopt_sequence_unique(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::false_) void flat_tree_adopt_sequence_unique// is_contiguous_container == false
(SequenceContainer &tseq, BOOST_RV_REF(SequenceContainer) seq, Compare comp, dtl::false_)
{ {
boost::movelib::adaptive_sort(seq.begin(), seq.end(), comp); boost::movelib::adaptive_sort(seq.begin(), seq.end(), comp);
seq.erase(boost::movelib::unique seq.erase(boost::movelib::unique
@ -270,32 +282,38 @@ void flat_tree_adopt_sequence_unique(SequenceContainer &tseq, BOOST_RV_REF(Seque
} }
template<class SequenceContainer> template<class SequenceContainer>
BOOST_CONTAINER_FORCEINLINE void BOOST_CONTAINER_FORCEINLINE void // has_reserve == true
flat_tree_reserve(SequenceContainer &tseq, typename SequenceContainer::size_type cap, dtl::true_) flat_tree_reserve(SequenceContainer &tseq, typename SequenceContainer::size_type cap, dtl::true_)
{ {
tseq.reserve(cap); tseq.reserve(cap);
} }
template<class SequenceContainer> template<class SequenceContainer>
BOOST_CONTAINER_FORCEINLINE void BOOST_CONTAINER_FORCEINLINE void // has_reserve == false
flat_tree_reserve(SequenceContainer &, typename SequenceContainer::size_type, dtl::false_) flat_tree_reserve(SequenceContainer &, typename SequenceContainer::size_type, dtl::false_)
{ {
} }
template<class SequenceContainer> template<class SequenceContainer> // has_capacity == true
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
flat_tree_capacity(const SequenceContainer &tseq, dtl::true_) flat_tree_capacity(const SequenceContainer &tseq, dtl::true_)
{ {
return tseq.capacity(); return tseq.capacity();
} }
template<class SequenceContainer> template<class SequenceContainer> // has_capacity == false
BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type BOOST_CONTAINER_FORCEINLINE typename SequenceContainer::size_type
flat_tree_capacity(const SequenceContainer &tseq, dtl::false_) flat_tree_capacity(const SequenceContainer &tseq, dtl::false_)
{ {
return tseq.size(); return tseq.size();
} }
///////////////////////////////////////
//
// flat_tree_value_compare
//
///////////////////////////////////////
template<class Compare, class Value, class KeyOfValue> template<class Compare, class Value, class KeyOfValue>
class flat_tree_value_compare class flat_tree_value_compare
: private Compare : private Compare
@ -324,19 +342,12 @@ class flat_tree_value_compare
Compare &get_comp() Compare &get_comp()
{ return *this; } { return *this; }
}; };
/*
template<class Pointer>
struct get_flat_tree_iterators
{
typedef typename boost::container::dtl::
vec_iterator<Pointer, false> iterator;
typedef typename boost::container::dtl::
vec_iterator<Pointer, true > const_iterator;
typedef boost::container::reverse_iterator<iterator> reverse_iterator;
typedef boost::container::reverse_iterator<const_iterator> const_reverse_iterator;
};
*/
///////////////////////////////////////
//
// select_container_type
//
///////////////////////////////////////
template < class Value, class AllocatorOrContainer template < class Value, class AllocatorOrContainer
, bool = boost::container::dtl::is_container<AllocatorOrContainer>::value > , bool = boost::container::dtl::is_container<AllocatorOrContainer>::value >
struct select_container_type struct select_container_type
@ -350,6 +361,12 @@ struct select_container_type<Value, AllocatorOrContainer, false>
typedef boost::container::vector<Value, AllocatorOrContainer> type; typedef boost::container::vector<Value, AllocatorOrContainer> type;
}; };
///////////////////////////////////////
//
// flat_tree
//
///////////////////////////////////////
template <class Value, class KeyOfValue, template <class Value, class KeyOfValue,
class Compare, class AllocatorOrContainer> class Compare, class AllocatorOrContainer>
class flat_tree class flat_tree

View File

@ -23,52 +23,54 @@
// container/detail // container/detail
#include <boost/container/detail/min_max.hpp> #include <boost/container/detail/min_max.hpp>
#include <boost/static_assert.hpp>
namespace boost { namespace boost {
namespace container { namespace container {
namespace dtl { namespace dtl {
enum NextCapacityOption { NextCapacityDouble, NextCapacity60Percent }; template<unsigned Minimum, unsigned Numerator, unsigned Denominator>
struct grow_factor_ratio
template<class SizeType, NextCapacityOption Option>
struct next_capacity_calculator;
template<class SizeType>
struct next_capacity_calculator<SizeType, NextCapacityDouble>
{ {
static SizeType get(const SizeType max_size BOOST_STATIC_ASSERT(Numerator > Denominator);
,const SizeType capacity BOOST_STATIC_ASSERT(Numerator < 100);
,const SizeType n) BOOST_STATIC_ASSERT(Denominator < 100);
BOOST_STATIC_ASSERT(Denominator == 1 || (0 != Numerator % Denominator));
template<class SizeType>
SizeType operator()(const SizeType cur_cap, const SizeType add_min_cap, const SizeType max_cap) const
{ {
const SizeType remaining = max_size - capacity; const SizeType overflow_limit = ((SizeType)-1) / Numerator;
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<class SizeType> SizeType new_cap = 0;
struct next_capacity_calculator<SizeType, NextCapacity60Percent>
{
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) if(cur_cap <= overflow_limit){
return capacity + max_value(3*(capacity+1)/5, n); new_cap = cur_cap * Numerator / Denominator;
}
if (capacity < m3*2) else if(Denominator == 1 || (SizeType(new_cap = cur_cap) / Denominator) > overflow_limit){
return capacity + max_value((capacity+1)/2, n); new_cap = (SizeType)-1;
return max_size; }
else{
new_cap *= Numerator;
}
return max_value(SizeType(Minimum), max_value(cur_cap+add_min_cap, min_value(max_cap, new_cap)));
} }
}; };
} //namespace dtl { } //namespace dtl {
struct growth_factor_50
: dtl::grow_factor_ratio<0, 3, 2>
{};
struct growth_factor_60
: dtl::grow_factor_ratio<0, 8, 5>
{};
struct growth_factor_100
: dtl::grow_factor_ratio<0, 2, 1>
{};
} //namespace container { } //namespace container {
} //namespace boost { } //namespace boost {

View File

@ -429,24 +429,39 @@ struct key_node_compare
{ return this->key_comp()(key_of_value()(nonkey1.get_data()), key_of_value()(nonkey2.get_data())); } { return this->key_comp()(key_of_value()(nonkey1.get_data()), key_of_value()(nonkey2.get_data())); }
}; };
template <class T, class KeyOfValue, template<class Options>
class Compare, class Allocator, struct get_tree_opt
class Options = tree_assoc_defaults> {
typedef Options type;
};
template<>
struct get_tree_opt<void>
{
typedef tree_assoc_defaults type;
};
template <class T, class KeyOfValue, class Compare, class Allocator, class Options>
class tree class tree
: public dtl::node_alloc_holder : public dtl::node_alloc_holder
< Allocator < Allocator
, typename dtl::intrusive_tree_type , typename dtl::intrusive_tree_type
< Allocator, tree_value_compare < Allocator, tree_value_compare
<typename allocator_traits<Allocator>::pointer, Compare, KeyOfValue> <typename allocator_traits<Allocator>::pointer, Compare, KeyOfValue>
, Options::tree_type, Options::optimize_size>::type , get_tree_opt<Options>::type::tree_type
, get_tree_opt<Options>::type::optimize_size
>::type
> >
{ {
typedef tree_value_compare typedef tree_value_compare
< typename allocator_traits<Allocator>::pointer < typename allocator_traits<Allocator>::pointer
, Compare, KeyOfValue> ValComp; , Compare, KeyOfValue> ValComp;
typedef typename get_tree_opt<Options>::type options_type;
typedef typename dtl::intrusive_tree_type typedef typename dtl::intrusive_tree_type
< Allocator, ValComp, Options::tree_type < Allocator, ValComp
, Options::optimize_size>::type Icont; , options_type::tree_type
, options_type::optimize_size
>::type Icont;
typedef dtl::node_alloc_holder typedef dtl::node_alloc_holder
<Allocator, Icont> AllocHolder; <Allocator, Icont> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr; typedef typename AllocHolder::NodePtr NodePtr;
@ -461,7 +476,7 @@ class tree
typedef typename Icont::const_iterator iconst_iterator; typedef typename Icont::const_iterator iconst_iterator;
typedef dtl::allocator_destroyer<NodeAlloc> Destroyer; typedef dtl::allocator_destroyer<NodeAlloc> Destroyer;
typedef typename AllocHolder::alloc_version alloc_version; typedef typename AllocHolder::alloc_version alloc_version;
typedef intrusive_tree_proxy<Options::tree_type> intrusive_tree_proxy_t; typedef intrusive_tree_proxy<options_type::tree_type> intrusive_tree_proxy_t;
BOOST_COPYABLE_AND_MOVABLE(tree) BOOST_COPYABLE_AND_MOVABLE(tree)

View File

@ -0,0 +1,36 @@
#ifndef BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
#define BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2017-2017. 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_CONFIG_HPP
# include <boost/config.hpp>
#endif
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
//Functors for member algorithm defaults
template<class ValueType>
struct value_less
{
bool operator()(const ValueType &a, const ValueType &b) const
{ return a < b; }
};
template<class ValueType>
struct value_equal
{
bool operator()(const ValueType &a, const ValueType &b) const
{ return a == b; }
};
#endif //BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP

View File

@ -33,6 +33,7 @@
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/node_alloc_holder.hpp> #include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/version_type.hpp> #include <boost/container/detail/version_type.hpp>
#include <boost/container/detail/value_functors.hpp>
// move // move
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/move/iterator.hpp> #include <boost/move/iterator.hpp>
@ -1204,7 +1205,7 @@ class list
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
void unique() void unique()
{ this->unique(value_equal()); } { this->unique(value_equal_t()); }
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
@ -1234,7 +1235,7 @@ class list
//! <b>Complexity</b>: This function is linear time: it performs at most //! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons. //! size() + x.size() - 1 comparisons.
void merge(list &x) void merge(list &x)
{ this->merge(x, value_less()); } { this->merge(x, value_less_t()); }
//! <b>Requires</b>: The lists x and *this must be distinct. //! <b>Requires</b>: The lists x and *this must be distinct.
//! //!
@ -1300,7 +1301,7 @@ class list
//! <b>Complexity</b>: The number of comparisons is approximately N log N, where N //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
//! is the list's size. //! is the list's size.
void sort() void sort()
{ this->sort(value_less()); } { this->sort(value_less_t()); }
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved. //! The sort is stable, that is, the relative order of equivalent elements is preserved.
@ -1457,18 +1458,8 @@ class list
} }
}; };
//Functors for member algorithm defaults typedef value_less<value_type> value_less_t;
struct value_less typedef value_equal<value_type> value_equal_t;
{
bool operator()(const value_type &a, const value_type &b) const
{ return a < b; }
};
struct value_equal
{
bool operator()(const value_type &a, const value_type &b) const
{ return a == b; }
};
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}; };

View File

@ -28,6 +28,24 @@
namespace boost { namespace boost {
namespace container { namespace container {
////////////////////////////////////////////////////////////////
//
//
// OPTIONS FOR ASSOCIATIVE TREE-BASED CONTAINERS
//
//
////////////////////////////////////////////////////////////////
//! Enumeration used to configure ordered associative containers
//! with a concrete tree implementation.
enum tree_type_enum
{
red_black_tree,
avl_tree,
scapegoat_tree,
splay_tree
};
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template<tree_type_enum TreeType, bool OptimizeSize> template<tree_type_enum TreeType, bool OptimizeSize>
@ -37,6 +55,8 @@ struct tree_opt
static const bool optimize_size = OptimizeSize; static const bool optimize_size = OptimizeSize;
}; };
typedef tree_opt<red_black_tree, true> tree_assoc_defaults;
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!This option setter specifies the underlying tree type //!This option setter specifies the underlying tree type
@ -72,6 +92,151 @@ struct tree_assoc_options
typedef implementation_defined type; typedef implementation_defined type;
}; };
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//! Helper alias metafunction to combine options into a single type to be used
//! by tree-based associative containers
template<class ...Options>
using tree_assoc_options_t = typename boost::container::tree_assoc_options<Options...>::type;
#endif
////////////////////////////////////////////////////////////////
//
//
// OPTIONS FOR VECTOR-BASED CONTAINERS
//
//
////////////////////////////////////////////////////////////////
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template<class AllocTraits, class StoredSizeType>
struct get_stored_size_type_with_alloctraits
{
typedef StoredSizeType type;
};
template<class AllocTraits>
struct get_stored_size_type_with_alloctraits<AllocTraits, void>
{
typedef typename AllocTraits::size_type type;
};
template<class GrowthType, class StoredSizeType>
struct vector_opt
{
typedef GrowthType growth_factor_type;
typedef StoredSizeType stored_size_type;
template<class AllocTraits>
struct get_stored_size_type
: get_stored_size_type_with_alloctraits<AllocTraits, StoredSizeType>
{};
};
class default_next_capacity;
typedef vector_opt<void, void> vector_null_opt;
#else //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!This growth factor argument specifies that the container should increase it's
//!capacity a 50% when existing capacity is exhausted.
struct growth_factor_50{};
//!This growth factor argument specifies that the container should increase it's
//!capacity a 60% when existing capacity is exhausted.
struct growth_factor_60{};
//!This growth factor argument specifies that the container should increase it's
//!capacity a 100% (doubling its capacity) when existing capacity is exhausted.
struct growth_factor_100{};
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
//!This option setter specifies the growth factor strategy of the underlying vector.
//!
//!\tparam GrowthFactor A function object that has the following signature:<br/><br/>
//!`template<class SizeType>`<br/>
//!`SizeType operator()(SizeType cur_cap, SizeType add_min_cap, SizeType max_cap) const;`.<br/><br/>
//!`cur_cap` is the current capacity, `add_min_cap` is the minimum additional capacity
//!we want to achieve and `max_cap` is the maximum capacity that the allocator or other
//!factors allow. The implementation should return a value between `cur_cap` + `add_min_cap`
//!and `max_cap`. `cur_cap` + `add_min_cap` is guaranteed not to overflow/wraparound,
//! but the implementation should handle wraparound produced by the growth factor.
//!
//!Predefined growth factors that can be passed as arguments to this option are:
//!\c boost::container::growth_factor_50
//!\c boost::container::growth_factor_60
//!\c boost::container::growth_factor_100
//!
//!If this option is not specified, a default will be used by the container.
BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_factor_type)
//!This option specifies the unsigned integer type that a user wants the container
//!to use to hold size-related information inside a container (e.g. current size, current capacity).
//!
//!\tparam StoredSizeType A unsigned integer type. It shall be smaller than than the size
//! of the size_type deduced from `allocator_traits<A>::size_type` or the same type.
//!
//!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit
//!(e.g. in 32-bit machines), or 32-bit size types (e.g. in a 64 bit machine) to see if some
//!memory can be saved for empty vectors. This could potentially performance benefits due to better
//!cache usage.
//!
//!Note that alignment requirements can disallow theoritical space savings. Example:
//!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine
//!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes)
//!will not save space when comparing two 16-bit size types because usually
//!a 32 bit alignment is required for vector and the size will be rounded to 8 bytes. In a 64-bit
//!machine a 16 bit size type does not usually save memory when comparing to a 32-bit size type.
//!Measure the size of the resulting container and do not assume a smaller \c stored_size
//!will always lead to a smaller sizeof(container).
//!
//!If a user tries to insert more elements than representable by \c stored_size, vector
//!will throw a length_error.
//!
//!If this option is not specified, `allocator_traits<A>::size_type` (usually std::size_t) will
//!be used to store size-related information inside the container.
BOOST_INTRUSIVE_OPTION_TYPE(stored_size, StoredSizeType, StoredSizeType, stored_size_type)
//! Helper metafunction to combine options into a single type to be used
//! by \c boost::container::vector.
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
template<class ...Options>
#else
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
#endif
struct vector_options
{
/// @cond
typedef typename ::boost::intrusive::pack_options
< vector_null_opt,
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
O1, O2, O3, O4
#else
Options...
#endif
>::type packed_options;
typedef vector_opt< typename packed_options::growth_factor_type
, typename packed_options::stored_size_type> implementation_defined;
/// @endcond
typedef implementation_defined type;
};
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
//! Helper alias metafunction to combine options into a single type to be used
//! by \c boost::container::vector.
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
template<class ...Options>
using vector_options_t = typename boost::container::vector_options<Options...>::type;
#endif
} //namespace container { } //namespace container {
} //namespace boost { } //namespace boost {

View File

@ -26,14 +26,12 @@ namespace pmr {
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key > >
,class Options = tree_assoc_defaults >
using flat_map = boost::container::flat_map<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > >; using flat_map = boost::container::flat_map<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > >;
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key> >
,class Options = tree_assoc_defaults >
using flat_multimap = boost::container::flat_multimap<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > >; using flat_multimap = boost::container::flat_multimap<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > >;
#endif #endif
@ -42,8 +40,7 @@ using flat_multimap = boost::container::flat_multimap<Key, T, Compare, polymorph
//! that uses a polymorphic allocator //! that uses a polymorphic allocator
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key> >
,class Options = tree_assoc_defaults >
struct flat_map_of struct flat_map_of
{ {
typedef boost::container::flat_map<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > > type; typedef boost::container::flat_map<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > > type;
@ -53,8 +50,7 @@ struct flat_map_of
//! that uses a polymorphic allocator //! that uses a polymorphic allocator
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key> >
,class Options = tree_assoc_defaults >
struct flat_multimap_of struct flat_multimap_of
{ {
typedef boost::container::flat_multimap<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > > type; typedef boost::container::flat_multimap<Key, T, Compare, polymorphic_allocator<std::pair<Key, T> > > type;

View File

@ -25,13 +25,11 @@ namespace pmr {
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key> >
,class Options = tree_assoc_defaults >
using flat_set = boost::container::flat_set<Key, Compare, polymorphic_allocator<Key> >; using flat_set = boost::container::flat_set<Key, Compare, polymorphic_allocator<Key> >;
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key> >
,class Options = tree_assoc_defaults >
using flat_multiset = boost::container::flat_multiset<Key, Compare, polymorphic_allocator<Key> >; using flat_multiset = boost::container::flat_multiset<Key, Compare, polymorphic_allocator<Key> >;
#endif #endif
@ -39,8 +37,7 @@ using flat_multiset = boost::container::flat_multiset<Key, Compare, polymorphic_
//! A portable metafunction to obtain a flat_set //! A portable metafunction to obtain a flat_set
//! that uses a polymorphic allocator //! that uses a polymorphic allocator
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key> >
,class Options = tree_assoc_defaults >
struct flat_set_of struct flat_set_of
{ {
typedef boost::container::flat_set<Key, Compare, polymorphic_allocator<Key> > type; typedef boost::container::flat_set<Key, Compare, polymorphic_allocator<Key> > type;
@ -49,8 +46,7 @@ struct flat_set_of
//! A portable metafunction to obtain a flat_multiset //! A portable metafunction to obtain a flat_multiset
//! that uses a polymorphic allocator //! that uses a polymorphic allocator
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key> >
,class Options = tree_assoc_defaults >
struct flat_multiset_of struct flat_multiset_of
{ {
typedef boost::container::flat_multiset<Key, Compare, polymorphic_allocator<Key> > type; typedef boost::container::flat_multiset<Key, Compare, polymorphic_allocator<Key> > type;

View File

@ -27,13 +27,13 @@ namespace pmr {
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
using map = boost::container::map<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options>; using map = boost::container::map<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options>;
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
using multimap = boost::container::multimap<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options>; using multimap = boost::container::multimap<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options>;
#endif #endif
@ -43,7 +43,7 @@ using multimap = boost::container::multimap<Key, T, Compare, polymorphic_allocat
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
struct map_of struct map_of
{ {
typedef boost::container::map<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options> type; typedef boost::container::map<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options> type;
@ -54,7 +54,7 @@ struct map_of
template <class Key template <class Key
,class T ,class T
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
struct multimap_of struct multimap_of
{ {
typedef boost::container::multimap<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options> type; typedef boost::container::multimap<Key, T, Compare, polymorphic_allocator<std::pair<const Key, T> >, Options> type;

View File

@ -26,12 +26,12 @@ namespace pmr {
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
using set = boost::container::set<Key, Compare, polymorphic_allocator<Key>, Options>; using set = boost::container::set<Key, Compare, polymorphic_allocator<Key>, Options>;
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
using multiset = boost::container::multiset<Key, Compare, polymorphic_allocator<Key>, Options>; using multiset = boost::container::multiset<Key, Compare, polymorphic_allocator<Key>, Options>;
#endif #endif
@ -40,7 +40,7 @@ using multiset = boost::container::multiset<Key, Compare, polymorphic_allocator<
//! that uses a polymorphic allocator //! that uses a polymorphic allocator
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
struct set_of struct set_of
{ {
typedef boost::container::set<Key, Compare, polymorphic_allocator<Key>, Options> type; typedef boost::container::set<Key, Compare, polymorphic_allocator<Key>, Options> type;
@ -50,7 +50,7 @@ struct set_of
//! that uses a polymorphic allocator //! that uses a polymorphic allocator
template <class Key template <class Key
,class Compare = std::less<Key> ,class Compare = std::less<Key>
,class Options = tree_assoc_defaults > ,class Options = void >
struct multiset_of struct multiset_of
{ {
typedef boost::container::multiset<Key, Compare, polymorphic_allocator<Key>, Options> type; typedef boost::container::multiset<Key, Compare, polymorphic_allocator<Key>, Options> type;

View File

@ -60,7 +60,7 @@ namespace container {
//! \tparam Compare is the comparison functor used to order keys //! \tparam Compare is the comparison functor used to order keys
//! \tparam Allocator is the allocator to be used to allocate memory for this container //! \tparam Allocator is the allocator to be used to allocate memory for this container
//! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options. //! \tparam Options is an packed option type generated using using boost::container::tree_assoc_options.
template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = tree_assoc_defaults > template <class Key, class Compare = std::less<Key>, class Allocator = new_allocator<Key>, class Options = void>
#else #else
template <class Key, class Compare, class Allocator, class Options> template <class Key, class Compare, class Allocator, class Options>
#endif #endif

View File

@ -34,6 +34,7 @@
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/node_alloc_holder.hpp> #include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/value_functors.hpp>
// intrusive // intrusive
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/slist.hpp> #include <boost/intrusive/slist.hpp>
@ -1165,7 +1166,7 @@ class slist
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
void unique() void unique()
{ this->unique(value_equal()); } { this->unique(value_equal_t()); }
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
@ -1195,7 +1196,7 @@ class slist
//! <b>Complexity</b>: This function is linear time: it performs at most //! <b>Complexity</b>: This function is linear time: it performs at most
//! size() + x.size() - 1 comparisons. //! size() + x.size() - 1 comparisons.
void merge(slist & x) void merge(slist & x)
{ this->merge(x, value_less()); } { this->merge(x, value_less_t()); }
//! <b>Requires</b>: The lists x and *this must be distinct. //! <b>Requires</b>: The lists x and *this must be distinct.
//! //!
@ -1261,7 +1262,7 @@ class slist
//! <b>Complexity</b>: The number of comparisons is approximately N log N, where N //! <b>Complexity</b>: The number of comparisons is approximately N log N, where N
//! is the list's size. //! is the list's size.
void sort() void sort()
{ this->sort(value_less()); } { this->sort(value_less_t()); }
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>. //! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved. //! The sort is stable, that is, the relative order of equivalent elements is preserved.
@ -1625,28 +1626,9 @@ class slist
}; };
//Functors for member algorithm defaults //Functors for member algorithm defaults
struct value_less typedef value_less<value_type> value_less_t;
{ typedef value_equal<value_type> value_equal_t;
bool operator()(const value_type &a, const value_type &b) const
{ return a < b; }
};
struct value_equal
{
bool operator()(const value_type &a, const value_type &b) const
{ return a == b; }
};
struct value_equal_to_this
{
explicit value_equal_to_this(const value_type &ref)
: m_ref(ref){}
bool operator()(const value_type &val) const
{ return m_ref == val; }
const value_type &m_ref;
};
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
}; };

View File

@ -282,7 +282,8 @@ class small_vector_allocator
pointer internal_storage() const pointer internal_storage() const
{ {
typedef typename Allocator::value_type value_type; typedef typename Allocator::value_type value_type;
typedef vector_alloc_holder< small_vector_allocator<Allocator> > vector_alloc_holder_t; typedef typename allocator_traits_type::size_type size_type;
typedef vector_alloc_holder< small_vector_allocator<Allocator>, size_type > vector_alloc_holder_t;
typedef vector<value_type, small_vector_allocator<Allocator> > vector_base; typedef vector<value_type, small_vector_allocator<Allocator> > vector_base;
typedef small_vector_base<value_type, Allocator> derived_type; typedef small_vector_base<value_type, Allocator> derived_type;
// //
@ -350,7 +351,6 @@ class small_vector_base
typedef small_vector_allocator<SecondaryAllocator> allocator_type; typedef small_vector_allocator<SecondaryAllocator> allocator_type;
protected: protected:
typedef typename base_type::initial_capacity_t initial_capacity_t;
BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(initial_capacity_t, std::size_t initial_capacity) BOOST_CONTAINER_FORCEINLINE explicit small_vector_base(initial_capacity_t, std::size_t initial_capacity)
: base_type(initial_capacity_t(), this->internal_storage(), initial_capacity) : base_type(initial_capacity_t(), this->internal_storage(), initial_capacity)
@ -481,7 +481,6 @@ class small_vector : public small_vector_base<T, Allocator>
BOOST_COPYABLE_AND_MOVABLE(small_vector) BOOST_COPYABLE_AND_MOVABLE(small_vector)
typedef typename base_type::initial_capacity_t initial_capacity_t;
typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type; typedef allocator_traits<typename base_type::allocator_type> allocator_traits_type;
public: public:

View File

@ -292,10 +292,8 @@ class basic_string_base
size_type next_capacity(size_type additional_objects) const size_type next_capacity(size_type additional_objects) const
{ {
return next_capacity_calculator return growth_factor_100()
<size_type, NextCapacityDouble /*NextCapacity60Percent*/>:: ( this->priv_storage(), additional_objects, allocator_traits_type::max_size(this->alloc()));
get( allocator_traits_type::max_size(this->alloc())
, this->priv_storage(), additional_objects );
} }
void deallocate(pointer p, size_type n) void deallocate(pointer p, size_type n)

View File

@ -27,6 +27,7 @@
#include <boost/container/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
#include <boost/container/new_allocator.hpp> //new_allocator #include <boost/container/new_allocator.hpp> //new_allocator
#include <boost/container/throw_exception.hpp> #include <boost/container/throw_exception.hpp>
#include <boost/container/options.hpp>
// container detail // container detail
#include <boost/container/detail/advanced_insert_int.hpp> #include <boost/container/detail/advanced_insert_int.hpp>
#include <boost/container/detail/algorithm.hpp> //equal() #include <boost/container/detail/algorithm.hpp> //equal()
@ -39,6 +40,7 @@
#include <boost/move/detail/iterator_to_raw_pointer.hpp> #include <boost/move/detail/iterator_to_raw_pointer.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/next_capacity.hpp> #include <boost/container/detail/next_capacity.hpp>
#include <boost/container/detail/value_functors.hpp>
#include <boost/move/detail/to_raw_pointer.hpp> #include <boost/move/detail/to_raw_pointer.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/version_type.hpp> #include <boost/container/detail/version_type.hpp>
@ -73,8 +75,6 @@ namespace container {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
namespace dtl {
template <class Pointer, bool IsConst> template <class Pointer, bool IsConst>
class vec_iterator class vec_iterator
{ {
@ -82,7 +82,7 @@ class vec_iterator
typedef std::random_access_iterator_tag iterator_category; typedef std::random_access_iterator_tag iterator_category;
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type; typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type; typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
typedef typename if_c typedef typename dtl::if_c
< IsConst < IsConst
, typename boost::intrusive::pointer_traits<Pointer>::template , typename boost::intrusive::pointer_traits<Pointer>::template
rebind_pointer<const value_type>::type rebind_pointer<const value_type>::type
@ -244,30 +244,28 @@ struct vector_merge_cursor
Comp &m_cmp; Comp &m_cmp;
}; };
} //namespace dtl { struct initial_capacity_t{};
template<class Pointer, bool IsConst> template<class Pointer, bool IsConst>
BOOST_CONTAINER_FORCEINLINE const Pointer &vector_iterator_get_ptr(const dtl::vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW BOOST_CONTAINER_FORCEINLINE const Pointer &vector_iterator_get_ptr(const vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
{ return it.get_ptr(); } { return it.get_ptr(); }
template<class Pointer, bool IsConst> template<class Pointer, bool IsConst>
BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr(dtl::vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr(vec_iterator<Pointer, IsConst> &it) BOOST_NOEXCEPT_OR_NOTHROW
{ return it.get_ptr(); } { return it.get_ptr(); }
namespace dtl { struct vector_uninitialized_size_t {};
static const vector_uninitialized_size_t vector_uninitialized_size = vector_uninitialized_size_t();
struct uninitialized_size_t {};
static const uninitialized_size_t uninitialized_size = uninitialized_size_t();
template <class T> template <class T>
struct vector_value_traits_base struct vector_value_traits_base
{ {
static const bool trivial_dctr = is_trivially_destructible<T>::value; static const bool trivial_dctr = dtl::is_trivially_destructible<T>::value;
static const bool trivial_dctr_after_move = has_trivial_destructor_after_move<T>::value; static const bool trivial_dctr_after_move = has_trivial_destructor_after_move<T>::value;
static const bool trivial_copy = is_trivially_copy_constructible<T>::value; static const bool trivial_copy = dtl::is_trivially_copy_constructible<T>::value;
static const bool nothrow_copy = is_nothrow_copy_constructible<T>::value || trivial_copy; static const bool nothrow_copy = dtl::is_nothrow_copy_constructible<T>::value || trivial_copy;
static const bool trivial_assign = is_trivially_copy_assignable<T>::value; static const bool trivial_assign = dtl::is_trivially_copy_assignable<T>::value;
static const bool nothrow_assign = is_nothrow_copy_assignable<T>::value || trivial_assign; static const bool nothrow_assign = dtl::is_nothrow_copy_assignable<T>::value || trivial_assign;
}; };
@ -289,6 +287,7 @@ struct vector_value_traits
//!This struct deallocates and allocated memory //!This struct deallocates and allocated memory
template < class Allocator template < class Allocator
, class StoredSizeType
, class AllocatorVersion = typename dtl::version<Allocator>::type , class AllocatorVersion = typename dtl::version<Allocator>::type
> >
struct vector_alloc_holder struct vector_alloc_holder
@ -298,7 +297,8 @@ struct vector_alloc_holder
BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder)
public: public:
typedef Allocator allocator_type; typedef Allocator allocator_type;
typedef StoredSizeType stored_size_type;
typedef boost::container::allocator_traits<Allocator> allocator_traits_type; typedef boost::container::allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::size_type size_type; typedef typename allocator_traits_type::size_type size_type;
@ -334,28 +334,34 @@ struct vector_alloc_holder
//Constructor, does not throw //Constructor, does not throw
template<class AllocConvertible> template<class AllocConvertible>
vector_alloc_holder(uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
: Allocator(boost::forward<AllocConvertible>(a)) : Allocator(boost::forward<AllocConvertible>(a))
, m_start() , m_start()
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this //Size is initialized here so vector should only call uninitialized_xxx after this
, m_size(static_cast<stored_size_type>(initial_size))
, m_capacity() , m_capacity()
{ {
if(initial_size){ if(initial_size){
pointer reuse = pointer(); pointer reuse = pointer();
m_start = this->allocation_command(allocate_new, initial_size, m_capacity = initial_size, reuse); size_type final_cap = initial_size;
m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse);
m_capacity = static_cast<stored_size_type>(final_cap);
} }
} }
//Constructor, does not throw //Constructor, does not throw
vector_alloc_holder(uninitialized_size_t, size_type initial_size) vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size)
: Allocator() : Allocator()
, m_start() , m_start()
, m_size(initial_size) //Size is initialized here so vector should only call uninitialized_xxx after this //Size is initialized here so vector should only call uninitialized_xxx after this
, m_size(static_cast<stored_size_type>(initial_size))
, m_capacity() , m_capacity()
{ {
if(initial_size){ if(initial_size){
pointer reuse = pointer(); pointer reuse = pointer();
m_start = this->allocation_command(allocate_new, initial_size, m_capacity = initial_size, reuse); size_type final_cap = initial_size;
m_start = this->allocation_command(allocate_new, initial_size, final_cap, reuse);
m_capacity = static_cast<stored_size_type>(final_cap);
} }
} }
@ -369,17 +375,17 @@ struct vector_alloc_holder
holder.m_size = holder.m_capacity = 0; holder.m_size = holder.m_capacity = 0;
} }
vector_alloc_holder(pointer p, size_type capacity, BOOST_RV_REF(vector_alloc_holder) holder) vector_alloc_holder(initial_capacity_t, pointer p, size_type capacity, BOOST_RV_REF(vector_alloc_holder) holder)
: Allocator(BOOST_MOVE_BASE(Allocator, holder)) : Allocator(BOOST_MOVE_BASE(Allocator, holder))
, m_start(p) , m_start(p)
, m_size(holder.m_size) , m_size(holder.m_size)
, m_capacity(capacity) , m_capacity(static_cast<stored_size_type>(capacity))
{ {
allocator_type &this_alloc = this->alloc(); allocator_type &this_alloc = this->alloc();
allocator_type &x_alloc = holder.alloc(); allocator_type &x_alloc = holder.alloc();
if(this->is_propagable_from(x_alloc, holder.start(), this_alloc, true)){ if(this->is_propagable_from(x_alloc, holder.start(), this_alloc, true)){
if(this->m_capacity){ if(this->m_capacity){
allocator_traits_type::deallocate(this->alloc(), this->m_start, this->m_capacity); this->deallocate(this->m_start, this->m_capacity);
} }
m_start = holder.m_start; m_start = holder.m_start;
m_capacity = holder.m_capacity; m_capacity = holder.m_capacity;
@ -389,23 +395,26 @@ struct vector_alloc_holder
else if(this->m_capacity < holder.m_size){ else if(this->m_capacity < holder.m_size){
size_type const n = holder.m_size; size_type const n = holder.m_size;
pointer reuse = pointer(); pointer reuse = pointer();
m_start = this->allocation_command(allocate_new, n, m_capacity = n, reuse); size_type final_cap = n;
m_start = this->allocation_command(allocate_new, n, final_cap, reuse);
m_capacity = static_cast<stored_size_type>(final_cap);
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
this->num_alloc += n != 0; this->num_alloc += n != 0;
#endif #endif
} }
} }
vector_alloc_holder(pointer p, size_type n) vector_alloc_holder(initial_capacity_t, pointer p, size_type n)
BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value) BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible<Allocator>::value)
: Allocator() : Allocator()
, m_start(p) , m_start(p)
, m_size() , m_size()
, m_capacity(n) //n is guaranteed to fit into stored_size_type
, m_capacity(static_cast<stored_size_type>(n))
{} {}
template<class AllocFwd> template<class AllocFwd>
vector_alloc_holder(pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a) vector_alloc_holder(initial_capacity_t, pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a)
: Allocator(::boost::forward<AllocFwd>(a)) : Allocator(::boost::forward<AllocFwd>(a))
, m_start(p) , m_start(p)
, m_size() , m_size()
@ -415,7 +424,7 @@ struct vector_alloc_holder
BOOST_CONTAINER_FORCEINLINE ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW BOOST_CONTAINER_FORCEINLINE ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW
{ {
if(this->m_capacity){ if(this->m_capacity){
allocator_traits_type::deallocate(this->alloc(), this->m_start, this->m_capacity); this->deallocate(this->m_start, this->m_capacity);
} }
} }
@ -426,6 +435,21 @@ struct vector_alloc_holder
return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse); return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse);
} }
BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n)
{
const size_type max_alloc = allocator_traits_type::max_size(this->alloc());
const size_type max = max_alloc <= stored_size_type(-1) ? max_alloc : stored_size_type(-1);
if ( max < n )
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
return allocator_traits_type::allocate(this->alloc(), n);
}
BOOST_CONTAINER_FORCEINLINE void deallocate(const pointer &p, size_type n)
{
allocator_traits_type::deallocate(this->alloc(), p, n);
}
bool try_expand_fwd(size_type at_least) bool try_expand_fwd(size_type at_least)
{ {
//There is not enough memory, try to expand the old one //There is not enough memory, try to expand the old one
@ -443,17 +467,24 @@ struct vector_alloc_holder
return success; return success;
} }
BOOST_CONTAINER_FORCEINLINE size_type next_capacity(size_type additional_objects) const template<class GrowthFactorType>
size_type next_capacity(size_type additional_objects) const
{ {
return next_capacity_calculator BOOST_ASSERT(additional_objects > size_type(this->m_capacity - this->m_size));
<size_type, NextCapacityDouble //NextCapacity60Percent size_type max = allocator_traits_type::max_size(this->alloc());
>::get( allocator_traits_type::max_size(this->alloc()) (clamp_by_stored_size_type)(max, stored_size_type());
, this->m_capacity, additional_objects ); const size_type remaining_cap = max - size_type(this->m_capacity);
const size_type min_additional_cap = additional_objects - size_type(this->m_capacity - this->m_size);
if ( remaining_cap < min_additional_cap )
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
return GrowthFactorType()( size_type(this->m_capacity), min_additional_cap, max);
} }
pointer m_start; pointer m_start;
size_type m_size; stored_size_type m_size;
size_type m_capacity; stored_size_type m_capacity;
void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW
{ {
@ -478,9 +509,9 @@ struct vector_alloc_holder
{ return *this; } { return *this; }
const pointer &start() const BOOST_NOEXCEPT_OR_NOTHROW { return m_start; } const pointer &start() const BOOST_NOEXCEPT_OR_NOTHROW { return m_start; }
const size_type &capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return m_capacity; } size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return m_capacity; }
void start(const pointer &p) BOOST_NOEXCEPT_OR_NOTHROW { m_start = p; } void start(const pointer &p) BOOST_NOEXCEPT_OR_NOTHROW { m_start = p; }
void capacity(const size_type &c) BOOST_NOEXCEPT_OR_NOTHROW { m_capacity = c; } void capacity(const size_type &c) BOOST_NOEXCEPT_OR_NOTHROW { BOOST_ASSERT( c <= stored_size_type(-1)); m_capacity = c; }
private: private:
void priv_first_allocation(size_type cap) void priv_first_allocation(size_type cap)
@ -495,15 +526,30 @@ struct vector_alloc_holder
} }
} }
BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &, size_type)
{}
template<class SomeStoredSizeType>
BOOST_CONTAINER_FORCEINLINE static void clamp_by_stored_size_type(size_type &s, SomeStoredSizeType)
{
if (s >= SomeStoredSizeType(-1) )
s = SomeStoredSizeType(-1);
}
BOOST_CONTAINER_FORCEINLINE pointer priv_allocation_command(version_1, boost::container::allocation_type command, BOOST_CONTAINER_FORCEINLINE pointer priv_allocation_command(version_1, boost::container::allocation_type command,
size_type , size_type limit_size,
size_type &prefer_in_recvd_out_size, size_type &prefer_in_recvd_out_size,
pointer &reuse) pointer &reuse)
{ {
(void)command; (void)command;
BOOST_ASSERT( (command & allocate_new)); BOOST_ASSERT( (command & allocate_new));
BOOST_ASSERT(!(command & nothrow_allocation)); BOOST_ASSERT(!(command & nothrow_allocation));
pointer const p = allocator_traits_type::allocate(this->alloc(), prefer_in_recvd_out_size, reuse); //First detect overflow on smaller stored_size_types
if (limit_size > stored_size_type(-1)){
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
}
(clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
pointer const p = this->allocate(prefer_in_recvd_out_size);
reuse = pointer(); reuse = pointer();
return p; return p;
} }
@ -513,13 +559,22 @@ struct vector_alloc_holder
size_type &prefer_in_recvd_out_size, size_type &prefer_in_recvd_out_size,
pointer &reuse) pointer &reuse)
{ {
return this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); //First detect overflow on smaller stored_size_types
if (limit_size > stored_size_type(-1)){
boost::container::throw_length_error("get_next_capacity, allocator's max size reached");
}
(clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
//Allocate memory
pointer p = this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse);
//If after allocation prefer_in_recvd_out_size is not representable by stored_size_type, truncate it.
(clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type());
return p;
} }
}; };
//!This struct deallocates and allocated memory //!This struct deallocates and allocated memory
template <class Allocator> template <class Allocator, class StoredSizeType>
struct vector_alloc_holder<Allocator, version_0> struct vector_alloc_holder<Allocator, StoredSizeType, version_0>
: public Allocator : public Allocator
{ {
private: private:
@ -530,8 +585,9 @@ struct vector_alloc_holder<Allocator, version_0>
typedef typename allocator_traits_type::pointer pointer; typedef typename allocator_traits_type::pointer pointer;
typedef typename allocator_traits_type::size_type size_type; typedef typename allocator_traits_type::size_type size_type;
typedef typename allocator_traits_type::value_type value_type; typedef typename allocator_traits_type::value_type value_type;
typedef StoredSizeType stored_size_type;
template <class OtherAllocator, class OtherAllocatorVersion> template <class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
friend struct vector_alloc_holder; friend struct vector_alloc_holder;
//Constructor, does not throw //Constructor, does not throw
@ -548,7 +604,7 @@ struct vector_alloc_holder<Allocator, version_0>
//Constructor, does not throw //Constructor, does not throw
template<class AllocConvertible> template<class AllocConvertible>
vector_alloc_holder(uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size)
: Allocator(boost::forward<AllocConvertible>(a)) : Allocator(boost::forward<AllocConvertible>(a))
, m_size(initial_size) //Size is initialized here... , m_size(initial_size) //Size is initialized here...
{ {
@ -557,7 +613,7 @@ struct vector_alloc_holder<Allocator, version_0>
} }
//Constructor, does not throw //Constructor, does not throw
vector_alloc_holder(uninitialized_size_t, size_type initial_size) vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size)
: Allocator() : Allocator()
, m_size(initial_size) //Size is initialized here... , m_size(initial_size) //Size is initialized here...
{ {
@ -573,8 +629,8 @@ struct vector_alloc_holder<Allocator, version_0>
(this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start())); (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start()));
} }
template<class OtherAllocator, class OtherAllocatorVersion> template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> BOOST_RV_REF_END holder) vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> BOOST_RV_REF_END holder)
: Allocator() : Allocator()
, m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort , m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort
{ {
@ -597,8 +653,8 @@ struct vector_alloc_holder<Allocator, version_0>
this->priv_deep_swap(x); this->priv_deep_swap(x);
} }
template<class OtherAllocator, class OtherAllocatorVersion> template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
void deep_swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x) void deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x)
{ {
if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){ if(this->m_size > OtherAllocator::internal_capacity || x.m_size > Allocator::internal_capacity){
throw_bad_alloc(); throw_bad_alloc();
@ -628,12 +684,12 @@ struct vector_alloc_holder<Allocator, version_0>
BOOST_CONTAINER_FORCEINLINE pointer start() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_storage(); } BOOST_CONTAINER_FORCEINLINE pointer start() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_storage(); }
BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_capacity; } BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW { return Allocator::internal_capacity; }
size_type m_size; stored_size_type m_size;
private: private:
template<class OtherAllocator, class OtherAllocatorVersion> template<class OtherAllocator, class OtherStoredSizeType, class OtherAllocatorVersion>
void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherAllocatorVersion> &x) void priv_deep_swap(vector_alloc_holder<OtherAllocator, OtherStoredSizeType, OtherAllocatorVersion> &x)
{ {
const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity; const size_type MaxTmpStorage = sizeof(value_type)*Allocator::internal_capacity;
value_type *const first_this = boost::movelib::to_raw_pointer(this->start()); value_type *const first_this = boost::movelib::to_raw_pointer(this->start());
@ -649,7 +705,34 @@ struct vector_alloc_holder<Allocator, version_0>
} }
}; };
} //namespace dtl { struct growth_factor_60;
template<class T, class Default>
struct default_if_void
{
typedef T type;
};
template<class Default>
struct default_if_void<void, Default>
{
typedef Default type;
};
template<class Options, class AllocatorSizeType>
struct get_vector_opt
{
typedef vector_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
, typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
> type;
};
template<class AllocatorSizeType>
struct get_vector_opt<void, AllocatorSizeType>
{
typedef vector_opt<growth_factor_60, AllocatorSizeType> type;
};
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@ -660,28 +743,32 @@ struct vector_alloc_holder<Allocator, version_0>
//! //!
//! \tparam T The type of object that is stored in the vector //! \tparam T The type of object that is stored in the vector
//! \tparam Allocator The allocator used for all internal memory management //! \tparam Allocator The allocator used for all internal memory management
template <class T, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>) > //! \tparam Options A type produced from \c boost::container::vector_options.
template <class T, class Allocator BOOST_CONTAINER_DOCONLY(= new_allocator<T>), class Options BOOST_CONTAINER_DOCONLY(= void) >
class vector class vector
{ {
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
struct value_less typedef typename boost::container::allocator_traits<Allocator>::size_type alloc_size_type;
{ typedef typename get_vector_opt<Options, alloc_size_type>::type options_type;
typedef typename boost::container::allocator_traits<Allocator>::value_type value_type; typedef typename options_type::growth_factor_type growth_factor_type;
bool operator()(const value_type &a, const value_type &b) const typedef typename options_type::stored_size_type stored_size_type;
{ return a < b; } typedef value_less<T> value_less_t;
};
//If provided the stored_size option must specify a type that is equal or a type that is smaller.
BOOST_STATIC_ASSERT( (sizeof(stored_size_type) < sizeof(alloc_size_type) ||
dtl::is_same<stored_size_type, alloc_size_type>::value) );
typedef typename dtl::version<Allocator>::type alloc_version; typedef typename dtl::version<Allocator>::type alloc_version;
typedef boost::container::dtl::vector_alloc_holder<Allocator> alloc_holder_t; typedef boost::container::vector_alloc_holder<Allocator, stored_size_type> alloc_holder_t;
alloc_holder_t m_holder; alloc_holder_t m_holder;
typedef allocator_traits<Allocator> allocator_traits_type; typedef allocator_traits<Allocator> allocator_traits_type;
template <class U, class UAllocator> template <class U, class UAllocator, class UOptions>
friend class vector; friend class vector;
typedef typename allocator_traits_type::pointer pointer_impl; typedef typename allocator_traits_type::pointer pointer_impl;
typedef dtl::vec_iterator<pointer_impl, false> iterator_impl; typedef vec_iterator<pointer_impl, false> iterator_impl;
typedef dtl::vec_iterator<pointer_impl, true > const_iterator_impl; typedef vec_iterator<pointer_impl, true > const_iterator_impl;
protected: protected:
static bool is_propagable_from(const Allocator &from_alloc, pointer_impl p, const Allocator &to_alloc, bool const propagate_allocator) static bool is_propagable_from(const Allocator &from_alloc, pointer_impl p, const Allocator &to_alloc, bool const propagate_allocator)
@ -716,7 +803,7 @@ class vector
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private: private:
BOOST_COPYABLE_AND_MOVABLE(vector) BOOST_COPYABLE_AND_MOVABLE(vector)
typedef dtl::vector_value_traits<Allocator> value_traits; typedef vector_value_traits<Allocator> value_traits;
typedef constant_iterator<T, difference_type> cvalue_iterator; typedef constant_iterator<T, difference_type> cvalue_iterator;
protected: protected:
@ -724,14 +811,13 @@ class vector
BOOST_CONTAINER_FORCEINLINE void steal_resources(vector &x) BOOST_CONTAINER_FORCEINLINE void steal_resources(vector &x)
{ return this->m_holder.steal_resources(x.m_holder); } { return this->m_holder.steal_resources(x.m_holder); }
struct initial_capacity_t{};
template<class AllocFwd> template<class AllocFwd>
BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity, BOOST_FWD_REF(AllocFwd) a) BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity, BOOST_FWD_REF(AllocFwd) a)
: m_holder(initial_memory, capacity, ::boost::forward<AllocFwd>(a)) : m_holder(initial_capacity_t(), initial_memory, capacity, ::boost::forward<AllocFwd>(a))
{} {}
BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity) BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity)
: m_holder(initial_memory, capacity) : m_holder(initial_capacity_t(), initial_memory, capacity)
{} {}
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@ -768,7 +854,7 @@ class vector
//! //!
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
explicit vector(size_type n) explicit vector(size_type n)
: m_holder(dtl::uninitialized_size, n) : m_holder(vector_uninitialized_size, n)
{ {
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
this->num_alloc += n != 0; this->num_alloc += n != 0;
@ -785,7 +871,7 @@ class vector
//! //!
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
explicit vector(size_type n, const allocator_type &a) explicit vector(size_type n, const allocator_type &a)
: m_holder(dtl::uninitialized_size, a, n) : m_holder(vector_uninitialized_size, a, n)
{ {
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
this->num_alloc += n != 0; this->num_alloc += n != 0;
@ -804,7 +890,7 @@ class vector
//! //!
//! <b>Note</b>: Non-standard extension //! <b>Note</b>: Non-standard extension
vector(size_type n, default_init_t) vector(size_type n, default_init_t)
: m_holder(dtl::uninitialized_size, n) : m_holder(vector_uninitialized_size, n)
{ {
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
this->num_alloc += n != 0; this->num_alloc += n != 0;
@ -823,7 +909,7 @@ class vector
//! //!
//! <b>Note</b>: Non-standard extension //! <b>Note</b>: Non-standard extension
vector(size_type n, default_init_t, const allocator_type &a) vector(size_type n, default_init_t, const allocator_type &a)
: m_holder(dtl::uninitialized_size, a, n) : m_holder(vector_uninitialized_size, a, n)
{ {
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
this->num_alloc += n != 0; this->num_alloc += n != 0;
@ -840,7 +926,7 @@ class vector
//! //!
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
vector(size_type n, const T& value) vector(size_type n, const T& value)
: m_holder(dtl::uninitialized_size, n) : m_holder(vector_uninitialized_size, n)
{ {
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
this->num_alloc += n != 0; this->num_alloc += n != 0;
@ -857,7 +943,7 @@ class vector
//! //!
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
vector(size_type n, const T& value, const allocator_type& a) vector(size_type n, const T& value, const allocator_type& a)
: m_holder(dtl::uninitialized_size, a, n) : m_holder(vector_uninitialized_size, a, n)
{ {
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
this->num_alloc += n != 0; this->num_alloc += n != 0;
@ -907,7 +993,7 @@ class vector
//! //!
//! <b>Complexity</b>: Linear to the elements x contains. //! <b>Complexity</b>: Linear to the elements x contains.
vector(const vector &x) vector(const vector &x)
: m_holder( dtl::uninitialized_size : m_holder( vector_uninitialized_size
, allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc()) , allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc())
, x.size()) , x.size())
{ {
@ -970,7 +1056,7 @@ class vector
//! //!
//! <b>Complexity</b>: Linear to the elements x contains. //! <b>Complexity</b>: Linear to the elements x contains.
vector(const vector &x, const allocator_type &a) vector(const vector &x, const allocator_type &a)
: m_holder(dtl::uninitialized_size, a, x.size()) : m_holder(vector_uninitialized_size, a, x.size())
{ {
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
this->num_alloc += x.size() != 0; this->num_alloc += x.size() != 0;
@ -988,7 +1074,7 @@ class vector
//! //!
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise. //! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
vector(BOOST_RV_REF(vector) x, const allocator_type &a) vector(BOOST_RV_REF(vector) x, const allocator_type &a)
: m_holder( dtl::uninitialized_size, a : m_holder( vector_uninitialized_size, a
, is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true) ? 0 : x.size() , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, true) ? 0 : x.size()
) )
{ {
@ -1194,7 +1280,7 @@ class vector
pointer const old_p = this->m_holder.start(); pointer const old_p = this->m_holder.start();
if(old_p){ if(old_p){
this->priv_destroy_all(); this->priv_destroy_all();
allocator_traits_type::deallocate(this->m_holder.alloc(), old_p, old_capacity); this->m_holder.deallocate(old_p, old_capacity);
} }
this->m_holder.start(ret); this->m_holder.start(ret);
this->m_holder.capacity(real_cap); this->m_holder.capacity(real_cap);
@ -2028,19 +2114,19 @@ class vector
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Linear to the number of elements in the container. //! <b>Complexity</b>: Linear to the number of elements in the container.
void clear() BOOST_NOEXCEPT_OR_NOTHROW BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW
{ this->priv_destroy_all(); } { this->priv_destroy_all(); }
//! <b>Effects</b>: Returns true if x and y are equal //! <b>Effects</b>: Returns true if x and y are equal
//! //!
//! <b>Complexity</b>: Linear to the number of elements in the container. //! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator==(const vector& x, const vector& y) BOOST_CONTAINER_FORCEINLINE friend bool operator==(const vector& x, const vector& y)
{ return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); }
//! <b>Effects</b>: Returns true if x and y are unequal //! <b>Effects</b>: Returns true if x and y are unequal
//! //!
//! <b>Complexity</b>: Linear to the number of elements in the container. //! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator!=(const vector& x, const vector& y) BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const vector& x, const vector& y)
{ return !(x == y); } { return !(x == y); }
//! <b>Effects</b>: Returns true if x is less than y //! <b>Effects</b>: Returns true if x is less than y
@ -2060,25 +2146,25 @@ class vector
//! <b>Effects</b>: Returns true if x is greater than y //! <b>Effects</b>: Returns true if x is greater than y
//! //!
//! <b>Complexity</b>: Linear to the number of elements in the container. //! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator>(const vector& x, const vector& y) BOOST_CONTAINER_FORCEINLINE friend bool operator>(const vector& x, const vector& y)
{ return y < x; } { return y < x; }
//! <b>Effects</b>: Returns true if x is equal or less than y //! <b>Effects</b>: Returns true if x is equal or less than y
//! //!
//! <b>Complexity</b>: Linear to the number of elements in the container. //! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator<=(const vector& x, const vector& y) BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const vector& x, const vector& y)
{ return !(y < x); } { return !(y < x); }
//! <b>Effects</b>: Returns true if x is equal or greater than y //! <b>Effects</b>: Returns true if x is equal or greater than y
//! //!
//! <b>Complexity</b>: Linear to the number of elements in the container. //! <b>Complexity</b>: Linear to the number of elements in the container.
friend bool operator>=(const vector& x, const vector& y) BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const vector& x, const vector& y)
{ return !(x < y); } { return !(x < y); }
//! <b>Effects</b>: x.swap(y) //! <b>Effects</b>: x.swap(y)
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
friend void swap(vector& x, vector& y) BOOST_CONTAINER_FORCEINLINE friend void swap(vector& x, vector& y)
{ x.swap(y); } { x.swap(y); }
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
@ -2099,26 +2185,26 @@ class vector
//Absolutely experimental. This function might change, disappear or simply crash! //Absolutely experimental. This function might change, disappear or simply crash!
template<class BiDirPosConstIt, class BiDirValueIt> template<class BiDirPosConstIt, class BiDirValueIt>
void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it) BOOST_CONTAINER_FORCEINLINE void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it)
{ {
typedef dtl::vector_insert_ordered_cursor<BiDirPosConstIt, BiDirValueIt> inserter_t; typedef vector_insert_ordered_cursor<BiDirPosConstIt, BiDirValueIt> inserter_t;
return this->priv_insert_ordered_at(element_count, inserter_t(last_position_it, last_value_it)); return this->priv_insert_ordered_at(element_count, inserter_t(last_position_it, last_value_it));
} }
template<class BidirIt> template<class BidirIt>
void merge(BidirIt first, BidirIt last) BOOST_CONTAINER_FORCEINLINE void merge(BidirIt first, BidirIt last)
{ this->merge(first, last, value_less()); } { this->merge(first, last, value_less_t()); }
template<class BidirIt, class Compare> template<class BidirIt, class Compare>
void merge(BidirIt first, BidirIt last, Compare comp) BOOST_CONTAINER_FORCEINLINE void merge(BidirIt first, BidirIt last, Compare comp)
{ this->priv_merge(dtl::false_type(), first, last, comp); } { this->priv_merge(dtl::false_type(), first, last, comp); }
template<class BidirIt> template<class BidirIt>
void merge_unique(BidirIt first, BidirIt last) BOOST_CONTAINER_FORCEINLINE void merge_unique(BidirIt first, BidirIt last)
{ this->priv_merge(dtl::true_type(), first, last, value_less()); } { this->priv_merge(dtl::true_type(), first, last, value_less_t()); }
template<class BidirIt, class Compare> template<class BidirIt, class Compare>
void merge_unique(BidirIt first, BidirIt last, Compare comp) BOOST_CONTAINER_FORCEINLINE void merge_unique(BidirIt first, BidirIt last, Compare comp)
{ this->priv_merge(dtl::true_type(), first, last, comp); } { this->priv_merge(dtl::true_type(), first, last, comp); }
private: private:
@ -2209,7 +2295,7 @@ class vector
} }
template<class UniqueBool, class FwdIt, class Compare> template<class UniqueBool, class FwdIt, class Compare>
void priv_merge_in_new_buffer(UniqueBool, FwdIt, size_type, Compare, version_0) BOOST_CONTAINER_FORCEINLINE void priv_merge_in_new_buffer(UniqueBool, FwdIt, size_type, Compare, version_0)
{ {
throw_bad_alloc(); throw_bad_alloc();
} }
@ -2266,7 +2352,7 @@ class vector
pointer const old_p = this->m_holder.start(); pointer const old_p = this->m_holder.start();
size_type const old_cap = this->m_holder.capacity(); size_type const old_cap = this->m_holder.capacity();
boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size); boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size);
allocator_traits_type::deallocate(a, old_p, old_cap); this->m_holder.deallocate(old_p, old_cap);
this->m_holder.m_size = old_size + added; this->m_holder.m_size = old_size + added;
this->m_holder.start(new_storage); this->m_holder.start(new_storage);
this->m_holder.capacity(new_cap); this->m_holder.capacity(new_cap);
@ -2274,10 +2360,10 @@ class vector
new_values_destroyer.release(); new_values_destroyer.release();
} }
bool room_enough() const BOOST_CONTAINER_FORCEINLINE bool room_enough() const
{ return this->m_holder.m_size < this->m_holder.capacity(); } { return this->m_holder.m_size < this->m_holder.capacity(); }
pointer back_ptr() const BOOST_CONTAINER_FORCEINLINE pointer back_ptr() const
{ return this->m_holder.start() + this->m_holder.m_size; } { return this->m_holder.start() + this->m_holder.m_size; }
size_type priv_index_of(pointer p) const size_type priv_index_of(pointer p) const
@ -2331,7 +2417,7 @@ class vector
} }
else if(is_propagable_from_x){ else if(is_propagable_from_x){
this->clear(); this->clear();
allocator_traits_type::deallocate(this->m_holder.alloc(), this->m_holder.m_start, this->m_holder.m_capacity); this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity);
this->m_holder.steal_resources(x.m_holder); this->m_holder.steal_resources(x.m_holder);
} }
//Else do a one by one move //Else do a one by one move
@ -2429,7 +2515,7 @@ class vector
{ {
//There is not enough memory, allocate a new buffer //There is not enough memory, allocate a new buffer
//Pass the hint so that allocators can take advantage of this. //Pass the hint so that allocators can take advantage of this.
pointer const p = allocator_traits_type::allocate(this->m_holder.alloc(), new_cap, this->m_holder.m_start); pointer const p = this->m_holder.allocate(new_cap);
//We will reuse insert code, so create a dummy input iterator //We will reuse insert code, so create a dummy input iterator
this->priv_forward_range_insert_new_allocation this->priv_forward_range_insert_new_allocation
( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy()); ( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy());
@ -2537,13 +2623,13 @@ class vector
} }
} }
dtl::insert_n_copies_proxy<Allocator, T*> priv_resize_proxy(const T &x) BOOST_CONTAINER_FORCEINLINE dtl::insert_n_copies_proxy<Allocator, T*> priv_resize_proxy(const T &x)
{ return dtl::insert_n_copies_proxy<Allocator, T*>(x); } { return dtl::insert_n_copies_proxy<Allocator, T*>(x); }
dtl::insert_default_initialized_n_proxy<Allocator, T*> priv_resize_proxy(default_init_t) BOOST_CONTAINER_FORCEINLINE dtl::insert_default_initialized_n_proxy<Allocator, T*> priv_resize_proxy(default_init_t)
{ return dtl::insert_default_initialized_n_proxy<Allocator, T*>(); } { return dtl::insert_default_initialized_n_proxy<Allocator, T*>(); }
dtl::insert_value_initialized_n_proxy<Allocator, T*> priv_resize_proxy(value_init_t) BOOST_CONTAINER_FORCEINLINE dtl::insert_value_initialized_n_proxy<Allocator, T*> priv_resize_proxy(value_init_t)
{ return dtl::insert_value_initialized_n_proxy<Allocator, T*>(); } { return dtl::insert_value_initialized_n_proxy<Allocator, T*>(); }
template <class U> template <class U>
@ -2560,7 +2646,7 @@ class vector
} }
} }
void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW BOOST_CONTAINER_FORCEINLINE void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW
{} {}
void priv_shrink_to_fit(version_1) void priv_shrink_to_fit(version_1)
@ -2569,14 +2655,14 @@ class vector
if(cp){ if(cp){
const size_type sz = this->size(); const size_type sz = this->size();
if(!sz){ if(!sz){
allocator_traits_type::deallocate(this->m_holder.alloc(), this->m_holder.m_start, cp); this->m_holder.deallocate(this->m_holder.m_start, cp);
this->m_holder.m_start = pointer(); this->m_holder.m_start = pointer();
this->m_holder.m_capacity = 0; this->m_holder.m_capacity = 0;
} }
else if(sz < cp){ else if(sz < cp){
//Allocate a new buffer. //Allocate a new buffer.
//Pass the hint so that allocators can take advantage of this. //Pass the hint so that allocators can take advantage of this.
pointer const p = allocator_traits_type::allocate(this->m_holder.alloc(), sz, this->m_holder.m_start); pointer const p = this->m_holder.allocate(sz);
//We will reuse insert code, so create a dummy input iterator //We will reuse insert code, so create a dummy input iterator
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
@ -2595,7 +2681,7 @@ class vector
if(cp){ if(cp){
const size_type sz = this->size(); const size_type sz = this->size();
if(!sz){ if(!sz){
allocator_traits_type::deallocate(this->m_holder.alloc(), this->m_holder.m_start, cp); this->m_holder.deallocate(this->m_holder.m_start, cp);
this->m_holder.m_start = pointer(); this->m_holder.m_start = pointer();
this->m_holder.m_capacity = 0; this->m_holder.m_capacity = 0;
} }
@ -2629,10 +2715,9 @@ class vector
const size_type n_pos = pos - this->m_holder.start(); const size_type n_pos = pos - this->m_holder.start();
T *const raw_pos = boost::movelib::to_raw_pointer(pos); T *const raw_pos = boost::movelib::to_raw_pointer(pos);
const size_type new_cap = this->m_holder.next_capacity(n); const size_type new_cap = this->m_holder.template next_capacity<growth_factor_type>(n);
//Pass the hint so that allocators can take advantage of this. //Pass the hint so that allocators can take advantage of this.
T * const new_buf = boost::movelib::to_raw_pointer T * const new_buf = boost::movelib::to_raw_pointer(this->m_holder.allocate(new_cap));
(allocator_traits_type::allocate(this->m_holder.alloc(), new_cap, this->m_holder.m_start));
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
++this->num_alloc; ++this->num_alloc;
#endif #endif
@ -2651,7 +2736,7 @@ class vector
//There is not enough memory, allocate a new //There is not enough memory, allocate a new
//buffer or expand the old one. //buffer or expand the old one.
size_type real_cap = this->m_holder.next_capacity(n); size_type real_cap = this->m_holder.template next_capacity<growth_factor_type>(n);
pointer reuse(this->m_holder.start()); pointer reuse(this->m_holder.start());
pointer const ret (this->m_holder.allocation_command pointer const ret (this->m_holder.allocation_command
(allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse)); (allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse));
@ -2725,7 +2810,7 @@ class vector
} }
template <class InsertionProxy, class AllocVersion> template <class InsertionProxy, class AllocVersion>
iterator priv_forward_range_insert_at_end BOOST_CONTAINER_FORCEINLINE iterator priv_forward_range_insert_at_end
(const size_type n, const InsertionProxy insert_range_proxy, AllocVersion) (const size_type n, const InsertionProxy insert_range_proxy, AllocVersion)
{ {
return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy); return this->priv_forward_range_insert(this->back_ptr(), n, insert_range_proxy);
@ -2909,10 +2994,10 @@ class vector
//If there is allocated memory, destroy and deallocate //If there is allocated memory, destroy and deallocate
if(!value_traits::trivial_dctr_after_move) if(!value_traits::trivial_dctr_after_move)
boost::container::destroy_alloc_n(this->get_stored_allocator(), old_buffer, this->m_holder.m_size); boost::container::destroy_alloc_n(this->get_stored_allocator(), old_buffer, this->m_holder.m_size);
allocator_traits_type::deallocate(this->m_holder.alloc(), this->m_holder.start(), this->m_holder.capacity()); this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity());
} }
this->m_holder.start(new_start); this->m_holder.start(new_start);
this->m_holder.m_size = new_finish - new_start; this->m_holder.m_size = size_type(new_finish - new_start);
this->m_holder.capacity(new_cap); this->m_holder.capacity(new_cap);
//All construction successful, disable rollbacks //All construction successful, disable rollbacks
new_values_destroyer.release(); new_values_destroyer.release();
@ -3248,12 +3333,12 @@ class vector
} }
} }
bool priv_in_range(const_iterator pos) const BOOST_CONTAINER_FORCEINLINE bool priv_in_range(const_iterator pos) const
{ {
return (this->begin() <= pos) && (pos < this->end()); return (this->begin() <= pos) && (pos < this->end());
} }
bool priv_in_range_or_end(const_iterator pos) const BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const
{ {
return (this->begin() <= pos) && (pos <= this->end()); return (this->begin() <= pos) && (pos <= this->end());
} }

View File

@ -1,72 +1,4 @@
Microsoft Visual Studio Solution File, Format Version 8.00 Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "set_test", "set_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "map_test", "map_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792606}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_emplace", "doc_emplace.vcproj", "{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_containers", "doc_move_containers.vcproj", "{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_recursive_containers", "doc_recursive_containers.vcproj", "{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_type_erasure", "doc_type_erasure.vcproj", "{5C8E1C13-A4F4-2C55-4FA2-D100BA6A9041}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alloc_basic_test", "alloc_basic_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alloc_full_test", "alloc_full_test.vcproj", "{CD57C283-1862-9FE5-BF87-BA91293A76D3}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_alloc_lib", "alloc_lib.vcproj", "{685AC59C-E667-4096-9DAA-AB76083C7092}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "allocator_traits_test", "allocator_traits_test.vcproj", "{5CE11C83-096A-84FE-4FA2-D3A6BA792002}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_adaptive_node_pool", "bench_adaptive_node_pool.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_alloc_expand_bwd", "bench_alloc_expand_bwd.vcproj", "{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_alloc", "bench_alloc.vcproj", "{7CC83A22-8612-7BF8-2F4E-BD9493C6A071}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_alloc_expand_fwd", "bench_alloc_expand_fwd.vcproj", "{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_alloc_shrink_to_fit", "bench_alloc_shrink_to_fit.vcproj", "{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_set", "bench_set.vcproj", "{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_static_vector", "bench_static_vector.vcproj", "{55E1C1C3-84FE-26A9-4A2E-D7901C32BA02}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_containerlib", "container.vcproj", "{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_containerlib", "container.vcproj", "{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
@ -319,6 +251,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flat_tree_test", "flat_tree
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vector_options_test", "vector_options_test.vcproj", "{3E10C8C3-4F8E-96A0-4FA2-D032BA7A6092}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_custom_vector", "doc_custom_vector.vcproj", "{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug Debug = Debug
@ -327,74 +267,6 @@ Global
GlobalSection(ProjectDependencies) = postSolution GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution GlobalSection(ProjectConfiguration) = postSolution
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D3A792606}.Release.Build.0 = Release|Win32
{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}.Debug.ActiveCfg = Debug|Win32
{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}.Debug.Build.0 = Debug|Win32
{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}.Release.ActiveCfg = Release|Win32
{5CE11C83-FA84-295A-4FA2-D7921A0BAB02}.Release.Build.0 = Release|Win32
{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}.Debug.ActiveCfg = Debug|Win32
{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}.Debug.Build.0 = Debug|Win32
{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}.Release.ActiveCfg = Release|Win32
{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}.Release.Build.0 = Release|Win32
{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}.Debug.ActiveCfg = Debug|Win32
{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}.Debug.Build.0 = Debug|Win32
{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}.Release.ActiveCfg = Release|Win32
{5D1C8E13-255A-FA84-4FA2-DA92100BAD42}.Release.Build.0 = Release|Win32
{5C8E1C13-A4F4-2C55-4FA2-D100BA6A9041}.Debug.ActiveCfg = Debug|Win32
{5C8E1C13-A4F4-2C55-4FA2-D100BA6A9041}.Debug.Build.0 = Debug|Win32
{5C8E1C13-A4F4-2C55-4FA2-D100BA6A9041}.Release.ActiveCfg = Release|Win32
{5C8E1C13-A4F4-2C55-4FA2-D100BA6A9041}.Release.Build.0 = Release|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
{CD57C283-1862-9FE5-BF87-BA91293A76D3}.Debug.ActiveCfg = Debug|Win32
{CD57C283-1862-9FE5-BF87-BA91293A76D3}.Debug.Build.0 = Debug|Win32
{CD57C283-1862-9FE5-BF87-BA91293A76D3}.Release.ActiveCfg = Release|Win32
{CD57C283-1862-9FE5-BF87-BA91293A76D3}.Release.Build.0 = Release|Win32
{685AC59C-E667-4096-9DAA-AB76083C7092}.Debug.ActiveCfg = Debug|Win32
{685AC59C-E667-4096-9DAA-AB76083C7092}.Debug.Build.0 = Debug|Win32
{685AC59C-E667-4096-9DAA-AB76083C7092}.Release.ActiveCfg = Release|Win32
{685AC59C-E667-4096-9DAA-AB76083C7092}.Release.Build.0 = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.ActiveCfg = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
{5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32
{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32
{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32
{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Debug.ActiveCfg = Debug|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Debug.Build.0 = Debug|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Release.ActiveCfg = Release|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Release.Build.0 = Release|Win32
{7CC83A22-8612-7BF8-2F4E-BD9493C6A071}.Debug.ActiveCfg = Debug|Win32
{7CC83A22-8612-7BF8-2F4E-BD9493C6A071}.Debug.Build.0 = Debug|Win32
{7CC83A22-8612-7BF8-2F4E-BD9493C6A071}.Release.ActiveCfg = Release|Win32
{7CC83A22-8612-7BF8-2F4E-BD9493C6A071}.Release.Build.0 = Release|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Debug.ActiveCfg = Debug|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Debug.Build.0 = Debug|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Release.ActiveCfg = Release|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Release.Build.0 = Release|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Debug.ActiveCfg = Debug|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Debug.Build.0 = Debug|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Release.ActiveCfg = Release|Win32
{C7C283A2-7BF8-8612-42FE-B9D26A0793A1}.Release.Build.0 = Release|Win32
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Debug.ActiveCfg = Debug|Win32
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Debug.Build.0 = Debug|Win32
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Release.ActiveCfg = Release|Win32
{5E1C1C23-26A9-4FE5-A24E-DA735271C32B}.Release.Build.0 = Release|Win32
{55E1C1C3-84FE-26A9-4A2E-D7901C32BA02}.Debug.ActiveCfg = Debug|Win32
{55E1C1C3-84FE-26A9-4A2E-D7901C32BA02}.Debug.Build.0 = Debug|Win32
{55E1C1C3-84FE-26A9-4A2E-D7901C32BA02}.Release.ActiveCfg = Release|Win32
{55E1C1C3-84FE-26A9-4A2E-D7901C32BA02}.Release.Build.0 = Release|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.ActiveCfg = Debug|Win32 {FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.ActiveCfg = Debug|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.Build.0 = Debug|Win32 {FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Debug.Build.0 = Debug|Win32
{FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Release.ActiveCfg = Release|Win32 {FF56BAF1-32EC-4B22-B6BD-95A3A67C3135}.Release.ActiveCfg = Release|Win32
@ -645,6 +517,14 @@ Global
{DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Debug.Build.0 = Debug|Win32 {DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Debug.Build.0 = Debug|Win32
{DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Release.ActiveCfg = Release|Win32 {DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Release.ActiveCfg = Release|Win32
{DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Release.Build.0 = Release|Win32 {DE1834C3-2609-FE38-4FA5-0BA0D3CD0796}.Release.Build.0 = Release|Win32
{3E10C8C3-4F8E-96A0-4FA2-D032BA7A6092}.Debug.ActiveCfg = Debug|Win32
{3E10C8C3-4F8E-96A0-4FA2-D032BA7A6092}.Debug.Build.0 = Debug|Win32
{3E10C8C3-4F8E-96A0-4FA2-D032BA7A6092}.Release.ActiveCfg = Release|Win32
{3E10C8C3-4F8E-96A0-4FA2-D032BA7A6092}.Release.Build.0 = Release|Win32
{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}.Debug.ActiveCfg = Debug|Win32
{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}.Debug.Build.0 = Debug|Win32
{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}.Release.ActiveCfg = Release|Win32
{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}.Release.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection EndGlobalSection

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="doc_custom_vector"
ProjectGUID="{5E11C8B3-A8C4-4A2F-295A-7951A0EDAA02}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/doc_custom_vector"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
ExceptionHandling="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/doc_custom_vector_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/doc_custom_vector.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"
/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/doc_custom_vector"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/doc_custom_vector.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4F4737BC-032A-5430-AC75-A32542AA2D1F}">
<File
RelativePath="..\..\example\doc_custom_vector.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -13,7 +13,7 @@
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug" OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/vector_test" IntermediateDirectory="Debug/doc_extended_allocators"
ConfigurationType="1" ConfigurationType="1"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool

View File

@ -13,7 +13,7 @@
<Configuration <Configuration
Name="Debug|Win32" Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug" OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/vector_test" IntermediateDirectory="Debug/doc_move_containers"
ConfigurationType="1" ConfigurationType="1"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="vector_options_test"
ProjectGUID="{3E10C8C3-4F8E-96A0-4FA2-D032BA7A6092}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/vector_options_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
ExceptionHandling="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/vector_options_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/vector_options_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/vector_options_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/vector_options_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{3BCC4057-7AC5-1273-6AD6-5A3296A32D7F}">
<File
RelativePath="..\..\test\vector_options_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,121 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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)
//
// See http://www.boost.org/libs/container for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/container/vector.hpp>
#include <boost/container/allocator.hpp>
#include <boost/container/detail/next_capacity.hpp>
#include <boost/core/lightweight_test.hpp>
using namespace boost::container;
template<class Unsigned, class VectorType>
void test_stored_size_type_impl()
{
VectorType v;
typedef typename VectorType::size_type size_type;
typedef typename VectorType::value_type value_type;
size_type const max = Unsigned(-1);
v.resize(5);
v.resize(max);
BOOST_TEST_THROWS(v.resize(max+1), std::exception);
BOOST_TEST_THROWS(v.push_back(value_type(1)), std::exception);
BOOST_TEST_THROWS(v.insert(v.begin(), value_type(1)), std::exception);
BOOST_TEST_THROWS(v.emplace(v.begin(), value_type(1)),std::exception);
BOOST_TEST_THROWS(v.reserve(max+1), std::exception);
BOOST_TEST_THROWS(VectorType v2(max+1), std::exception);
}
template<class Unsigned>
void test_stored_size_type()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = vector_options_t< stored_size<Unsigned> >;
#else
typedef typename vector_options
< stored_size<Unsigned> >::type options_t;
#endif
//Test first with a typical allocator
{
typedef vector<unsigned char, new_allocator<unsigned char>, options_t> vector_t;
test_stored_size_type_impl<Unsigned, vector_t>();
}
//Test with a V2 allocator
{
typedef vector<unsigned char, allocator<unsigned char>, options_t> vector_t;
test_stored_size_type_impl<Unsigned, vector_t>();
}
}
void test_growth_factor_50()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = vector_options_t< growth_factor<growth_factor_50> >;
#else
typedef vector_options
< growth_factor<growth_factor_50> >::type options_t;
#endif
vector<int, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == old_capacity + old_capacity/2);
}
void test_growth_factor_60()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = vector_options_t< growth_factor<growth_factor_60> >;
#else
typedef vector_options
< growth_factor<growth_factor_60> >::type options_t;
#endif
vector<int, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == old_capacity + 3*old_capacity/5);
}
void test_growth_factor_100()
{
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
using options_t = vector_options_t< growth_factor<growth_factor_100> >;
#else
typedef vector_options
< growth_factor<growth_factor_100> >::type options_t;
#endif
vector<int, new_allocator<int>, options_t> v;
v.resize(5);
v.resize(v.capacity());
std::size_t old_capacity = v.capacity();
v.push_back(0);
std::size_t new_capacity = v.capacity();
BOOST_TEST(new_capacity == 2*old_capacity);
}
int main()
{
test_growth_factor_50();
test_growth_factor_60();
test_growth_factor_100();
test_stored_size_type<unsigned char>();
test_stored_size_type<unsigned short>();
return ::boost::report_errors();
}

View File

@ -38,13 +38,9 @@ template class boost::container::vector
< test::movable_and_copyable_int < test::movable_and_copyable_int
, allocator<test::movable_and_copyable_int> >; , allocator<test::movable_and_copyable_int> >;
namespace dtl {
template class vec_iterator<int*, true >; template class vec_iterator<int*, true >;
template class vec_iterator<int*, false>; template class vec_iterator<int*, false>;
}
}} }}
int test_expand_bwd() int test_expand_bwd()