Changes during Git migration:

- Added Extended Allocator support for Boost.Container.
- Improved Doxygen generated reference
- Fixed ticket #9338 ("VS2005 compiler errors in swap() definition after including container/memory_util.hpp")
This commit is contained in:
Ion Gaztañaga committed 2013-12-23 10:47:20 +01:00
1 parent b1d4ef3a2e
commit f2947c115e
95 files changed
+2248 -2692

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
# Boost.Container library documentation Jamfile ---------------------------------
#
# Copyright Ion Gaztanaga 2009-2012. Use, modification and
# Copyright Ion Gaztanaga 2009-2013. Use, modification and
# distribution is subject to the Boost Software License, Version
# 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
+150 -23
View File
@@ -49,9 +49,13 @@ In short, what does [*Boost.Container] offer?
[section:introduction_building_container Building Boost.Container]
There is no need to compile [*Boost.Container], since it's
a header only library. Just include your Boost header directory in your
compiler include path.
There is no need to compile [*Boost.Container] if you don't use [link container.extended_functionality.extended_allocators Extended Allocators]
since in that case it's a header-only library. Just include your Boost header directory in your compiler include path.
[link container.extended_functionality.extended_allocators Extended Allocators] are
implemented as a separately compiled library, so you must install binaries in a location that can be found by your linker
when using these classes. If you followed the [@http://www.boost.org/doc/libs/release/more/getting_started/index.html Boost Getting Started] instructions,
that's already been done for you.
[endsect]
@@ -148,12 +152,19 @@ today, in fact, implementors would have to go out of their way to prohibit it!]]
C++11 standard is also cautious about incomplete types and STL: ["['17.6.4.8 Other functions (...) 2.
the effects are undefined in the following cases: (...) In particular - if an incomplete type (3.9)
is used as a template argument when instantiating a template component,
unless specifically allowed for that component]]. Fortunately [*Boost.Container] containers are designed
to support type erasure and recursive types, so let's see some examples:
unless specifically allowed for that component]].
Fortunately all [*Boost.Container] containers except
[classref boost::container::static_vector static_vector] and
[classref boost::container::basic_string basic_string] are designed to support incomplete types.
[classref boost::container::static_vector static_vector] is special because
it statically allocates memory for `value_type` and this requires complete types and
[classref boost::container::basic_string basic_string] implements Small String Optimization which
also requires complete types.
[section:recursive_containers Recursive containers]
All containers offered by [*Boost.Container] can be used to define recursive containers:
Most [*Boost.Container] containers can be used to define recursive containers:
[import ../example/doc_recursive_containers.cpp]
[doc_recursive_containers]
@@ -261,8 +272,8 @@ When dealing with user-defined classes, (e.g. when constructing user-defined cla
propagate error situations internally as no error will be propagated through [*Boost.Container].
* If `BOOST_NO_EXCEPTIONS` is *not* defined, the library propagates exceptions offering the exception guarantees detailed in the documentation.
When the library needs to throw an exception (such as `out_of_range` when an incorrect index is used in `vector::at`)], the library calls
a throw callback declared in `<boost/container/throw_exception.hpp>`:
When the library needs to throw an exception (such as `out_of_range` when an incorrect index is used in `vector::at`), the library calls
a throw-callback declared in [headerref boost/container/throw_exception.hpp]:
* If `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` is defined, then the programmer must provide its own definition for all
`throw_xxx` functions. Those functions can't return, they must throw an exception or call `std::exit` or `std::abort`.
@@ -522,6 +533,123 @@ using [@http://en.cppreference.com/w/cpp/language/default_initialization default
[endsect]
[section:ordered_range_insertion Ordered range insertion for associative containers (['ordered_unique_range], ['ordered_range]) ]
When filling associative containers big performance gains can be achieved if the input range to be inserted
is guaranteed by the user to be ordered according to the predicate. This can happen when inserting values from a `set` to
a `multiset` or between different associative container families (`[multi]set/map` vs. `flat_[multi]set/map`).
[*Boost.Container] has some overloads for constructors and insertions taking an `ordered_unique_range_t` or
an `ordered_range_t` tag parameters as the first argument. When an `ordered_unique_range_t` overload is used, the
user notifies the container that the input range is ordered according to the container predicate and has no
duplicates. When an `ordered_range_t` overload is used, the
user notifies the container that the input range is ordered according to the container predicate but it might
have duplicates. With this information, the container can avoid multiple predicate calls and improve insertion
times.
[endsect]
[section:constant_time_range_splice Constant-time range splice for `(s)list`]
In the first C++ standard `list::size()` was not required to be constant-time,
and that caused some controversy in the C++ community. Quoting Howard Hinnant's
[@http://home.roadrunner.com/~hinnant/On_list_size.html ['On List Size]] paper:
[: ['There is a considerable debate on whether `std::list<T>::size()` should be O(1) or O(N).
The usual argument notes that it is a tradeoff with:]
`splice(iterator position, list& x, iterator first, iterator last);`
['If size() is O(1) and this != &x, then this method must perform a linear operation so that it
can adjust the size member in each list]]
C++11 definitely required `size()` to be O(1), so range splice became O(N). However,
Howard Hinnant's paper proposed a new `splice` overload so that even O(1) `list:size()`
implementations could achieve O(1) range splice when the range size was known to the caller:
[: `void splice(iterator position, list& x, iterator first, iterator last, size_type n);`
[*Effects]: Inserts elements in the range [first, last) before position and removes the elements from x.
[*Requires]: [first, last) is a valid range in x. The result is undefined if position is an iterator in the range [first, last). Invalidates only the iterators and references to the spliced elements. n == distance(first, last).
[*Throws]: Nothing.
[*Complexity]: Constant time.
]
This new splice signature allows the client to pass the distance of the input range in.
This information is often available at the call site. If it is passed in,
then the operation is constant time, even with an O(1) size.
[*Boost.Container] implements this overload for `list` and a modified version of it for `slist`
(as `slist::size()` is also `O(1)`).
[endsect]
[section:extended_allocators Extended allocators]
Many C++ programmers have ever wondered where does good old realloc fit in C++. And that's a good question.
Could we improve [classref boost::container::vector vector] performance using memory expansion mechanisms
to avoid too many copies? But [classref boost::container::vector vector] is not the only container that
could benefit from an improved allocator interface: we could take advantage of the insertion of multiple
elements in [classref boost::container::list list] using a burst allocation mechanism that could amortize
costs (mutex locks, free memory searches...) that can't be amortized when using single node allocation
strategies.
These improvements require extending the STL allocator interface and use make use of a new
general purpose allocator since new and delete don't offer expansion and burst capabilities.
* [*Boost.Container] containers support an extended allocator interface based on an evolution of proposals
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1953.html N1953: Upgrading the Interface of Allocators using API Versioning],
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2045.html N2045: Improving STL allocators]
and the article
[@http://www.drivehq.com/web/igaztanaga/allocplus/ Applying classic memory allocation strategies to C++ containers].
The extended allocator interface is implemented by [classref boost::container::allocator allocator],
[classref boost::container::adaptive_pool adaptive_pool] and [classref boost::container::node_allocator node_allocator]
classes.
* Extended allocators use a modified [@http://g.oswego.edu/dl/html/malloc.html Doug Lea Malloc (DLMalloc)] low-level
allocator and offers an C API to implement memory expansion and burst allocations. DLmalloc is known to be very size
and speed efficient, and this allocator is used as the basis of many malloc implementations, including multithreaded
allocators built above DLmalloc (See [@http://www.malloc.de/en/ ptmalloc2, ptmalloc3] or
[@http://www.nedprod.com/programs/portable/nedmalloc/ nedmalloc]). This low-level allocator is implemented as
a separately compiled library whereas [classref boost::container::allocator allocator],
[classref boost::container::adaptive_pool adaptive_pool] and [classref boost::container::node_allocator node_allocator]
are header-only classes.
The following extended allocators are provided:
* [classref boost::container::allocator allocator]: This extended allocator offers expansion, shrink-in place
and burst allocation capabilities implemented as a thin wrapper around the modified DLMalloc.
It can be used with all containers and it should be the default choice when the programmer wants to use
extended allocator capabilities.
* [classref boost::container::node_allocator node_allocator]: It's a
[@http://www.boost.org/doc/libs/1_55_0/libs/pool/doc/html/boost_pool/pool/pooling.html#boost_pool.pool.pooling.simple Simple Segregated Storage]
allocator, similar to [*Boost.Pool] that takes advantage of the modified DLMalloc burst interface. It does not return
memory to the DLMalloc allocator (and thus, to the system), unless explicitly requested. It does offer a very small
memory overhead so it's suitable for node containers ([boost::container::list list], [boost::container::slist slist]
[boost::container::set set]...) that allocate very small `value_type`s and it offers improved node allocation times
for single node allocations with respecto to [classref boost::container::allocator allocator].
* [classref boost::container::adaptive_pool adaptive_pool]: It's a low-overhead node allocator that can return memory
to the system. The overhead can be very low (< 5% for small nodes) and it's nearly as fast as [classref boost::container::node_allocator node_allocator].
It's also suitable for node containers.
[endsect]
[/
/a__section:previous_element_slist Previous element for slist__a
/
/The C++11 `std::forward_list` class implement a singly linked list, similar to `slist`, and these
/containers only offer forward iterators and implement insertions and splice operations that operate with ranges
/to be inserted ['after] that position. In those cases, sometimes it's interesting to obtain an iterator pointing
/to the previous element of another element. This operation can be implemented
/
/a__endsect__a
]
[/
/a__section:get_stored_allocator Obtain stored allocator__a
/
@@ -532,18 +660,6 @@ using [@http://en.cppreference.com/w/cpp/language/default_initialization default
/http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html
/
/a__endsect__a
/
/a__section:ordered_range_insertion Ordered range insertion (a__'ordered_unique_range__a, a__'ordered_range__a) __a
/
/a__endsect__a
/
/a__section:constant_time_range_splice Constant-time range splice__a
/
/a__endsect__a
/
/a__section:previous_element_slist Slist previous element__a
/
/a__endsect__a
/]
[endsect]
@@ -709,9 +825,10 @@ use [*Boost.Container]? There are several reasons for that:
* Default constructors don't allocate memory at all, which improves performance and
usually implies a no-throw guarantee (if predicate's or allocator's default constructor doesn't throw).
* Small string optimization for [classref boost::container::basic_string basic_string].
* New extensions beyond the standard based on user feedback to improve code performance.
* [link container.extended_functionality Extended functionality] beyond the standard based
on user feedback to improve code performance.
* You need a portable implementation that works when compiling without exceptions support or
you need to customize the error handling when a container needs to signall an exceptional error.
you need to customize the error handling when a container needs to signal an exceptional error.
[endsect]
@@ -759,6 +876,15 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes Release Notes]
[section:release_notes_boost_1_56_00 Boost 1.56 Release]
* Added DlMalloc-based [link container.extended_functionality.extended_allocators Extended Allocators].
* Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/9338 #9338: ['"VS2005 compiler errors in swap() definition after including container/memory_util.hpp"]].
[endsect]
[section:release_notes_boost_1_55_00 Boost 1.55 Release]
* Implemented [link container.main_features.scary_iterators SCARY iterators].
@@ -769,7 +895,8 @@ use [*Boost.Container]? There are several reasons for that:
[@https://svn.boost.org/trac/boost/ticket/9009 #9009],
[@https://svn.boost.org/trac/boost/ticket/9064 #9064],
[@https://svn.boost.org/trac/boost/ticket/9092 #9092],
[@https://svn.boost.org/trac/boost/ticket/9108 #9108].
[@https://svn.boost.org/trac/boost/ticket/9108 #9108],
[@https://svn.boost.org/trac/boost/ticket/9166 #9166],
[endsect]