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