From 0098adea15500fde74cb1bec2a0a6f4dddce4397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 31 Mar 2012 20:57:45 +0000 Subject: [PATCH] Added documentation on scoped allocators [SVN r77679] --- doc/container.qbk | 52 ++++++++++++++++++++++++++++++++++++++++---- test/vector_test.cpp | 36 +++++++++++++++--------------- 2 files changed, 66 insertions(+), 22 deletions(-) diff --git a/doc/container.qbk b/doc/container.qbk index 464bd04..c446e60 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -422,10 +422,9 @@ to suppose two allocators of the same type always compare equal (that means that by one allocator object could be deallocated by another instance of the same type) and allocators were not swapped when the container was swapped. -C++11 further improves stateful allocator support through the -[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2554.pdf -Scoped Allocators model]. [@http://en.cppreference.com/w/cpp/memory/allocator_traits -`std::allocator_traits`] is the protocol between a container and an allocator, and +C++11 further improves stateful allocator support through +[@http://en.cppreference.com/w/cpp/memory/allocator_traits `std::allocator_traits`]. +`std::allocator_traits` is the protocol between a container and an allocator, and an allocator writer can customize its behaviour (should the container propagate it in move constructor, swap, etc.?) following `allocator_traits` requirements. [*Boost.Container] not only supports this model with C++11 but also [*backports it to C++03]. @@ -437,6 +436,36 @@ not constructed on the fly when auxiliary memory is needed). [endsect] +[section:scoped_allocator Scoped allocators] + +C++11 improves stateful allocators with the introduction of +[@http://http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor `std::scoped_allocator_adaptor`] +class template. `scoped_allocator_adaptor` is instantiated with one outer allocator and zero or more inner +allocators. + +A scoped allocator is a mechanism to automatically propagate the state of the allocator to the subobjects +of a container in a controlled way. If instantiated with only one allocator type, the inner allocator +becomes the `scoped_allocator_adaptor` itself, thus using the same allocator +resource for the container and every element within the container and, if the elements themselves are +containers, each of their elements recursively. If instantiated with more than one allocator, the first allocator +is the outer allocator for use by the container, the second allocator is passed to the constructors of the +container's elements, and, if the elements themselves are containers, the third allocator is passed to the +elements' elements, and so on. + +[*Boost.Container] implements its own `scoped_allocator_adaptor` class and [*backports this feature also +to C++03 compilers]. Due to C++03 limitations, in those compilers +the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions +will be based on traits([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix] +and [classref boost::container::constructible_with_allocator_prefix constructible_with_allocator_prefix]) +proposed in [@http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2554.pdf +N2554: The Scoped Allocator Model (Rev 2) proposal]. In conforming C++11 compilers or compilers supporting SFINAE +expressions (when `BOOST_NO_SFINAE_EXPR` is NOT defined), traits are ignored and C++11 rules +(`is_constructible::value` and +`is_constructible::value`) +will be used to detect if the allocator must be propagated with suffix or prefix allocator arguments. + +[endsect] + [section:initializer_lists Initializer lists] [*Boost.Container] does not support initializer lists when constructing or assigning containers @@ -585,6 +614,21 @@ use [*Boost.Container]? There are several reasons for that: [section:release_notes Release Notes] +[section:release_notes_boost_1_50_00 Boost 1.50 Release] + +* Added Scoped Allocator Model support. + +* Fixed bugs + [@https://svn.boost.org/trac/boost/ticket/6566 #6566], + [@https://svn.boost.org/trac/boost/ticket/6575 #6575], + [@https://svn.boost.org/trac/boost/ticket/6606 #6606], + [@https://svn.boost.org/trac/boost/ticket/6615 #6615], + [@https://svn.boost.org/trac/boost/ticket/6533 #6533], + [@https://svn.boost.org/trac/boost/ticket/6536 #6536], + +[endsect] + + [section:release_notes_boost_1_49_00 Boost 1.49 Release] * Fixed bugs diff --git a/test/vector_test.cpp b/test/vector_test.cpp index cbc9721..bf99fea 100644 --- a/test/vector_test.cpp +++ b/test/vector_test.cpp @@ -94,27 +94,27 @@ enum Test }; int main() -{ - const std::size_t positions_length = 10; - std::size_t positions[positions_length]; - vector vector_int; - vector vector_int2(positions_length); - for(std::size_t i = 0; i != positions_length; ++i){ - positions[i] = 0u; - } - for(std::size_t i = 0, max = vector_int2.size(); i != max; ++i){ - vector_int2[i] = i; - } +{/* + { + const std::size_t positions_length = 10; + std::size_t positions[positions_length]; + vector vector_int; + vector vector_int2(positions_length); + for(std::size_t i = 0; i != positions_length; ++i){ + positions[i] = 0u; + } + for(std::size_t i = 0, max = vector_int2.size(); i != max; ++i){ + vector_int2[i] = i; + } - vector_int.insert(vector_int.begin(), 999); + vector_int.insert(vector_int.begin(), 999); - //vector_int.insert_at_ordered_positions(positions, positions_length, vector_int2.end()); - - for(std::size_t i = 0, max = vector_int.size(); i != max; ++i){ - std::cout << vector_int[i] << std::endl; - } - return 0; + vector_int.insert_ordered_at(positions_length, positions + positions_length, vector_int2.end()); + for(std::size_t i = 0, max = vector_int.size(); i != max; ++i){ + std::cout << vector_int[i] << std::endl; + } + }*/ recursive_vector_test(); { //Now test move semantics