forked from boostorg/container
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:
1 parent
b1d4ef3a2e
commit
f2947c115e
95 files changed
+2248
-2692
No files matched your search
+1
-1
@@ -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
@@ -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]
|
||||
|
||||
|
||||
Reference in new issue
Block a user