Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / container / doc / container.qbk
1 [/
2  / Copyright (c) 2009-2013 Ion Gazta\u00F1aga
3  /
4  / Distributed under the Boost Software License, Version 1.0. (See accompanying
5  / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  /]
7
8 [library Boost.Container
9     [quickbook 1.5]
10     [authors [Gaztanaga, Ion]]
11     [copyright 2009-2013 Ion Gaztanaga]
12     [id container]
13     [dirname container]
14     [purpose Containers library]
15     [license
16         Distributed under the Boost Software License, Version 1.0.
17         (See accompanying file LICENSE_1_0.txt or copy at
18         [@http://www.boost.org/LICENSE_1_0.txt])
19     ]
20 ]
21
22 [template super[x]'''<superscript>'''[x]'''</superscript>''']
23 [template sub[x]'''<subscript>'''[x]'''</subscript>''']
24
25 [section:intro Introduction]
26
27 [*Boost.Container] library implements several well-known containers, including
28 STL containers. The aim of the library is to offers advanced features not present
29 in standard containers or to offer the latest standard draft features for compilers
30 that comply with C++03.
31
32 In short, what does [*Boost.Container] offer?
33
34 * Move semantics are implemented, including move emulation for pre-C++11 compilers.
35 * New advanced features (e.g. placement insertion, recursive containers) are present.
36 * Containers support stateful allocators and are compatible with [*Boost.Interprocess]
37   (they can be safely placed in shared memory).
38 * The library offers new useful containers:
39   * [classref boost::container::flat_map flat_map],
40     [classref boost::container::flat_set flat_set],
41     [classref boost::container::flat_multimap flat_multimap] and
42     [classref boost::container::flat_multiset flat_multiset]: drop-in
43     replacements for standard associative containers but more memory friendly and with faster
44     searches.
45   * [classref boost::container::stable_vector stable_vector]: a std::list and std::vector hybrid
46     container: vector-like random-access iterators and list-like iterator stability in insertions and erasures.
47   * [classref boost::container::slist slist]: the classic pre-standard singly linked list implementation
48     offering constant-time `size()`. Note that C++11 `forward_list` has no `size()`.
49
50 [section:introduction_building_container Building Boost.Container]
51
52 There is no need to compile [*Boost.Container] if you don't use [link container.extended_functionality.extended_allocators Extended Allocators]
53 since in that case it's a header-only library. Just include your Boost header directory in your compiler include path.
54
55 [link container.extended_functionality.extended_allocators Extended Allocators] are
56 implemented as a separately compiled library, so you must install binaries in a location that can be found by your linker
57 when using these classes. If you followed the [@http://www.boost.org/doc/libs/release/more/getting_started/index.html Boost Getting Started] instructions,
58 that's already been done for you.
59
60 [endsect]
61
62 [section:tested_compilers Tested compilers]
63
64 [*Boost.Container] requires a decent C++98 compatibility. Some compilers known to work are:
65
66 *  Visual C++ >= 7.1.
67 *  GCC >= 4.1.
68 *  Intel C++ >= 9.0
69
70 [endsect]
71
72 [endsect]
73
74 [section:main_features Main features]
75
76 [section:move_emplace Efficient insertion]
77
78 Move semantics and placement insertion are two features brought by C++11 containers
79 that can have a very positive impact in your C++ applications. Boost.Container implements
80 both techniques both for C++11 and C++03 compilers.
81
82 [section:move_containers Move-aware containers]
83
84 All containers offered by [*Boost.Container] can store movable-only types
85 and actual requirements for `value_type` depend on each container operations.
86 Following C++11 requirements even for C++03 compilers, many operations now require
87 movable or default constructible types instead of just copy constructible types.
88
89 Containers themselves are also movable, with no-throw guarantee if allocator
90 or predicate (if present) copy operations are no-throw. This allows
91 high performance operations when transferring data between vectors.
92 Let's see an example:
93
94 [import ../example/doc_move_containers.cpp]
95 [doc_move_containers]
96
97 [endsect]
98
99 [section:emplace Emplace: Placement insertion]
100
101 All containers offered by [*Boost.Container] implement placement insertion,
102 which means that  objects can be built directly into the container from user arguments
103 without creating any temporary object. For compilers without variadic templates support
104 placement insertion is emulated up to a finite (10) number of arguments.
105
106 Expensive to move types are perfect candidates emplace functions and in case of node containers
107 ([classref boost::container::list list], [classref boost::container::set set], ...)
108 emplace allows storing non-movable and non-copyable types in containers! Let's
109 see an example:
110
111 [import ../example/doc_emplace.cpp]
112 [doc_emplace]
113
114 [endsect]
115
116 [endsect]
117
118
119 [section:containers_of_incomplete_types Containers of Incomplete Types]
120
121 Incomplete types allow
122 [@http://en.wikipedia.org/wiki/Type_erasure [*type erasure ]] and
123 [@http://en.wikipedia.org/wiki/Recursive_data_type [*recursive data types]], and
124 C and C++ programmers have been using it for years to build complex data structures, like
125 tree structures where a node may have an arbitrary number of children.
126
127 What about standard containers? Containers of incomplete types have been under discussion for a long time,
128 as explained in Matt Austern's great article ([@http://drdobbs.com/184403814 [*The Standard Librarian: Containers of Incomplete Types]]):
129
130 ["['Unlike most of my columns, this one is about something you can't do with the C++ Standard library:
131 put incomplete types in one of the standard containers. This column explains why you might want to
132 do this, why the standardization committee banned it even though they knew it was useful, and what
133 you might be able to do to get around the restriction.]]
134
135 ["['In 1997, shortly before the C++ Standard was completed, the standardization committee received a
136 query: Is it possible to create standard containers with incomplete types? It took a while for the
137 committee to understand the question. What would such a thing even mean, and why on earth would you
138 ever want to do it? The committee eventually worked it out and came up with an answer to the question.
139 (Just so you don't have to skip ahead to the end, the answer is "no.") But the question is much more
140 interesting than the answer: it points to a useful, and insufficiently discussed, programming technique.
141 The standard library doesn't directly support that technique, but the two can be made to coexist.]]
142
143 ["['In a future revision of C++, it might make sense to relax the restriction on instantiating
144 standard library templates with incomplete types. Clearly, the general prohibition should stay
145 in place - instantiating templates with incomplete types is a delicate business, and there are
146 too many classes in the standard library where it would make no sense. But perhaps it should be
147 relaxed on a case-by-case basis, and `vector` looks like a good candidate for such special-case
148 treatment: it's the one standard container class where there are good reasons to instantiate
149 it with an incomplete type and where Standard Library implementors want to make it work. As of
150 today, in fact, implementors would have to go out of their way to prohibit it!]]
151
152 C++11 standard is also cautious about incomplete types and STL: ["['17.6.4.8 Other functions (...) 2.
153 the effects are undefined in the following cases: (...) In particular - if an incomplete type (3.9)
154 is used as a template argument when instantiating a template component,
155 unless specifically allowed for that component]].
156
157 Fortunately all [*Boost.Container] containers except
158 [classref boost::container::static_vector static_vector] and
159 [classref boost::container::basic_string basic_string] are designed to support incomplete types.
160 [classref boost::container::static_vector static_vector] is special because
161 it statically allocates memory for `value_type` and this requires complete types and
162 [classref boost::container::basic_string basic_string] implements Small String Optimization which
163 also requires complete types.
164
165 [*Boost.Container] containers supporting incomplete types also support instantiating iterators to
166 those incomplete elements.
167
168 [section:recursive_containers Recursive containers]
169
170 Most [*Boost.Container] containers can be used to define recursive containers:
171
172 [import ../example/doc_recursive_containers.cpp]
173 [doc_recursive_containers]
174
175 [endsect]
176
177 [section:type_erasure Type Erasure]
178
179 Containers of incomplete types are useful to break header file dependencies and improve
180 compilation types. With Boost.Container, you can write a header file defining a class
181 with containers of incomplete types as data members, if you carefully put all the
182 implementation details that require knowing the size of the `value_type` in your
183 implementation file:
184
185 [import ../example/doc_type_erasure.cpp]
186
187 In this header file we define a class (`MyClassHolder)` that holds a `vector` of an
188 incomplete type (`MyClass`) that it's only forward declared.
189
190 [doc_type_erasure_MyClassHolder_h]
191
192 Then we can define `MyClass` in its own header file.
193
194 [doc_type_erasure_MyClass_h]
195
196 And include it only in the implementation file of `MyClassHolder`
197
198 [doc_type_erasure_MyClassHolder_cpp]
199
200 Finally, we can just compile, link, and run!
201
202 [doc_type_erasure_main_cpp]
203
204 [endsect]
205
206 [endsect]
207
208 [section:scary_iterators SCARY iterators]
209
210 The paper N2913, titled [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2913.pdf,
211 SCARY Iterator Assignment and Initialization], proposed a requirement that a standard container's
212 iterator types have no dependency on any type argument apart from the container's `value_type`,
213 `difference_type`, `pointer type`, and `const_pointer` type. In particular, according to the proposal,
214 the types of a standard container's iterators should not depend on the container's `key_compare`,
215 `hasher`, `key_equal`, or `allocator` types.
216
217 That paper demonstrated that SCARY operations were crucial to the performant implementation of common
218 design patterns using STL components. It showed that implementations that support SCARY operations reduce
219 object code bloat by eliminating redundant specializations of iterator and algorithm templates.
220
221 [*Boost.Container] containers implement SCARY iterators so the iterator type of a container is only dependent
222 on the `allocator_traits<allocator_type>::pointer` type (the pointer type of the `value_type` to be inserted
223 in the container). Reference types and all other typedefs are deduced from the pointer type using the
224 C++11 `pointer_traits` utility. This leads to lower code bloat in algorithms and classes templated on
225 iterators.
226
227 [endsect]
228
229 [section:other_features Other features]
230
231 * Default constructors don't allocate memory which improves performance and
232   usually implies a no-throw guarantee (if predicate's or allocator's default constructor doesn't throw).
233
234 * Small string optimization for [classref boost::container::basic_string basic_string],
235   with an internal buffer of 11/23 bytes (32/64 bit systems)
236   [*without] increasing the usual `sizeof` of the string (3 words).
237
238 * `[multi]set/map` containers are size optimized embedding the color bit of the red-black tree nodes
239    in the parent pointer.
240
241 * `[multi]set/map` containers use no recursive functions so stack problems are avoided.
242
243 [endsect]
244
245 [endsect]
246
247 [section:exception_handling Boost.Container and C++ exceptions]
248
249 In some environments, such as game development or embedded systems, C++ exceptions are disabled or a customized error handling is needed.
250 According to document [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html N2271 EASTL -- Electronic Arts Standard Template Library]
251 exceptions can be disabled for several reasons:
252
253 *  ["['Exception handling incurs some kind of cost in all compiler implementations, including those that avoid
254    the cost during normal execution. However, in some cases this cost may arguably offset the cost of the code that it is replacing.]]
255 *  ["['Exception handling is often agreed to be a superior solution for handling a large range of function return values. However,
256    avoiding the creation of functions that need large ranges of return values is superior to using exception handling to handle such values.]]
257 *  ["['Using exception handling correctly can be difficult in the case of complex software.]]
258 *  ["['The execution of throw and catch can be significantly expensive with some implementations.]]
259 *  ["['Exception handling violates the don't-pay-for-what-you-don't-use design of C++, as it incurs overhead in any non-leaf function that
260    has destructible stack objects regardless of whether they use exception handling.]]
261 *  ["['The approach that game software usually takes is to avoid the need for exception handling where possible; avoid the possibility
262    of circumstances that may lead to exceptions. For example, verify up front that there is enough memory for a subsystem to do its job
263    instead of trying to deal with the problem via exception handling or any other means after it occurs.]]
264 *  ["['However, some game libraries may nevertheless benefit from the use of exception handling. It's best, however,
265    if such libraries keep the exception handling internal lest they force their usage of exception handling on the rest of the application.]]
266
267 In order to support environments without C++ exception support or environments with special error handling needs,
268 [*Boost.Container] changes error signalling behaviour when `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` or `BOOST_NO_EXCEPTIONS`
269 is defined. The former shall be defined by the user and the latter can be either defined by the user or implicitly defined by [*Boost.Confg]
270 when the compiler has been invoked with the appropriate flag (like `-fno-exceptions` in GCC).
271
272 When dealing with user-defined classes, (e.g. when constructing user-defined classes):
273
274 *  If `BOOST_NO_EXCEPTIONS` is defined, the library avoids using `try`/`catch`/`throw` statements. The class writer must handle and
275    propagate error situations internally as no error will be propagated through [*Boost.Container].
276 *  If `BOOST_NO_EXCEPTIONS` is *not* defined, the library propagates exceptions offering the exception guarantees detailed in the documentation.
277
278 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
279 a throw-callback declared in [headerref boost/container/throw_exception.hpp]:
280
281 *  If `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` is defined, then the programmer must provide its own definition for all
282    `throw_xxx` functions. Those functions can't return, they must throw an exception or call `std::exit` or `std::abort`.
283 *  Else if `BOOST_NO_EXCEPTIONS` is defined, a `BOOST_ASSERT_MSG` assertion is triggered
284    (see [@http://www.boost.org/libs/utility/assert.html Boost.Assert] for more information).
285    If this assertion returns, then `std::abort` is called.
286 *  Else, an appropriate standard library exception is thrown (like `std::out_of_range`).
287
288 [endsect]
289
290 [section:non_standard_containers Non-standard containers]
291
292 [section:stable_vector ['stable_vector]]
293
294 This useful, fully STL-compliant stable container [@http://bannalia.blogspot.com/2008/09/introducing-stablevector.html designed by Joaqu\u00EDn M. L\u00F3pez Mu\u00F1oz]
295 is an hybrid between `vector` and `list`, providing most of
296 the features of `vector` except [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#69 element contiguity].
297
298 Extremely convenient as they are, `vector`s have a limitation that many novice C++ programmers frequently stumble upon:
299 iterators and references to an element of an `vector` are invalidated when a preceding element is erased or when the
300 vector expands and needs to migrate its internal storage to a wider memory region (i.e. when the required size exceeds
301 the vector's capacity). We say then that `vector`s are unstable: by contrast, stable containers are those for which
302 references and iterators to a given element remain valid as long as the element is not erased: examples of stable containers
303 within the C++ standard library are `list` and the standard associative containers (`set`, `map`, etc.).
304
305 Sometimes stability is too precious a feature to live without, but one particular property of `vector`s, element contiguity,
306 makes it impossible to add stability to this container. So, provided we sacrifice element contiguity, how much
307 can a stable design approach the behavior of `vector` (random access iterators, amortized constant time end
308 insertion/deletion, minimal memory overhead, etc.)?
309 The following image describes the layout of a possible data structure upon which to base the design of a stable vector:
310
311 [$../../libs/container/doc/html/images/stable_vector.png  [width 50%] [align center] ]
312
313 Each element is stored in its own separate node. All the nodes are referenced from a contiguous array of pointers, but
314 also every node contains an "up" pointer referring back to the associated array cell. This up pointer is the key element
315 to implementing stability and random accessibility:
316
317 Iterators point to the nodes rather than to the pointer array. This ensures stability, as it is only the pointer array
318 that needs to be shifted or relocated upon insertion or deletion. Random access operations can be implemented by using
319 the pointer array as a convenient intermediate zone. For instance, if the iterator it holds a node pointer `it.p` and we
320 want to advance it by n positions, we simply do:
321
322 [c++]
323
324    it.p = *(it.p->up+n);
325
326 That is, we go "up" to the pointer array, add n there and then go "down" to the resulting node.
327
328 [*General properties]. `stable_vector` satisfies all the requirements of a container, a reversible container and a sequence
329 and provides all the optional operations present in vector. Like vector, iterators are random access. `stable_vector`
330 does not provide element contiguity; in exchange for this absence, the container is stable, i.e. references and iterators
331 to an element of a `stable_vector` remain valid as long as the element is not erased, and an iterator that has been
332 assigned the return value of end() always remain valid until the destruction of the associated `stable_vector`.
333
334 [*Operation complexity]. The big-O complexities of `stable_vector` operations match exactly those of vector. In general,
335 insertion/deletion is constant time at the end of the sequence and linear elsewhere. Unlike vector, `stable_vector`
336 does not internally perform any value_type destruction, copy/move construction/assignment operations other than those exactly
337 corresponding to the insertion of new elements or deletion of stored elements, which can sometimes compensate in terms of
338 performance for the extra burden of doing more pointer manipulation and an additional allocation per element.
339
340 [*Exception safety]. (according to [@http://www.boost.org/community/exception_safety.html Abrahams' terminology])
341 As `stable_vector` does not internally copy/move elements around, some
342 operations provide stronger exception safety guarantees than in vector:
343
344 [table:stable_vector_req Exception safety
345     [[operation] [exception safety for `vector<T>`] [exception safety for `stable_vector<T>`]]
346     [[insert]    [strong unless copy/move construction/assignment of `T` throw (basic)]     [strong]]
347     [[erase]     [no-throw unless copy/move construction/assignment  of `T` throw (basic)]     [no-throw]]
348 ]
349
350 [*Memory overhead]. The C++ standard does not specifiy requirements on memory consumption, but virtually any implementation
351 of `vector` has the same behavior wih respect to memory usage: the memory allocated by a `vector` v with n elements of type T
352 is
353
354 m[sub v] = c\u2219e,
355
356 where c is `v.capacity()` and e is `sizeof(T)`. c can be as low as n if the user has explicitly reserved the exact capacity
357 required; otherwise, the average value c for a growing `vector` oscillates between 1.25\u2219n and 1.5\u2219n for typical resizing
358 policies. For `stable_vector`, the memory usage is
359
360 m[sub sv] = (c + 1)p + (n + 1)(e + p),
361
362 where p is the size of a pointer. We have c + 1 and n + 1 rather than c and n because a dummy node is needed at the end of
363 the sequence. If we call f the capacity to size ratio c/n and assume that n is large enough, we have that
364
365 m[sub sv]/m[sub v] \u2243 (fp + e + p)/fe.
366
367 So, `stable_vector` uses less memory than `vector` only when e > p and the capacity to size ratio exceeds a given threshold:
368
369 m[sub sv] < m[sub v] <-> f > (e + p)/(e - p). (provided e > p)
370
371 This threshold approaches typical values of f below 1.5 when e > 5p; in a 32-bit architecture, when e > 20 bytes.
372
373 [*Summary]. `stable_vector` is a drop-in replacement for `vector` providing stability of references and iterators, in exchange
374 for missing element contiguity and also some performance and memory overhead. When the element objects are expensive to
375 move around, the performance overhead can turn into a net performance gain for `stable_vector` if many middle insertions
376 or deletions are performed or if resizing is very frequent. Similarly, if the elements are large there are situations when
377 the memory used by `stable_vector` can actually be less than required by vector.
378
379 ['Note: Text and explanations taken from [@http://bannalia.blogspot.com/2008/09/introducing-stablevector.html Joaqu\u00EDn's blog]]
380
381 [endsect]
382
383 [section:flat_xxx ['flat_(multi)map/set] associative containers]
384
385 Using sorted vectors instead of tree-based associative containers is a well-known technique in
386 C++ world. Matt Austern's  classic article
387 [@http://lafstern.org/matt/col1.pdf Why You Shouldn't Use set, and What You Should Use Instead]
388 (C++ Report 12:4, April 2000) was enlightening:
389
390 ["['Red-black trees aren't the only way to organize data that permits lookup in logarithmic time.  One of the basic
391 algorithms of computer science is binary search, which works by successively dividing a range in half. Binary
392 search is log N and it doesn't require any fancy data structures, just a sorted collection of elements.
393 (...) You can use whatever data structure is convenient, so long as it provides STL iterator;
394 usually it's easiest to use a C array, or a vector.]]
395
396 ["['Both std::lower_bound and set::find take time proportional to log N, but the constants of proportionality
397 are very different.  Using g++ (...) it takes X seconds to perform a million lookups in a
398 sorted vector<double> of a million elements, and almost twice as long (...) using a set. Moreover,
399 the set uses almost three times as much memory (48 million bytes) as the vector (16.8 million).]]
400
401 ["['Using a sorted vector instead of a set gives you faster lookup and much faster iteration,
402 but at the cost of slower insertion.  Insertion into a set, using set::insert, is proportional
403 to log N, but insertion into a sorted vector, (...)
404 , is proportional to N. Whenever you insert something into a vector,
405 vector::insert has to make room by shifting all of the elements that follow it.  On average, if you're equally
406 likely to insert a new element anywhere, you'll be shifting N/2 elements.]]
407
408 ["['It may sometimes be convenient to bundle all of this together into a small container adaptor.
409 This class does not satisfy the requirements of a Standard Associative Container, since the complexity of insert is
410 O(N) rather than O(log N), but otherwise it is almost a drop-in replacement for set.]]
411
412 Following Matt Austern's indications, Andrei Alexandrescu's
413 [@http://www.bestwebbuys.com/Modern-C-Design-Generic-Programming-and-Design-Patterns-Applied-ISBN-9780201704310?isrc=-rd Modern C++ Design]
414 showed `AssocVector`, a `std::map` drop-in
415 replacement designed in his [@http://loki-lib.sourceforge.net/ Loki] library:
416
417 ["['It seems as if we're better off with a sorted vector. The disadvantages of a sorted
418 vector are linear-time insertions and linear-time deletions (...). In exchange, a vector
419 offers about twice the lookup speed and a much smaller working set (...).
420 Loki saves the trouble of maintaining a sorted vector by hand by defining an AssocVector class
421 template. AssocVector is a drop-in replacement for std::map (it supports the same set of member
422 functions), implemented on top of std::vector. AssocVector differs from a map in the behavior of
423 its erase functions (AssocVector::erase invalidates all iterators into the object) and in the
424 complexity guarantees of insert and erase (linear as opposed to constant). ]]
425
426 [*Boost.Container] `flat_[multi]map/set` containers are ordered-vector based associative containers
427 based on Austern's and Alexandrescu's guidelines. These ordered vector containers have also
428 benefited recently with the addition of `move semantics` to C++, speeding up insertion
429 and erasure times considerably. Flat associative containers have the following
430 attributes:
431
432 * Faster lookup than standard associative containers
433 * Much faster iteration than standard associative containers.
434    Random-access iterators instead of bidirectional iterators.
435 * Less memory consumption for small objects (and for big objects if `shrink_to_fit` is used)
436 * Improved cache performance (data is stored in contiguous memory)
437 * Non-stable iterators (iterators are invalidated when inserting and erasing elements)
438 * Non-copyable and non-movable values types can't be stored
439 * Weaker exception safety than standard associative containers
440 (copy/move constructors can throw when shifting values in erasures and insertions)
441 * Slower insertion and erasure than standard associative containers (specially for non-movable types)
442
443 [endsect]
444
445 [section:slist ['slist]]
446
447 When the standard template library was designed, it contained a singly linked list called `slist`.
448 Unfortunately, this container was not standardized and remained as an extension for many standard
449 library implementations until C++11 introduced `forward_list`, which is a bit different from the
450 the original SGI `slist`. According to [@http://www.sgi.com/tech/stl/Slist.html SGI STL documentation]:
451
452 ["['An `slist` is a singly linked list: a list where each element is linked to the next element, but
453 not to the previous element. That is, it is a Sequence that supports forward but not backward traversal,
454 and (amortized) constant time insertion and removal of elements. Slists, like lists, have the important
455 property that insertion and splicing do not invalidate iterators to list elements, and that even removal
456 invalidates only the iterators that point to the elements that are removed. The ordering of iterators
457 may be changed (that is, slist<T>::iterator might have a different predecessor or successor after a list
458 operation than it did before), but the iterators themselves will not be invalidated or made to point to
459 different elements unless that invalidation or mutation is explicit.]]
460
461 ["['The main difference between `slist` and list is that list's iterators are bidirectional iterators,
462 while slist's iterators are forward iterators. This means that `slist` is less versatile than list;
463 frequently, however, bidirectional iterators are unnecessary. You should usually use `slist` unless
464 you actually need the extra functionality of list, because singly linked lists are smaller and faster
465 than double linked lists.]]
466
467 ["['Important performance note: like every other Sequence, `slist` defines the member functions insert and erase.
468 Using these member functions carelessly, however, can result in disastrously slow programs. The problem is that
469 insert's first argument is an iterator pos, and that it inserts the new element(s) before pos. This means that
470 insert must find the iterator just before pos; this is a constant-time operation for list, since list has
471 bidirectional iterators, but for `slist` it must find that iterator by traversing the list from the beginning
472 up to pos. In other words: insert and erase are slow operations anywhere but near the beginning of the slist.]]
473
474 ["['Slist provides the member functions insert_after and erase_after, which are constant time operations: you should
475 always use insert_after and erase_after whenever possible. If you find that insert_after and erase_after aren't
476 adequate for your needs, and that you often need to use insert and erase in the middle of the list, then you
477 should probably use list instead of slist.]]
478
479 [*Boost.Container] updates the classic `slist` container with C++11 features like move semantics and placement
480 insertion and implements it a bit differently than the standard C++ `forward_list`. `forward_list` has no `size()`
481 method, so it's been designed to allow (or in practice, encourage) implementations without tracking list size
482 with every insertion/erasure, allowing constant-time
483 `splice_after(iterator, forward_list &, iterator, iterator)`-based list merging. On the other hand `slist` offers
484 constant-time `size()` for those that don't care about linear-time `splice_after(iterator, slist &, iterator, iterator)`
485 `size()` and offers an additional `splice_after(iterator, slist &, iterator, iterator, size_type)` method that
486 can speed up `slist` merging when the programmer already knows the size. `slist` and `forward_list` are therefore
487 complementary.
488
489 [endsect]
490
491 [section:static_vector ['static_vector]]
492
493 `static_vector` is an hybrid between `vector` and `array`: like `vector`, it's a sequence container
494 with contiguous storage that can change in size, along with the static allocation, low overhead,
495 and fixed capacity of `array`. `static_vector` is based on Adam Wulkiewicz and Andrew Hundt's
496 high-performance [@https://svn.boost.org/svn/boost/sandbox/varray/doc/html/index.html varray]
497 class.
498
499 The number of elements in a `static_vector` may vary dynamically up to a fixed capacity
500 because elements are stored within the object itself similarly to an array. However, objects are
501 initialized as they are inserted into `static_vector` unlike C arrays or `std::array` which must construct
502 all elements on instantiation. The behavior of `static_vector` enables the use of statically allocated
503 elements in cases with complex object lifetime requirements that would otherwise not be trivially
504 possible. Some other properties:
505
506 * Random access to elements
507 * Constant time insertion and removal of elements at the end
508 * Linear time insertion and removal of elements at the beginning or in the middle.
509
510 `static_vector` is well suited for use in a buffer, the internal implementation of other
511 classes, or use cases where there is a fixed limit to the number of elements that must be stored.
512 Embedded and realtime applications where allocation either may not be available or acceptable
513 are a particular case where `static_vector` can be beneficial.
514
515 [endsect]
516
517 [endsect]
518
519 [section:extended_functionality Extended functionality]
520
521 [section:default_initialialization Default initialization for vector-like containers]
522
523 STL and most other containers value initialize new elements in common operations like
524 `vector::resize(size_type n)` or `explicit vector::vector(size_type n)`.
525
526 In some performance-sensitive environments, where vectors are used as a replacement for
527 variable-size buffers for file or network operations,
528 [@http://en.cppreference.com/w/cpp/language/value_initialization value initialization]
529 is a cost that is not negligible as elements are going to be overwritten by an external source
530 shortly after new elements are added to the container.
531
532 [*Boost.Container] offers two new members for `vector`, `static_vector` and `stable_vector`:
533 `explicit container::container(size_type n, default_init_t)` and
534 `explicit container::resize(size_type n, default_init_t)`, where new elements are constructed
535 using [@http://en.cppreference.com/w/cpp/language/default_initialization default initialization].
536
537 [endsect]
538
539 [section:ordered_range_insertion Ordered range insertion for associative containers (['ordered_unique_range], ['ordered_range]) ]
540
541 When filling associative containers big performance gains can be achieved if the input range to be inserted
542 is guaranteed by the user to be ordered according to the predicate. This can happen when inserting values from a `set` to
543 a `multiset` or between different associative container families (`[multi]set/map` vs. `flat_[multi]set/map`).
544
545 [*Boost.Container] has some overloads for constructors and insertions taking an `ordered_unique_range_t` or
546 an `ordered_range_t` tag parameters as the first argument. When an `ordered_unique_range_t` overload is used, the
547 user notifies the container that the input range is ordered according to the container predicate and has no
548 duplicates. When an `ordered_range_t` overload is used, the
549 user notifies the container that the input range is ordered according to the container predicate but it might
550 have duplicates. With this information, the container can avoid multiple predicate calls and improve insertion
551 times.
552
553 [endsect]
554
555 [section:configurable_tree_based_associative_containers Configurable tree-based associative ordered containers]
556
557 [classref boost::container::set set], [classref boost::container::multiset multiset],
558 [classref boost::container::map map] and [classref boost::container::multimap multimap] associative containers
559 are implemented as binary search trees which offer the needed complexity and stability guarantees required by the
560 C++ standard for associative containers.
561
562 [*Boost.Container] offers the possibility to configure at compile time some parameters of the binary search tree
563 implementation. This configuration is passed as the last template parameter and defined using the utility class
564 [classref boost::container::tree_assoc_options tree_assoc_options].
565
566 The following parameters can be configured:
567
568 *  The underlying [*tree implementation] type ([classref boost::container::tree_type tree_type]).
569    By default these containers use a red-black tree but the user can use other tree types:
570    *  [@http://en.wikipedia.org/wiki/Red%E2%80%93black_tree Red-Black Tree]
571    *  [@http://en.wikipedia.org/wiki/Avl_trees AVL tree]
572    *  [@http://en.wikipedia.org/wiki/Scapegoat_tree Scapegoat tree]. In this case Insertion and Deletion
573       are amortized O(log n) instead of O(log n).
574    *  [@http://en.wikipedia.org/wiki/Splay_tree Splay tree]. In this case Searches, Insertions and Deletions
575       are amortized O(log n) instead of O(log n).
576
577 *  Whether the [*size saving] mechanisms are used to implement the tree nodes
578    ([classref boost::container::optimize_size optimize_size]). By default this option is activated and is only
579    meaningful to red-black and avl trees (in other cases, this option will be ignored).
580    This option will try to put rebalancing metadata inside the "parent" pointer of the node if the pointer
581    type has enough alignment. Usually, due to alignment issues, the metadata uses the size of a pointer yielding
582    to four pointer size overhead per node, whereas activating this option usually leads to 3 pointer size overhead.
583    Although some mask operations must be performed to extract
584    data from this special "parent" pointer, in several systems this option also improves performance due to the
585    improved cache usage produced by the node size reduction.
586
587 See the following example to see how [classref boost::container::tree_assoc_options tree_assoc_options] can be
588 used to customize these containers:
589
590 [import ../example/doc_custom_tree.cpp]
591 [doc_custom_tree]
592
593 [endsect]
594
595 [section:constant_time_range_splice Constant-time range splice for `(s)list`]
596
597 In the first C++ standard `list::size()` was not required to be constant-time,
598 and that caused some controversy in the C++ community. Quoting Howard Hinnant's
599 [@http://home.roadrunner.com/~hinnant/On_list_size.html ['On List Size]] paper:
600
601 [: ['There is a considerable debate on whether `std::list<T>::size()` should be O(1) or O(N).
602 The usual argument notes that it is a tradeoff with:]
603
604 `splice(iterator position, list& x, iterator first, iterator last);`
605
606 ['If size() is O(1) and this != &x, then this method must perform a linear operation so that it
607 can adjust the size member in each list]]
608
609 C++11 definitely required `size()` to be O(1), so range splice became O(N). However,
610 Howard Hinnant's paper proposed a new `splice` overload so that even O(1) `list:size()`
611 implementations could achieve O(1) range splice when the range size was known to the caller:
612
613 [: `void splice(iterator position, list& x, iterator first, iterator last, size_type n);`
614
615    [*Effects]: Inserts elements in the range [first, last) before position and removes the elements from x.
616
617    [*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).
618
619    [*Throws]: Nothing.
620
621    [*Complexity]: Constant time.
622 ]
623
624 This new splice signature allows the client to pass the distance of the input range in.
625 This information is often available at the call site. If it is passed in,
626 then the operation is constant time, even with an O(1) size.
627
628 [*Boost.Container] implements this overload for `list` and a modified version of it for `slist`
629 (as `slist::size()` is also `O(1)`).
630
631 [endsect]
632
633 [section:extended_allocators Extended allocators]
634
635 Many C++ programmers have ever wondered where does good old realloc fit in C++. And that's a good question.
636 Could we improve [classref boost::container::vector vector] performance using memory expansion mechanisms
637 to avoid too many copies? But [classref boost::container::vector vector] is not the only container that
638 could benefit from an improved allocator interface: we could take advantage of the insertion of multiple
639 elements in [classref boost::container::list list] using a burst allocation mechanism that could amortize
640 costs (mutex locks, free memory searches...) that can't be amortized when using single node allocation
641 strategies.
642
643 These improvements require extending the STL allocator interface and use make use of a new
644 general purpose allocator since new and delete don't offer expansion and burst capabilities.
645
646 *  [*Boost.Container] containers support an extended allocator interface based on an evolution of proposals
647 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1953.html N1953: Upgrading the Interface of Allocators using API Versioning],
648 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2045.html N2045: Improving STL allocators]
649 and the article
650 [@http://www.drivehq.com/web/igaztanaga/allocplus/ Applying classic memory allocation strategies to C++ containers].
651 The extended allocator interface is implemented by [classref boost::container::allocator allocator],
652 [classref boost::container::adaptive_pool adaptive_pool] and [classref boost::container::node_allocator node_allocator]
653 classes.
654
655 *  Extended allocators use a modified [@http://g.oswego.edu/dl/html/malloc.html Doug Lea Malloc (DLMalloc)] low-level
656 allocator and offers an C API to implement memory expansion and burst allocations. DLmalloc is known to be very size
657 and speed efficient, and this allocator is used as the basis of many malloc implementations, including multithreaded
658 allocators built above DLmalloc (See [@http://www.malloc.de/en/ ptmalloc2, ptmalloc3] or
659 [@http://www.nedprod.com/programs/portable/nedmalloc/ nedmalloc]). This low-level allocator is implemented as
660 a separately compiled library whereas [classref boost::container::allocator allocator],
661 [classref boost::container::adaptive_pool adaptive_pool] and [classref boost::container::node_allocator node_allocator]
662 are header-only classes.
663
664 The following extended allocators are provided:
665
666 *  [classref boost::container::allocator allocator]: This extended allocator offers expansion, shrink-in place
667    and burst allocation capabilities implemented as a thin wrapper around the modified DLMalloc.
668    It can be used with all containers and it should be the default choice when the programmer wants to use
669    extended allocator capabilities.
670
671 *  [classref boost::container::node_allocator node_allocator]: It's a
672    [@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]
673    allocator, similar to [*Boost.Pool] that takes advantage of the modified DLMalloc burst interface. It does not return
674    memory to the DLMalloc allocator (and thus, to the system), unless explicitly requested. It does offer a very small
675    memory overhead so it's suitable for node containers ([boost::container::list list], [boost::container::slist slist]
676    [boost::container::set set]...) that allocate very small `value_type`s and it offers improved node allocation times
677    for single node allocations with respecto to [classref boost::container::allocator allocator].
678
679 *  [classref boost::container::adaptive_pool adaptive_pool]: It's a low-overhead node allocator that can return memory
680    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].
681    It's also suitable for node containers.
682
683 Use them simply specifying the new allocator in the corresponding template argument of your favourite container:
684
685 [import ../example/doc_extended_allocators.cpp]
686 [doc_extended_allocators]
687
688 [endsect]
689
690 [/
691 /a__section:previous_element_slist Previous element for slist__a
692 /
693 /The C++11 `std::forward_list` class implement a singly linked list, similar to `slist`, and these
694 /containers only offer forward iterators and implement insertions and splice operations that operate with ranges
695 /to be inserted ['after] that position. In those cases, sometimes it's interesting to obtain an iterator pointing
696 /to the previous element of another element. This operation can be implemented
697 /
698 /a__endsect__a
699 ]
700
701 [/
702 /a__section:get_stored_allocator Obtain stored allocator__a
703 /
704 /STL containers offer a `get_allocator()` member to obtain a copy of the allocator that
705 /the container is using to allocate and construct elements. For performance reasons, some
706 /applications need o
707 /
708 /http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html
709 /
710 /a__endsect__a
711 /]
712
713 [endsect]
714
715 [section:Cpp11_conformance C++11/C++14 Conformance]
716
717 [*Boost.Container] aims for full C++11 conformance except reasoned deviations,
718 backporting as much as possible for C++03. Obviously, this conformance is a work
719 in progress so this section explains what C++11 features are implemented and which of them
720 have been backported to C++03 compilers.
721
722 [section:move_emplace Move and Emplace]
723
724 For compilers with rvalue references and for those C++03 types that use
725 [@http://www.boost.org/libs/move Boost.Move] rvalue reference emulation
726 [*Boost.Container] supports all C++11 features related to move semantics: containers
727 are movable, requirements for `value_type` are those specified for C++11 containers.
728
729 For compilers with variadic templates, [*Boost.Container] supports placement insertion
730 (`emplace`, ...) functions from C++11. For those compilers without variadic templates
731 support [*Boost.Container] uses the preprocessor to create a set of overloads up to
732 a finite (10) number of parameters.
733
734 [endsect]
735
736 [section:alloc_traits_move_traits Stateful allocators]
737
738 C++03 was not stateful-allocator friendly. For compactness of container objects and for
739 simplicity, it did not require containers to support allocators with state: Allocator objects
740 need not be stored in container objects. It was not possible to store an allocator with state,
741 say an allocator that holds a pointer to an arena from which to allocate. C++03 allowed implementors
742 to suppose two allocators of the same type always compare equal (that means that memory allocated
743 by one allocator object could be deallocated by another instance of the same type) and
744 allocators were not swapped when the container was swapped.
745
746 C++11 further improves stateful allocator support through
747 [@http://en.cppreference.com/w/cpp/memory/allocator_traits `std::allocator_traits`].
748 `std::allocator_traits` is the protocol between a container and an allocator, and
749 an allocator writer can customize its behaviour (should the container propagate it in
750 move constructor, swap, etc.?) following `allocator_traits` requirements. [*Boost.Container]
751 not only supports this model with C++11 but also [*backports it to C++03] via
752 [classref boost::container::allocator_traits boost::container::allocator_traits]. This class
753 offers some workarounds for C++03 compilers to achieve the same allocator guarantees as
754 `std::allocator_traits`.
755
756 In [Boost.Container] containers, if possible, a single allocator is hold to construct
757 `value_type`s. If the container needs an auxiliary
758 allocator (e.g. an array allocator used by `deque` or `stable_vector`), that allocator is also
759 stored in the container and initialized from the user-supplied allocator when the
760 container is constructed (i.e. it's not constructed on the fly when auxiliary memory is needed).
761
762 [endsect]
763
764 [section:scoped_allocator Scoped allocators]
765
766 C++11 improves stateful allocators with the introduction of
767 [@http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor `std::scoped_allocator_adaptor`]
768 class template. `scoped_allocator_adaptor` is instantiated with one outer allocator and zero or more inner
769 allocators.
770
771 A scoped allocator is a mechanism to automatically propagate the state of the allocator to the subobjects
772 of a container in a controlled way. If instantiated with only one allocator type, the inner allocator
773 becomes the `scoped_allocator_adaptor` itself, thus using the same allocator
774 resource for the container and every element within the container and, if the elements themselves are
775 containers, each of their elements recursively. If instantiated with more than one allocator, the first allocator
776 is the outer allocator for use by the container, the second allocator is passed to the constructors of the
777 container's elements, and, if the elements themselves are containers, the third allocator is passed to the
778 elements' elements, and so on.
779
780 [*Boost.Container] implements its own `scoped_allocator_adaptor` class and [*backports this feature also
781 to C++03 compilers]. Due to C++03 limitations, in those compilers
782 the allocator propagation implemented by `scoped_allocator_adaptor::construct` functions
783 will be based on traits ([classref boost::container::constructible_with_allocator_suffix constructible_with_allocator_suffix]
784 and [classref boost::container::constructible_with_allocator_prefix constructible_with_allocator_prefix])
785 proposed in [@http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2554.pdf
786 N2554: The Scoped Allocator Model (Rev 2) proposal]. In conforming C++11 compilers or compilers supporting SFINAE
787 expressions (when `BOOST_NO_SFINAE_EXPR` is NOT defined), traits are ignored and C++11 rules
788 (`is_constructible<T, Args..., inner_allocator_type>::value` and
789 `is_constructible<T, allocator_arg_t, inner_allocator_type, Args...>::value`)
790 will be used to detect if the allocator must be propagated with suffix or prefix allocator arguments.
791
792 [endsect]
793
794 [section:insertion_hints Insertion hints in associative containers and preserving 
795  insertion ordering for elements with equivalent keys]
796
797 [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233 LWG Issue #233] corrected a defect
798 in C++98 and specified how equivalent keys were to be inserted in associative containers. [*Boost.Container]
799 implements the C++11 changes that were specified in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html N1780  
800 ['Comments on LWG issue 233: Insertion hints in associative containers]]:
801
802 * `a_eq.insert(t)`: If a range containing elements equivalent to t exists in a_eq, t is inserted at the end of that range.
803 * `a_eq.insert(p,t)`: t is inserted as close as possible to the position just prior to p.
804
805 [endsect]
806
807 [section:initializer_lists Initializer lists]
808
809 [*Boost.Container] supports initialization, assignments and insertions from initializer lists
810 in compilers that implement this feature.
811
812 [endsect]
813
814 [section:null_iterators Null Forward Iterators]
815
816 [*Boost.Container] implements
817 [@http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3644.pdf C++14 Null Forward Iterators],
818 which means that value-initialized iterators may be compared and compare equal
819 to other value-initialized iterators of the same type. Value initialized iterators behave as if they refer
820 past the end of the same empty sequence (example taken from N3644):
821
822 [c++]
823
824    vector<int> v = { ... };
825    auto ni = vector<int>::iterator();
826    auto nd = vector<double>::iterator();
827    ni == ni; // True.
828    nd != nd; // False.
829    v.begin() == ni; // ??? (likely false in practice).
830    v.end() == ni;   // ??? (likely false in practice).
831    ni == nd; // Won't compile.
832
833 [endsect]
834
835 [section:forward_list `forward_list<T>`]
836
837 [*Boost.Container] does not offer C++11 `forward_list` container yet, but it will be available in future
838 versions.
839
840 [endsect]
841
842 [section:vector_exception_guarantees `vector` vs. `std::vector` exception guarantees]
843
844 [classref boost::container::vector vector] does not support the strong exception guarantees
845 given by `std::vector` in functions like `insert`, `push_back`, `emplace`, `emplace_back`,
846 `resize`, `reserve` or `shrink_to_fit` for either copyable or no-throw moveable classes.
847 In C++11 [@http://en.cppreference.com/w/cpp/utility/move_if_noexcept move_if_noexcept] is used
848 to maintain C++03 exception safety guarantees combined with C++11 move semantics.
849 This strong exception guarantee degrades the insertion performance of copyable and throwing-moveable types,
850 degrading moves to copies when such types are inserted in the vector using the aforementioned
851 members.
852
853 This strong exception guarantee also precludes the possibility of using some type of
854 in-place reallocations that can further improve the insertion performance of `vector` See
855 [link container.extended_functionality.extended_allocators Extended Allocators] to know more
856 about these optimizations.
857
858 [classref boost::container::vector vector] always uses move constructors/assignments
859 to rearrange elements in the vector and uses memory expansion mechanisms if the allocator supports them,
860 while offering only basic safety guarantees. It trades off exception guarantees for an improved performance.
861
862 [endsect]
863
864 [section:container_const_reference_parameters Parameter taken by const reference that can be changed]
865
866 Several container operations use a parameter taken by const reference that can be changed during execution of the function.
867 [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#526 LWG Issue 526
868    (['Is it undefined if a function in the standard changes in parameters?])]
869 discusses them:
870
871 [c++]
872
873    //Given std::vector<int> v
874    v.insert(v.begin(), v[2]);
875    //v[2] can be changed by moving elements of vector
876
877    //Given std::list<int> l:
878    l.remove(*l.begin())
879    //The operation could delete the first element, and then continue trying to access it.
880
881 The adopted resolution, NAD (Not A Defect), implies that previous operations must be well-defined. This requires code
882 to detect a reference to an inserted element and an additional copy in that case, impacting performance even when
883 references to already inserted objects are not used. Note that equivalent functions taking rvalue references or
884 iterator ranges require elements not already inserted in the container.
885
886 [*Boost.Container] prioritizes performance and has not implemented the NAD resolution: 
887 in functions that might modify the argument, the library requires references to elements not stored
888 in the container. Using references to inserted elements yields to undefined behaviour (although in debug mode, this
889 precondition violation could be notified via BOOST_ASSERT).
890
891 [endsect]
892
893 [section:Vector_bool `vector<bool>` specialization]
894
895 `vector<bool>` specialization has been quite problematic, and there have been several
896 unsuccessful tries to deprecate or remove it from the standard. [*Boost.Container] does not implement it
897 as there is a superior [@http://www.boost.org/libs/dynamic_bitset/ Boost.DynamicBitset]
898 solution. For issues with `vector<bool>` see the following papers:
899
900 * [@http://home.roadrunner.com/~hinnant/onvectorbool.html On `vector<bool>`]
901 * [@http://www.gotw.ca/publications/N1211.pdf vector<bool>: N1211: More Problems, Better Solutions],
902 * [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2160.html N2160: Library Issue 96: Fixing vector<bool>],
903 * [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2204.html N2204 A Specification to deprecate vector<bool>].
904
905 Quotes:
906
907 * ["['But it is a shame that the C++ committee gave this excellent data structure the name vector<bool> and
908   that it gives no guidance nor encouragement on the critical generic algorithms that need to be optimized for this
909   data structure. Consequently, few std::lib implementations go to this trouble.]]
910
911 * ["['In 1998, admitting that the committee made a mistake was controversial.
912   Since then Java has had to deprecate such significant portions of their libraries
913   that the idea C++ would be ridiculed for deprecating a single minor template specialization seems quaint.]]
914
915 * ["['`vector<bool>` is not a container and `vector<bool>::iterator` is not a random-access iterator
916 (or even a forward or bidirectional iterator either, for that matter). This has already broken user code
917 in the field in mysterious ways.]]
918
919 * ["['`vector<bool>` forces a specific (and potentially bad) optimization choice on all users by enshrining
920 it in the standard. The optimization is premature; different users have different requirements. This too
921 has already hurt users who have been forced to implement workarounds to disable the 'optimization'
922 (e.g., by using a vector<char> and manually casting to/from bool).]]
923
924 So `boost::container::vector<bool>::iterator` returns real `bool` references and works as a fully compliant container.
925 If you need a memory optimized version of `boost::container::vector<bool>`, please use
926 [@http://www.boost.org/libs/dynamic_bitset/ Boost.DynamicBitset].
927
928 [endsect]
929
930 [section:non_standard_memset_initialization Non-standard value initialization using `std::memset`]
931
932 [*Boost.Container] uses `std::memset` with a zero value to initialize some types as in most platforms this
933 initialization yields to the desired value initialization with improved performance.
934
935 Following the C11 standard, [*Boost.Container] assumes that ['for any integer type,
936 the object representation where all the bits are zero shall be a representation of the value
937 zero in that type]. Since `_Bool`/`wchar_t`/`char16_t`/`char32_t` are also integer types in C, it considers
938 all C++ integral types as initializable via `std::memset`.
939
940 By default, [*Boost.Container] also considers floating point types to be initializable using `std::memset`.
941 Most platforms are compatible with this initialization, but in case this initialization is not desirable the
942 user can `#define BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO` before including library headers.
943
944 By default, it also considers pointer types (pointer and pointer to function types, excluding
945 member object and member function pointers) to be initializable using `std::memset`.
946 Most platforms are compatible with this initialization, but in case this initialization is not desired the
947 user can `#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_ZERO` before including library headers.
948
949 If neither `BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO` nor 
950 `BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_ZERO` is defined [*Boost.Container] also considers POD
951 types to be value initializable via `std::memset` with value zero.
952
953 [endsect]
954
955 [endsect]
956
957 [section:known_issues Known Issues]
958
959 [section:move_emulation_limitations Move emulation limitations in C++03 compilers]
960
961 [*Boost.Container] uses [*Boost.Move] to implement move semantics both in C++03 and C++11 compilers.
962 However, as explained in
963 [@http://www.boost.org/doc/libs/release/doc/html/move/emulation_limitations.html Emulation limitations],
964 there are some limitations in C++03 compilers that might surprise [*Boost.Container] users.
965
966 The most noticeable problem is when [*Boost.Container] containers are placed in a struct with a
967 compiler-generated assignment operator:
968
969 [c++]
970
971    class holder
972    {
973       boost::container::vector<MyType> vect;
974    };
975
976    void func(const holder& h)
977    {
978       holder copy_h(h); //<--- ERROR: can't convert 'const holder&' to 'holder&'
979       //Compiler-generated copy constructor is non-const:
980       // holder& operator(holder &)
981       //!!!
982    }
983
984 This limitation forces the user to define a const version of the copy assignment, in all classes
985 holding containers, which might be annoying in some cases.
986
987 [endsect]
988
989 [endsect]
990
991 [section:history_and_reasons History and reasons to use Boost.Container]
992
993 [section:boost_container_history Boost.Container history]
994
995 [*Boost.Container] is a product of a long development effort that started
996 [@http://lists.boost.org/Archives/boost/2004/11/76263.php in 2004 with the experimental Shmem library],
997 which pioneered the use of standard containers in shared memory. Shmem included modified SGI STL container
998 code tweaked to support non-raw `allocator::pointer` types and stateful allocators. Once reviewed,
999 Shmem was accepted as [@http://www.boost.org/libs/interprocess/ Boost.Interprocess] and this library
1000 continued to refine and improve those containers.
1001
1002 In 2007, container code from node containers (`map`, `list`, `slist`) was rewritten, refactored
1003 and expanded to build the intrusive container library [@http://www.boost.org/libs/intrusive/ Boost.Intrusive].
1004 [*Boost.Interprocess] containers were refactored to take advantage of [*Boost.Intrusive] containers and
1005 code duplication was minimized. Both libraries continued to gain support and bug fixes for years.
1006 They introduced move semantics, emplacement insertion and more features of then unreleased C++0x
1007 standard.
1008
1009 [*Boost.Interprocess] containers were always standard compliant, and those containers and new
1010 containers like `stable_vector` and `flat_[multi]set/map` were used outside [*Boost.Interprocess]
1011 with success. As containers were mature enough to get their own library, it was a natural step to
1012 collect them containers and build [*Boost.Container], a library targeted to a wider audience.
1013
1014 [endsect]
1015
1016
1017 [section:Why_boost_container Why Boost.Container?]
1018
1019 With so many high quality standard library implementations out there, why would you want to
1020 use [*Boost.Container]? There are several reasons for that:
1021
1022 * If you have a C++03 compiler, you can have access to C++11 features and have an easy
1023   code migration when you change your compiler.
1024 * It's compatible with [*Boost.Interprocess] shared memory allocators.
1025 * You have extremely useful new containers like `stable_vector` and `flat_[multi]set/map`.
1026 * If you work on multiple platforms, you'll have a portable behaviour without depending
1027   on the std-lib implementation conformance of each platform. Some examples:
1028    * Default constructors don't allocate memory at all, which improves performance and
1029    usually implies a no-throw guarantee (if predicate's or allocator's default constructor doesn't throw).
1030    * Small string optimization for [classref boost::container::basic_string basic_string].
1031 * [link container.extended_functionality Extended functionality] beyond the standard based
1032    on user feedback to improve code performance.
1033 * You need a portable implementation that works when compiling without exceptions support or
1034   you need to customize the error handling when a container needs to signal an exceptional error.
1035
1036 [endsect]
1037
1038 [endsect]
1039
1040 [include auto_index_helpers.qbk]
1041
1042 [section:index Indexes]
1043
1044 [named_index class_name Class Index]
1045 [named_index typedef_name Typedef Index]
1046 [named_index function_name Function Index]
1047 [/named_index macro_name Macro Index]
1048 [/index]
1049
1050 [endsect]
1051
1052 [xinclude autodoc.xml]
1053
1054 [section:acknowledgements_notes Acknowledgements, notes and links]
1055
1056 *  Original standard container code comes from [@http://www.sgi.com/tech/stl/ SGI STL library],
1057    which enhanced the original HP STL code. Code was rewritten for
1058    [*Boost.Interprocess] and moved to [*Boost.Intrusive]. Many thanks to Alexander Stepanov, Meng Lee, David Musser,
1059    Matt Austern... and all HP and SGI STL developers.
1060
1061 *  `flat_[multi]_map/set` containers were originally based on [@http://en.wikipedia.org/wiki/Loki_%28C%2B%2B%29 Loki's]
1062    AssocVector class. Code was rewritten and expanded for [*Boost.Interprocess], so thanks to Andrei Alexandrescu.
1063
1064 *  `stable_vector` was invented and coded by
1065    [@http://bannalia.blogspot.com/2008/09/introducing-stablevector.html Joaqu\u00EDn M. L\u00F3pez Mu\u00F1oz],
1066    then adapted for [*Boost.Interprocess]. Thanks for such a great container.
1067
1068 *  `static_vector` was based on Andrew Hundt's and Adam Wulkiewicz's high-performance `varray` class.
1069    Many performance improvements of `vector` were also inspired in their implementation. Thanks!
1070
1071 *  Howard Hinnant's help and advices were essential when implementing move semantics,
1072    improving allocator support or implementing small string optimization. Thanks Howard
1073    for your wonderful standard library implementations.
1074
1075 *  And finally thanks to all Boosters who helped all these years, improving, fixing and
1076    reviewing all my libraries.
1077
1078 [endsect]
1079
1080 [section:release_notes Release Notes]
1081
1082 [section:release_notes_boost_1_57_00 Boost 1.57 Release]
1083 *  Added support for `initializer_list`. Contributed by Robert Matusewicz.
1084 *  Fixed double destruction bugs in vector and backward expansion capable allocators.
1085 *  Fixed bugs:
1086    * [@https://svn.boost.org/trac/boost/ticket/10263 Trac #10263 (['"AIX 6.1 bug with sched_yield() function out of scope"])].
1087    * [@https://github.com/boostorg/container/pull/16 GitHub #16: ['Fix iterators of incomplete type containers]]. Thanks to Mikael Persson.
1088
1089 [endsect]
1090
1091 [section:release_notes_boost_1_56_00 Boost 1.56 Release]
1092
1093 * Added DlMalloc-based [link container.extended_functionality.extended_allocators Extended Allocators].
1094
1095 * [link container.extended_functionality.configurable_tree_based_associative_containers Improved configurability]
1096    of tree-based ordered associative containers. AVL, Scapegoat and Splay trees are now available
1097    to implement [classref boost::container::set set], [classref boost::container::multiset multiset],
1098    [classref boost::container::map map] and [classref boost::container::multimap multimap].
1099
1100 * Fixed bugs:
1101    *  [@https://svn.boost.org/trac/boost/ticket/9338 #9338: ['"VS2005 compiler errors in swap() definition after including container/memory_util.hpp"]].
1102    *  [@https://svn.boost.org/trac/boost/ticket/9637 #9637: ['"Boost.Container vector::resize() performance issue"]].
1103    *  [@https://svn.boost.org/trac/boost/ticket/9648 #9648: ['"string construction optimization - char_traits::copy could be used ..."]].
1104    *  [@https://svn.boost.org/trac/boost/ticket/9801 #9801: ['"I can no longer create and iterator_range from a stable_vector"]].
1105    *  [@https://svn.boost.org/trac/boost/ticket/9915 #9915: ['"Documentation issues regarding vector constructors and resize methods - value/default initialization"]].
1106    *  [@https://svn.boost.org/trac/boost/ticket/9916 #9916: ['"Allocator propagation incorrect in the assignment operator of most"]].
1107    *  [@https://svn.boost.org/trac/boost/ticket/9931 #9931: ['"flat_map::insert(ordered_unique_range_t...) fails with move_iterators"]].
1108    *  [@https://svn.boost.org/trac/boost/ticket/9955 #9955: ['"Using memcpy with overlapped buffers in vector"]].
1109
1110 [endsect]
1111
1112 [section:release_notes_boost_1_55_00 Boost 1.55 Release]
1113
1114 *  Implemented [link container.main_features.scary_iterators SCARY iterators].
1115
1116 *  Fixed bugs [@https://svn.boost.org/trac/boost/ticket/8269 #8269],
1117               [@https://svn.boost.org/trac/boost/ticket/8473 #8473],
1118               [@https://svn.boost.org/trac/boost/ticket/8892 #8892],
1119               [@https://svn.boost.org/trac/boost/ticket/9009 #9009],
1120               [@https://svn.boost.org/trac/boost/ticket/9064 #9064],
1121               [@https://svn.boost.org/trac/boost/ticket/9092 #9092],
1122               [@https://svn.boost.org/trac/boost/ticket/9108 #9108],
1123               [@https://svn.boost.org/trac/boost/ticket/9166 #9166].
1124
1125 * Added `default initialization` insertion functions to vector-like containers
1126    with new overloads taking `default_init_t` as an argument instead of `const value_type &`.
1127
1128 [endsect]
1129
1130 [section:release_notes_boost_1_54_00 Boost 1.54 Release]
1131
1132 *  Added experimental `static_vector` class, based on Andrew Hundt's and Adam Wulkiewicz's
1133    high performance `varray` class.
1134 *  Speed improvements in `vector` constructors/copy/move/swap, dispatching to memcpy when possible.
1135 *  Support for `BOOST_NO_EXCEPTIONS` [@https://svn.boost.org/trac/boost/ticket/7227 #7227].
1136 *  Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7921 #7921],
1137               [@https://svn.boost.org/trac/boost/ticket/7969 #7969],
1138               [@https://svn.boost.org/trac/boost/ticket/8118 #8118],
1139               [@https://svn.boost.org/trac/boost/ticket/8294 #8294],
1140               [@https://svn.boost.org/trac/boost/ticket/8553 #8553],
1141               [@https://svn.boost.org/trac/boost/ticket/8724 #8724].
1142
1143 [endsect]
1144
1145 [section:release_notes_boost_1_53_00 Boost 1.53 Release]
1146
1147 *  Fixed bug [@https://svn.boost.org/trac/boost/ticket/7650 #7650].
1148 *  Improved `vector`'s insertion performance.
1149 *  Changed again experimental multiallocation interface for better performance (still experimental).
1150 *  Added no exception support for those willing to disable exceptions in their compilers.
1151 *  Fixed GCC -Wshadow warnings.
1152 *  Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros.
1153
1154 [endsect]
1155
1156 [section:release_notes_boost_1_52_00 Boost 1.52 Release]
1157
1158 *  Improved `stable_vector`'s template code bloat and type safety.
1159 *  Changed typedefs and reordered functions of sequence containers to improve doxygen documentation.
1160 *  Fixed bugs
1161   [@https://svn.boost.org/trac/boost/ticket/6615 #6615],
1162   [@https://svn.boost.org/trac/boost/ticket/7139 #7139],
1163   [@https://svn.boost.org/trac/boost/ticket/7215 #7215],
1164   [@https://svn.boost.org/trac/boost/ticket/7232 #7232],
1165   [@https://svn.boost.org/trac/boost/ticket/7269 #7269],
1166   [@https://svn.boost.org/trac/boost/ticket/7439 #7439].
1167 *  Implemented LWG Issue #149 (range insertion now returns an iterator) & cleaned up insertion code in most containers
1168 *  Corrected aliasing errors.
1169
1170 [endsect]
1171
1172 [section:release_notes_boost_1_51_00 Boost 1.51 Release]
1173
1174 *  Fixed bugs
1175   [@https://svn.boost.org/trac/boost/ticket/6763 #6763],
1176   [@https://svn.boost.org/trac/boost/ticket/6803 #6803],
1177   [@https://svn.boost.org/trac/boost/ticket/7114 #7114],
1178   [@https://svn.boost.org/trac/boost/ticket/7103 #7103].
1179   [@https://svn.boost.org/trac/boost/ticket/7123 #7123],
1180
1181 [endsect]
1182
1183 [section:release_notes_boost_1_50_00 Boost 1.50 Release]
1184
1185 *  Added Scoped Allocator Model support.
1186
1187 *  Fixed bugs
1188   [@https://svn.boost.org/trac/boost/ticket/6606 #6606],
1189   [@https://svn.boost.org/trac/boost/ticket/6533 #6533],
1190   [@https://svn.boost.org/trac/boost/ticket/6536 #6536],
1191   [@https://svn.boost.org/trac/boost/ticket/6566 #6566],
1192   [@https://svn.boost.org/trac/boost/ticket/6575 #6575],
1193
1194 [endsect]
1195
1196
1197 [section:release_notes_boost_1_49_00 Boost 1.49 Release]
1198
1199 *  Fixed bugs
1200   [@https://svn.boost.org/trac/boost/ticket/6540 #6540],
1201   [@https://svn.boost.org/trac/boost/ticket/6499 #6499],
1202   [@https://svn.boost.org/trac/boost/ticket/6336 #6336],
1203   [@https://svn.boost.org/trac/boost/ticket/6335 #6335],
1204   [@https://svn.boost.org/trac/boost/ticket/6287 #6287],
1205   [@https://svn.boost.org/trac/boost/ticket/6205 #6205],
1206   [@https://svn.boost.org/trac/boost/ticket/4383 #4383].
1207
1208 *  Added `allocator_traits` support for both C++11 and C++03
1209    compilers through an internal `allocator_traits` clone.
1210
1211 [endsect]
1212
1213 [section:release_notes_boost_1_48_00 Boost 1.48 Release]
1214
1215 *  First release. Container code from [*Boost.Interprocess] was deleted
1216    and redirected to [*Boost.Container ] via using directives.
1217
1218 [endsect]
1219
1220 [endsect]