container.qbk 100 KB

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