[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,89 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Acknowledgements, notes and links</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="../boost/container/pmr/vector_of.html" title="Struct template vector_of">
<link rel="next" href="release_notes.html" title="Release Notes">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost/container/pmr/vector_of.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="release_notes.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.acknowledgements_notes"></a><a class="link" href="acknowledgements_notes.html" title="Acknowledgements, notes and links">Acknowledgements, notes
and links</a>
</h2></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Original standard container code comes from <a href="http://www.sgi.com/tech/stl/" target="_top">SGI
STL library</a>, which enhanced the original HP STL code. Code was
rewritten for <span class="bold"><strong>Boost.Interprocess</strong></span> and moved
to <span class="bold"><strong>Boost.Intrusive</strong></span>. Many thanks to Alexander
Stepanov, Meng Lee, David Musser, Matt Austern... and all HP and SGI STL
developers.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">flat_</span><span class="special">[</span><span class="identifier">multi</span><span class="special">]</span><span class="identifier">_map</span><span class="special">/</span><span class="identifier">set</span></code> containers were originally based
on <a href="http://en.wikipedia.org/wiki/Loki_%28C%2B%2B%29" target="_top">Loki's</a>
AssocVector class. Code was rewritten and expanded for <span class="bold"><strong>Boost.Interprocess</strong></span>,
so thanks to Andrei Alexandrescu.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">stable_vector</span></code> was invented
and coded by <a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" target="_top">Joaquín
M. López Muñoz</a>, then adapted for <span class="bold"><strong>Boost.Interprocess</strong></span>.
Thanks for such a great container.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">static_vector</span></code> was based
on Andrew Hundt's and Adam Wulkiewicz's high-performance <code class="computeroutput"><span class="identifier">varray</span></code> class. Many performance improvements
of <code class="computeroutput"><span class="identifier">vector</span></code> were also inspired
by their implementation. Thanks!
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">devector</span></code> is based on Thaler
Benedek's high-performance <code class="computeroutput"><span class="identifier">devector</span></code>
implementation, then adapted for <span class="bold"><strong>Boost.Container</strong></span>.
Also inspired by similar implemenations by Orson Peters and Lars Hagen.
Thanks for such a great code and documentation!
</li>
<li class="listitem">
Howard Hinnant's help and advices were essential when implementing move
semantics, improving allocator support or implementing small string optimization.
Thanks Howard for your wonderful standard library implementations.
</li>
<li class="listitem">
And finally thanks to all Boosters who helped all these years, improving,
fixing and reviewing all my libraries.
</li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost/container/pmr/vector_of.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="release_notes.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,498 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Extended functionality: Configurable containers</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="extended_functionality.html" title="Extended functionality: Basic extensions">
<link rel="next" href="extended_allocators.html" title="Extended functionality: Extended allocators">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="extended_functionality.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="extended_allocators.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.configurable_containers"></a><a class="link" href="configurable_containers.html" title="Extended functionality: Configurable containers">Extended functionality:
Configurable containers</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="configurable_containers.html#container.configurable_containers.configurable_tree_based_associative_containers">Configurable
tree-based associative ordered containers</a></span></dt>
<dt><span class="section"><a href="configurable_containers.html#container.configurable_containers.configurable_vectors">Configurable
vectors</a></span></dt>
<dt><span class="section"><a href="configurable_containers.html#container.configurable_containers.configurable_deques">Configurable
deques</a></span></dt>
<dt><span class="section"><a href="configurable_containers.html#container.configurable_containers.configurable_static_vectors">Configurable
static vector</a></span></dt>
<dt><span class="section"><a href="configurable_containers.html#container.configurable_containers.configurable_small_vectors">Configurable
small vector</a></span></dt>
</dl></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span> offers the possibility to
configure at compile time some parameters of several containers, apart from
the stored type and the allocator. This configuration is passed as the last
template parameter and defined using the utility classes. The following containers
can receive useful configuration options:
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.configurable_containers.configurable_tree_based_associative_containers"></a><a class="link" href="configurable_containers.html#container.configurable_containers.configurable_tree_based_associative_containers" title="Configurable tree-based associative ordered containers">Configurable
tree-based associative ordered containers</a>
</h3></div></div></div>
<p>
<code class="computeroutput"><a class="link" href="../boost/container/set.html" title="Class template set">set</a></code>, <code class="computeroutput"><a class="link" href="../boost/container/multiset.html" title="Class template multiset">multiset</a></code>,
<code class="computeroutput"><a class="link" href="../boost/container/map.html" title="Class template map">map</a></code> and <code class="computeroutput"><a class="link" href="../boost/container/multimap.html" title="Class template multimap">multimap</a></code>
associative containers are implemented as binary search trees which offer
the needed complexity and stability guarantees required by the C++ standard
for associative containers.
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> offers the possibility to
configure at compile time some parameters of the binary search tree implementation.
This configuration is passed as the last template parameter and defined using
the utility class <code class="computeroutput"><a class="link" href="../boost/container/tree_assoc_options.html" title="Struct template tree_assoc_options">tree_assoc_options</a></code>.
The following parameters can be configured:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
The underlying <span class="bold"><strong>tree implementation</strong></span> type
(<code class="computeroutput"><a class="link" href="../boost/container/tree_type.html" title="Struct template tree_type">tree_type</a></code>).
By default these containers use a red-black tree but the user can use
other tree types:
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
<a href="http://en.wikipedia.org/wiki/Red%E2%80%93black_tree" target="_top">Red-Black
Tree</a>
</li>
<li class="listitem">
<a href="http://en.wikipedia.org/wiki/Avl_trees" target="_top">AVL tree</a>
</li>
<li class="listitem">
<a href="http://en.wikipedia.org/wiki/Scapegoat_tree" target="_top">Scapegoat
tree</a>. In this case Insertion and Deletion are amortized
O(log n) instead of O(log n).
</li>
<li class="listitem">
<a href="http://en.wikipedia.org/wiki/Splay_tree" target="_top">Splay tree</a>.
In this case Searches, Insertions and Deletions are amortized O(log
n) instead of O(log n).
</li>
</ul></div>
</li>
<li class="listitem">
Whether the <span class="bold"><strong>size saving</strong></span> mechanisms are
used to implement the tree nodes (<code class="computeroutput"><a class="link" href="../boost/container/optimize_size.html" title="Struct template optimize_size">optimize_size</a></code>).
By default this option is activated and is only meaningful to red-black
and avl trees (in other cases, this option will be ignored). This option
will try to put rebalancing metadata inside the "parent" pointer
of the node if the pointer type has enough alignment. Usually, due to
alignment issues, the metadata uses the size of a pointer yielding to
four pointer size overhead per node, whereas activating this option usually
leads to 3 pointer size overhead. Although some mask operations must
be performed to extract data from this special "parent" pointer,
in several systems this option also improves performance due to the improved
cache usage produced by the node size reduction.
</li>
</ul></div>
<p>
See the following example to see how <code class="computeroutput"><a class="link" href="../boost/container/tree_assoc_options.html" title="Struct template tree_assoc_options">tree_assoc_options</a></code>
can be used to customize these containers:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">set</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//Make sure assertions are active</span>
<span class="preprocessor">#ifdef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#undef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//First define several options</span>
<span class="comment">//</span>
<span class="comment">//This option specifies an AVL tree based associative container</span>
<span class="keyword">typedef</span> <span class="identifier">tree_assoc_options</span><span class="special">&lt;</span> <span class="identifier">tree_type</span><span class="special">&lt;</span><span class="identifier">avl_tree</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">AVLTree</span><span class="special">;</span>
<span class="comment">//This option specifies an AVL tree based associative container</span>
<span class="comment">//disabling node size optimization.</span>
<span class="keyword">typedef</span> <span class="identifier">tree_assoc_options</span><span class="special">&lt;</span> <span class="identifier">tree_type</span><span class="special">&lt;</span><span class="identifier">avl_tree</span><span class="special">&gt;</span>
<span class="special">,</span> <span class="identifier">optimize_size</span><span class="special">&lt;</span><span class="keyword">false</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">AVLTreeNoSizeOpt</span><span class="special">;</span>
<span class="comment">//This option specifies an Splay tree based associative container</span>
<span class="keyword">typedef</span> <span class="identifier">tree_assoc_options</span><span class="special">&lt;</span> <span class="identifier">tree_type</span><span class="special">&lt;</span><span class="identifier">splay_tree</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">SplayTree</span><span class="special">;</span>
<span class="comment">//Now define new tree-based associative containers</span>
<span class="comment">//</span>
<span class="comment">//AVLTree based set container</span>
<span class="keyword">typedef</span> <span class="identifier">set</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">new_allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">AVLTree</span><span class="special">&gt;</span> <span class="identifier">AvlSet</span><span class="special">;</span>
<span class="comment">//AVLTree based set container without size optimization</span>
<span class="keyword">typedef</span> <span class="identifier">set</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">new_allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">AVLTreeNoSizeOpt</span><span class="special">&gt;</span> <span class="identifier">AvlSetNoSizeOpt</span><span class="special">;</span>
<span class="comment">//Splay tree based multiset container</span>
<span class="keyword">typedef</span> <span class="identifier">multiset</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">new_allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">SplayTree</span><span class="special">&gt;</span> <span class="identifier">SplayMultiset</span><span class="special">;</span>
<span class="comment">//Use them</span>
<span class="comment">//</span>
<span class="identifier">AvlSet</span> <span class="identifier">avl_set</span><span class="special">;</span>
<span class="identifier">avl_set</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">avl_set</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">!=</span> <span class="identifier">avl_set</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
<span class="identifier">AvlSetNoSizeOpt</span> <span class="identifier">avl_set_no_szopt</span><span class="special">;</span>
<span class="identifier">avl_set_no_szopt</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">avl_set_no_szopt</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">avl_set_no_szopt</span><span class="special">.</span><span class="identifier">count</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="identifier">SplayMultiset</span> <span class="identifier">splay_mset</span><span class="special">;</span>
<span class="identifier">splay_mset</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
<span class="identifier">splay_mset</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="number">2</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">splay_mset</span><span class="special">.</span><span class="identifier">count</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.configurable_containers.configurable_vectors"></a><a class="link" href="configurable_containers.html#container.configurable_containers.configurable_vectors" title="Configurable vectors">Configurable
vectors</a>
</h3></div></div></div>
<p>
The configuration for <code class="computeroutput"><a class="link" href="../boost/container/vector.html" title="Class template vector">vector</a></code>
is passed as the last template parameter and defined using the utility class
<code class="computeroutput"><a class="link" href="../boost/container/vector_options.html" title="Struct template vector_options">vector_options</a></code>.
The following parameters can be configured:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/growth_factor.html" title="Struct template growth_factor">growth_factor</a></code>:
the growth policy of the vector. The rate at which the capacity of a
vector grows is implementation dependent and implementations choose exponential
growth in order to meet the amortized constant time requirement for push_back.
A higher growth factor will make it faster as it will require less data
movement, but it will have a greater memory impact (on average, more
memory will be unused). A user can provide a custom implementation of
the growth factor and some predefined policies are available: <code class="computeroutput"><a class="link" href="../boost/container/growth_factor_50.html" title="Struct growth_factor_50">growth_factor_50</a></code>,
<code class="computeroutput"><a class="link" href="../boost/container/growth_factor_60.html" title="Struct growth_factor_60">growth_factor_60</a></code>
and <code class="computeroutput"><a class="link" href="../boost/container/growth_factor_50.html" title="Struct growth_factor_50">growth_factor_100</a></code>.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/stored_size.html" title="Struct template stored_size">stored_size</a></code>:
the type that will be used to store size-related parameters inside of
the vector. Sometimes, when the maximum capacity to be used is much less
than the theoretical maximum that a vector can hold, it's interesting
to use smaller unsigned integer types to represent <code class="computeroutput"><span class="identifier">size</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">capacity</span><span class="special">()</span></code> inside vector, so that the size of
an empty vector is minimized and cache performance might be improved.
See <code class="computeroutput"><a class="link" href="../boost/container/stored_size.html" title="Struct template stored_size">stored_size</a></code>
for more details.
</li>
</ul></div>
<p>
See the following example to see how <code class="computeroutput"><a class="link" href="../boost/container/vector_options.html" title="Struct template vector_options">vector_options</a></code>
can be used to customize <code class="computeroutput"><span class="identifier">vector</span></code>
container:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">core</span><span class="special">/</span><span class="identifier">no_exceptions_support</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//Make sure assertions are active</span>
<span class="preprocessor">#ifdef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#undef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//This option specifies that a vector that will use "unsigned char" as</span>
<span class="comment">//the type to store capacity or size internally.</span>
<span class="keyword">typedef</span> <span class="identifier">vector_options</span><span class="special">&lt;</span> <span class="identifier">stored_size</span><span class="special">&lt;</span><span class="keyword">unsigned</span> <span class="keyword">char</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">size_option_t</span><span class="special">;</span>
<span class="comment">//Size-optimized vector is smaller than the default one.</span>
<span class="keyword">typedef</span> <span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">new_allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">size_option_t</span> <span class="special">&gt;</span> <span class="identifier">size_optimized_vector_t</span><span class="special">;</span>
<span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">((</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">size_optimized_vector_t</span><span class="special">)</span> <span class="special">&lt;</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;)</span> <span class="special">));</span>
<span class="comment">//Requesting capacity for more elements than representable by "unsigned char"</span>
<span class="comment">//is an error in the size optimized vector.</span>
<span class="keyword">bool</span> <span class="identifier">exception_thrown</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
<span class="keyword">try</span> <span class="special">{</span> <span class="identifier">size_optimized_vector_t</span> <span class="identifier">v</span><span class="special">(</span><span class="number">256</span><span class="special">);</span> <span class="special">}</span>
<span class="keyword">catch</span><span class="special">(...){</span> <span class="identifier">exception_thrown</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span> <span class="special">}</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">exception_thrown</span> <span class="special">==</span> <span class="keyword">true</span><span class="special">);</span>
<span class="comment">//This option specifies that a vector will increase its capacity 50%</span>
<span class="comment">//each time the previous capacity was exhausted.</span>
<span class="keyword">typedef</span> <span class="identifier">vector_options</span><span class="special">&lt;</span> <span class="identifier">growth_factor</span><span class="special">&lt;</span><span class="identifier">growth_factor_50</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">growth_50_option_t</span><span class="special">;</span>
<span class="comment">//Fill the vector until full capacity is reached</span>
<span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">new_allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">growth_50_option_t</span> <span class="special">&gt;</span> <span class="identifier">growth_50_vector</span><span class="special">(</span><span class="number">5</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
<span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">old_cap</span> <span class="special">=</span> <span class="identifier">growth_50_vector</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">();</span>
<span class="identifier">growth_50_vector</span><span class="special">.</span><span class="identifier">resize</span><span class="special">(</span><span class="identifier">old_cap</span><span class="special">);</span>
<span class="comment">//Now insert an additional item and check the new buffer is 50% bigger</span>
<span class="identifier">growth_50_vector</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">growth_50_vector</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">old_cap</span><span class="special">*</span><span class="number">3</span><span class="special">/</span><span class="number">2</span><span class="special">);</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.configurable_containers.configurable_deques"></a><a class="link" href="configurable_containers.html#container.configurable_containers.configurable_deques" title="Configurable deques">Configurable
deques</a>
</h3></div></div></div>
<p>
The configuration for <code class="computeroutput"><a class="link" href="../boost/container/deque.html" title="Class template deque">deque</a></code>
is passed as the last template parameter and defined using the utility class
<code class="computeroutput"><a class="link" href="../boost/container/deque_options.html" title="Struct template deque_options">deque_options</a></code>.
The following parameters can be configured:
</p>
<p>
Parameters that control the size of deque's 'block' (deque allocates contiguous
chunks of elements, called 'blocks'). Only one of these paratemers can be
specified:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/block_bytes.html" title="Struct template block_bytes">block_bytes</a></code>:
the number of bytes deque will allocate for store elements contiguously:
<code class="computeroutput"><span class="identifier">deque</span><span class="special">::</span><span class="identifier">get_block_size</span><span class="special">()</span></code>
will return aproximately <code class="computeroutput"><span class="identifier">block_bytes</span><span class="special">/</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">value_type</span><span class="special">)</span></code>. A value of zero means the default value.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/block_size.html" title="Struct template block_size">block_size</a></code>:
the number of elements deque will allocate contiguously. If this option
is specified, <code class="computeroutput"><span class="identifier">deque</span><span class="special">::</span><span class="identifier">get_block_size</span><span class="special">()</span></code>
will return the specified <code class="computeroutput"><span class="identifier">block_size</span></code>.
A value of zero means the default value.
</li>
</ul></div>
<p>
See the following example to see how <code class="computeroutput"><a class="link" href="../boost/container/deque_options.html" title="Struct template deque_options">deque_options</a></code>
can be used to customize <code class="computeroutput"><span class="identifier">deque</span></code>
container:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">deque</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//Make sure assertions are active</span>
<span class="preprocessor">#ifdef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#undef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//This option specifies the desired block size for deque</span>
<span class="keyword">typedef</span> <span class="identifier">deque_options</span><span class="special">&lt;</span> <span class="identifier">block_size</span><span class="special">&lt;</span><span class="number">128u</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">block_128_option_t</span><span class="special">;</span>
<span class="comment">//This deque will allocate blocks of 128 elements</span>
<span class="keyword">typedef</span> <span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="identifier">block_128_option_t</span> <span class="special">&gt;</span> <span class="identifier">block_128_deque_t</span><span class="special">;</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">block_128_deque_t</span><span class="special">::</span><span class="identifier">get_block_size</span><span class="special">()</span> <span class="special">==</span> <span class="number">128u</span><span class="special">);</span>
<span class="comment">//This option specifies the maximum block size for deque</span>
<span class="comment">//in bytes</span>
<span class="keyword">typedef</span> <span class="identifier">deque_options</span><span class="special">&lt;</span> <span class="identifier">block_bytes</span><span class="special">&lt;</span><span class="number">1024u</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">block_1024_bytes_option_t</span><span class="special">;</span>
<span class="comment">//This deque will allocate blocks of 1024 bytes</span>
<span class="keyword">typedef</span> <span class="identifier">deque</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="identifier">block_1024_bytes_option_t</span> <span class="special">&gt;</span> <span class="identifier">block_1024_bytes_deque_t</span><span class="special">;</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">block_1024_bytes_deque_t</span><span class="special">::</span><span class="identifier">get_block_size</span><span class="special">()</span> <span class="special">==</span> <span class="number">1024u</span><span class="special">/</span><span class="keyword">sizeof</span><span class="special">(</span><span class="keyword">int</span><span class="special">));</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.configurable_containers.configurable_static_vectors"></a><a class="link" href="configurable_containers.html#container.configurable_containers.configurable_static_vectors" title="Configurable static vector">Configurable
static vector</a>
</h3></div></div></div>
<p>
The configuration for <code class="computeroutput"><a class="link" href="../boost/container/static_vector.html" title="Class template static_vector">static_vector</a></code>
is passed as the last template parameter and defined using the utility class
<code class="computeroutput"><a class="link" href="../boost/container/static_vector_options.html" title="Struct template static_vector_options">static_vector_options</a></code>.
The following parameters can be configured:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/inplace_alignment.html" title="Struct template inplace_alignment">inplace_alignment</a></code>:
the minimum alignment (in bytes) that the stored value type needs. This
option allows static vectors that need non-default alignments, e.g.,
to be used in SIMD operations.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/throw_on_overflow.html" title="Struct template throw_on_overflow">throw_on_overflow</a></code>:
A boolean that specifies if the container should throw an exception when
the compile-time capacity is not enough to hold the requesteed number
of objects. When "false", if the capacit is overflowd, the
implementation calls to BOOST_ASSERT and if that assertion does not throw
or abort, undefined behavior is triggered.
</li>
</ul></div>
<p>
See the following example to see how <code class="computeroutput"><a class="link" href="../boost/container/static_vector_options.html" title="Struct template static_vector_options">static_vector_options</a></code>
can be used to customize <code class="computeroutput"><span class="identifier">static_vector</span></code>
container:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">static_vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//Make sure assertions are active</span>
<span class="preprocessor">#ifdef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#undef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//This option specifies the desired alignment for value_type</span>
<span class="keyword">typedef</span> <span class="identifier">static_vector_options</span><span class="special">&lt;</span> <span class="identifier">inplace_alignment</span><span class="special">&lt;</span><span class="number">16u</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">alignment_16_option_t</span><span class="special">;</span>
<span class="comment">//Check 16 byte alignment option</span>
<span class="identifier">static_vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">,</span> <span class="identifier">alignment_16_option_t</span> <span class="special">&gt;</span> <span class="identifier">sv</span><span class="special">;</span>
<span class="identifier">assert</span><span class="special">(((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">)</span><span class="identifier">sv</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">%</span> <span class="number">16u</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
<span class="comment">//This static_vector won't throw on overflow, for maximum performance</span>
<span class="keyword">typedef</span> <span class="identifier">static_vector_options</span><span class="special">&lt;</span> <span class="identifier">throw_on_overflow</span><span class="special">&lt;</span><span class="keyword">false</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">no_throw_options_t</span><span class="special">;</span>
<span class="comment">//Create static_vector with no throw on overflow</span>
<span class="identifier">static_vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">,</span> <span class="identifier">no_throw_options_t</span> <span class="special">&gt;</span> <span class="identifier">sv2</span><span class="special">;</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.configurable_containers.configurable_small_vectors"></a><a class="link" href="configurable_containers.html#container.configurable_containers.configurable_small_vectors" title="Configurable small vector">Configurable
small vector</a>
</h3></div></div></div>
<p>
The configuration for <code class="computeroutput"><a class="link" href="../boost/container/small_vector.html" title="Class template small_vector">small_vector</a></code>
is passed as the last template parameter and defined using the utility class
<code class="computeroutput"><a class="link" href="../boost/container/small_vector_options.html" title="Struct template small_vector_options">small_vector_options</a></code>.
The following parameters can be configured:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/inplace_alignment.html" title="Struct template inplace_alignment">inplace_alignment</a></code>:
the minimum alignment (in bytes) for the in-place storage used to build
the "small" number of elements. <span class="bold"><strong>The alignment
of the dynamic memory must be provided by the allocator and it is not
affected by this option</strong></span>.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/growth_factor.html" title="Struct template growth_factor">growth_factor</a></code>:
the growth policy of the vector. The rate at which the capacity of a
vector grows is implementation dependent and implementations choose exponential
growth in order to meet the amortized constant time requirement for push_back.
A higher growth factor will make it faster as it will require less data
movement, but it will have a greater memory impact (on average, more
memory will be unused). A user can provide a custom implementation of
the growth factor and some predefined policies are available: <code class="computeroutput"><a class="link" href="../boost/container/growth_factor_50.html" title="Struct growth_factor_50">growth_factor_50</a></code>,
<code class="computeroutput"><a class="link" href="../boost/container/growth_factor_60.html" title="Struct growth_factor_60">growth_factor_60</a></code>
and <code class="computeroutput"><a class="link" href="../boost/container/growth_factor_50.html" title="Struct growth_factor_50">growth_factor_100</a></code>.
</li>
</ul></div>
<p>
See the following example to see how <code class="computeroutput"><a class="link" href="../boost/container/small_vector_options.html" title="Struct template small_vector_options">small_vector_options</a></code>
can be used to customize <code class="computeroutput"><span class="identifier">small_vector</span></code>
container:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">small_vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//Make sure assertions are active</span>
<span class="preprocessor">#ifdef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#undef</span> <span class="identifier">NDEBUG</span>
<span class="preprocessor">#endif</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//This option specifies the desired alignment for the internal value_type</span>
<span class="keyword">typedef</span> <span class="identifier">small_vector_options</span><span class="special">&lt;</span> <span class="identifier">inplace_alignment</span><span class="special">&lt;</span><span class="number">16u</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">alignment_16_option_t</span><span class="special">;</span>
<span class="comment">//Check 16 byte alignment option</span>
<span class="identifier">small_vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="identifier">alignment_16_option_t</span> <span class="special">&gt;</span> <span class="identifier">sv</span><span class="special">;</span>
<span class="identifier">assert</span><span class="special">(((</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">)</span><span class="identifier">sv</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">%</span> <span class="number">16u</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
<span class="comment">//This option specifies that a vector will increase its capacity 50%</span>
<span class="comment">//each time the previous capacity was exhausted.</span>
<span class="keyword">typedef</span> <span class="identifier">small_vector_options</span><span class="special">&lt;</span> <span class="identifier">growth_factor</span><span class="special">&lt;</span><span class="identifier">growth_factor_50</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">growth_50_option_t</span><span class="special">;</span>
<span class="comment">//Fill the vector until full capacity is reached</span>
<span class="identifier">small_vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">,</span> <span class="keyword">void</span><span class="special">,</span> <span class="identifier">growth_50_option_t</span> <span class="special">&gt;</span> <span class="identifier">growth_50_vector</span><span class="special">(</span><span class="number">10</span><span class="special">,</span> <span class="number">0</span><span class="special">);</span>
<span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">old_cap</span> <span class="special">=</span> <span class="identifier">growth_50_vector</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">();</span>
<span class="identifier">growth_50_vector</span><span class="special">.</span><span class="identifier">resize</span><span class="special">(</span><span class="identifier">old_cap</span><span class="special">);</span>
<span class="comment">//Now insert an additional item and check the new buffer is 50% bigger</span>
<span class="identifier">growth_50_vector</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">growth_50_vector</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">old_cap</span><span class="special">*</span><span class="number">3</span><span class="special">/</span><span class="number">2</span><span class="special">);</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="extended_functionality.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="extended_allocators.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,680 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>C++11/C++14/C++17 Conformance</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="extended_allocators.html" title="Extended functionality: Extended allocators">
<link rel="next" href="known_issues.html" title="Known Issues">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="extended_allocators.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="known_issues.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.cpp_conformance"></a><a class="link" href="cpp_conformance.html" title="C++11/C++14/C++17 Conformance">C++11/C++14/C++17 Conformance</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.move_emplace">Move and Emplace</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.alloc_traits_move_traits">Stateful
allocators</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.scoped_allocator">Scoped allocators</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.insertion_hints">Insertion
hints in associative containers and preserving insertion ordering for elements
with equivalent keys</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.initializer_lists">Initializer
lists</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.null_iterators">Null Forward
Iterators</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.polymorphic_memory_resources">Polymorphic
Memory Resources </a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.forward_list"><code class="computeroutput"><span class="identifier">forward_list</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code></a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.vector_exception_guarantees"><code class="computeroutput"><span class="identifier">vector</span></code> vs. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
exception guarantees</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.container_const_reference_parameters">Parameter
taken by const reference that can be changed</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.Vector_bool"><code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code> specialization</a></span></dt>
<dt><span class="section"><a href="cpp_conformance.html#container.cpp_conformance.non_standard_memset_initialization">Non-standard
value initialization using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">memset</span></code></a></span></dt>
</dl></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span> aims for full C++11 conformance
except reasoned deviations, backporting as much as possible for C++03. Obviously,
this conformance is a work in progress so this section explains what C++11/C++14/C++17
features are implemented and which of them have been backported to earlier
standard conformig compilers.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.move_emplace"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.move_emplace" title="Move and Emplace">Move and Emplace</a>
</h3></div></div></div>
<p>
For compilers with rvalue references and for those C++03 types that use
<a href="http://www.boost.org/libs/move" target="_top">Boost.Move</a> rvalue reference
emulation <span class="bold"><strong>Boost.Container</strong></span> supports all C++11
features related to move semantics: containers are movable, requirements
for <code class="computeroutput"><span class="identifier">value_type</span></code> are those
specified for C++11 containers.
</p>
<p>
For compilers with variadic templates, <span class="bold"><strong>Boost.Container</strong></span>
supports placement insertion (<code class="computeroutput"><span class="identifier">emplace</span></code>,
...) functions from C++11. For those compilers without variadic templates
support <span class="bold"><strong>Boost.Container</strong></span> uses the preprocessor
to create a set of overloads up to a finite number of parameters.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.alloc_traits_move_traits"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.alloc_traits_move_traits" title="Stateful allocators">Stateful
allocators</a>
</h3></div></div></div>
<p>
C++03 was not stateful-allocator friendly. For compactness of container objects
and for simplicity, it did not require containers to support allocators with
state: Allocator objects need not be stored in container objects. It was
not possible to store an allocator with state, say an allocator that holds
a pointer to an arena from which to allocate. C++03 allowed implementors
to suppose two allocators of the same type always compare equal (that means
that memory allocated by one allocator object could be deallocated by another
instance of the same type) and allocators were not swapped when the container
was swapped.
</p>
<p>
C++11 further improves stateful allocator support through <a href="http://en.cppreference.com/w/cpp/memory/allocator_traits" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_traits</span></code></a>.
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_traits</span></code> is the protocol between
a container and an allocator, and an allocator writer can customize its behaviour
(should the container propagate it in move constructor, swap, etc.?) following
<code class="computeroutput"><span class="identifier">allocator_traits</span></code> requirements.
<span class="bold"><strong>Boost.Container</strong></span> not only supports this model
with C++11 but also <span class="bold"><strong>backports it to C++03</strong></span>
via <code class="computeroutput"><a class="link" href="../boost/container/allocator_traits.html" title="Struct template allocator_traits">boost::container::allocator_traits</a></code>
including some C++17 changes. This class offers some workarounds for C++03
compilers to achieve the same allocator guarantees as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_traits</span></code>.
</p>
<p>
In [Boost.Container] containers, if possible, a single allocator is hold
to construct <code class="computeroutput"><span class="identifier">value_type</span></code>s.
If the container needs an auxiliary allocator (e.g. an array allocator used
by <code class="computeroutput"><span class="identifier">deque</span></code> or <code class="computeroutput"><span class="identifier">stable_vector</span></code>), that allocator is also
stored in the container and initialized from the user-supplied allocator
when the container is constructed (i.e. it's not constructed on the fly when
auxiliary memory is needed).
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.scoped_allocator"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.scoped_allocator" title="Scoped allocators">Scoped allocators</a>
</h3></div></div></div>
<p>
C++11 improves stateful allocators with the introduction of <a href="http://en.cppreference.com/w/cpp/memory/scoped_allocator_adaptor" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">scoped_allocator_adaptor</span></code></a>
class template. <code class="computeroutput"><span class="identifier">scoped_allocator_adaptor</span></code>
is instantiated with one outer allocator and zero or more inner allocators.
</p>
<p>
A scoped allocator is a mechanism to automatically propagate the state of
the allocator to the subobjects of a container in a controlled way. If instantiated
with only one allocator type, the inner allocator becomes the <code class="computeroutput"><span class="identifier">scoped_allocator_adaptor</span></code> itself, thus using
the same allocator resource for the container and every element within the
container and, if the elements themselves are containers, each of their elements
recursively. If instantiated with more than one allocator, the first allocator
is the outer allocator for use by the container, the second allocator is
passed to the constructors of the container's elements, and, if the elements
themselves are containers, the third allocator is passed to the elements'
elements, and so on.
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> implements its own <code class="computeroutput"><a class="link" href="../boost/container/scoped_allocator_adaptor.html" title="Class template scoped_allocator_adaptor">scoped_allocator_adaptor</a></code>
class and <span class="bold"><strong>backports this feature also to C++03 compilers</strong></span>.
Due to C++03 limitations, in those compilers the allocator propagation implemented
by <code class="computeroutput"><span class="identifier">scoped_allocator_adaptor</span><span class="special">::</span><span class="identifier">construct</span></code>
functions will be based on traits (<code class="computeroutput"><a class="link" href="../boost/container/construc_idm46288248430944.html" title="Struct template constructible_with_allocator_suffix">constructible_with_allocator_suffix</a></code>
and <code class="computeroutput"><a class="link" href="../boost/container/construc_idm46288248441312.html" title="Struct template constructible_with_allocator_prefix">constructible_with_allocator_prefix</a></code>)
proposed in <a href="http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2008/n2554.pdf" target="_top">N2554:
The Scoped Allocator Model (Rev 2) proposal</a>. In conforming C++11
compilers or compilers supporting SFINAE expressions (when <code class="computeroutput"><span class="identifier">BOOST_NO_SFINAE_EXPR</span></code> is NOT defined), traits
are ignored and C++11 rules (<code class="computeroutput"><span class="identifier">is_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span>
<span class="identifier">Args</span><span class="special">...,</span>
<span class="identifier">inner_allocator_type</span><span class="special">&gt;::</span><span class="identifier">value</span></code> and <code class="computeroutput"><span class="identifier">is_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span>
<span class="identifier">allocator_arg_t</span><span class="special">,</span>
<span class="identifier">inner_allocator_type</span><span class="special">,</span>
<span class="identifier">Args</span><span class="special">...&gt;::</span><span class="identifier">value</span></code>) will be used to detect if the allocator
must be propagated with suffix or prefix allocator arguments.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.insertion_hints"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.insertion_hints" title="Insertion hints in associative containers and preserving insertion ordering for elements with equivalent keys">Insertion
hints in associative containers and preserving insertion ordering for elements
with equivalent keys</a>
</h3></div></div></div>
<p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233" target="_top">LWG
Issue #233</a> corrected a defect in C++98 and specified how equivalent
keys were to be inserted in associative containers. <span class="bold"><strong>Boost.Container</strong></span>
implements the C++11 changes that were specified in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html" target="_top">N1780
<span class="emphasis"><em>Comments on LWG issue 233: Insertion hints in associative containers</em></span></a>:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">a_eq</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span></code>:
If a range containing elements equivalent to t exists in a_eq, t is inserted
at the end of that range.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">a_eq</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">p</span><span class="special">,</span><span class="identifier">t</span><span class="special">)</span></code>:
t is inserted as close as possible to the position just prior to p.
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.initializer_lists"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.initializer_lists" title="Initializer lists">Initializer
lists</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span> supports initialization,
assignments and insertions from initializer lists in compilers that implement
this feature.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.null_iterators"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.null_iterators" title="Null Forward Iterators">Null Forward
Iterators</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span> implements <a href="http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3644.pdf" target="_top">C++14
Null Forward Iterators</a>, which means that value-initialized iterators
may be compared and compare equal to other value-initialized iterators of
the same type. Value initialized iterators behave as if they refer past the
end of the same empty sequence (example taken from N3644):
</p>
<pre class="programlisting"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">v</span> <span class="special">=</span> <span class="special">{</span> <span class="special">...</span> <span class="special">};</span>
<span class="keyword">auto</span> <span class="identifier">ni</span> <span class="special">=</span> <span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">iterator</span><span class="special">();</span>
<span class="keyword">auto</span> <span class="identifier">nd</span> <span class="special">=</span> <span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">iterator</span><span class="special">();</span>
<span class="identifier">ni</span> <span class="special">==</span> <span class="identifier">ni</span><span class="special">;</span> <span class="comment">// True.</span>
<span class="identifier">nd</span> <span class="special">!=</span> <span class="identifier">nd</span><span class="special">;</span> <span class="comment">// False.</span>
<span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">ni</span><span class="special">;</span> <span class="comment">// ??? (likely false in practice).</span>
<span class="identifier">v</span><span class="special">.</span><span class="identifier">end</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">ni</span><span class="special">;</span> <span class="comment">// ??? (likely false in practice).</span>
<span class="identifier">ni</span> <span class="special">==</span> <span class="identifier">nd</span><span class="special">;</span> <span class="comment">// Won't compile.</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.polymorphic_memory_resources"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.polymorphic_memory_resources" title="Polymorphic Memory Resources">Polymorphic
Memory Resources </a>
</h3></div></div></div>
<p>
The document <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html" target="_top">C++
Extensions for Library Fundamentals (final draft)</a> includes classes
that provide allocator type erasure and runtime polymorphism. As Pablo Halpern,
the author of the proposal, explains in the paper (<a href="https://isocpp.org/files/papers/N3916.pdf" target="_top">N3916
Polymorphic Memory Resources (r2)</a>):
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>A significant impediment to effective memory management
in C++ has been the inability to use allocators in non-generic contexts.
In large software systems, most of the application program consists of non-generic
procedural or object-oriented code that is compiled once and linked many
times.</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>Allocators in C++, however, have historically relied solely
on compile-time polymorphism, and therefore have not been suitable for use
in vocabulary types, which are passed through interfaces between separately-compiled
modules, because the allocator type necessarily affects the type of the object
that uses it. This proposal builds upon the improvements made to allocators
in C++11 and describes a set of facilities for runtime polymorphic memory
resources that interoperate with the existing compile-time polymorphic allocators.</em></span></span></span>
</p>
<p>
Most utilities from the Fundamentals TS were merged into C++17, but <span class="bold"><strong>Boost.Container</strong></span> offers them for C++03, C++11 and C++14
compilers.
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> implements nearly all classes
of the proposal under the namespace <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">pmr</span></code>.
There are two groups,
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Header only utilities (these don't require the separately compiled library):
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/pmr/memory_resource.html" title="Class memory_resource">memory_resource</a></code>.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/pmr/resource_adaptor.html" title="Type definition resource_adaptor">resource_adaptor</a></code>.
</li>
</ul></div>
</li>
<li class="listitem">
Utilities that require the the separately compiled library:
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/pmr/polymorphic_allocator.html" title="Class template polymorphic_allocator">polymorphic_allocator</a></code>.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/pmr/monotonic_buffer_resource.html" title="Class monotonic_buffer_resource">monotonic_buffer_resource</a></code>.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/pmr/unsynchr_idm46288252717728.html" title="Class unsynchronized_pool_resource">unsynchronized_pool_resource</a></code>.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/pmr/synchronized_pool_resource.html" title="Class synchronized_pool_resource">synchronized_pool_resource</a></code>.
</li>
<li class="listitem">
Global resource functions: <code class="computeroutput"><a class="link" href="../boost/container/pmr/get_default_resource.html" title="Function get_default_resource">get_default_resource</a></code>/
<code class="computeroutput"><a class="link" href="../boost/container/pmr/set_default_resource.html" title="Function set_default_resource">set_default_resource</a></code>/
<code class="computeroutput"><a class="link" href="../boost/container/pmr/new_delete_resource.html" title="Function new_delete_resource">new_delete_resource</a></code>/
<code class="computeroutput"><a class="link" href="../boost/container/pmr/null_memory_resource.html" title="Function null_memory_resource">null_memory_resource</a></code>
</li>
<li class="listitem">
Aliases for boost containers using the polymorphic allocator (like
<code class="computeroutput"><a class="link" href="../boost_container_header_reference.html#boost.container.pmr.vector">pmr::vector</a></code>,
etc.)
</li>
</ul></div>
</li>
</ul></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span>'s polymorphic resource library
is usable from C++03 containers, and offers some alternative utilities if
the required C++11 features of the <span class="emphasis"><em>Library Fundamentals</em></span>
specification are not available.
</p>
<p>
Let's review the usage example given in <a href="https://isocpp.org/files/papers/N3916.pdf" target="_top">N3916</a>
and see how it can be implemented using <span class="bold"><strong>Boost.Container</strong></span>:
<span class="emphasis"><em>Suppose we are processing a series of shopping lists, where a shopping
list is a container of strings, and storing them in a collection (a list)
of shopping lists. Each shopping list being processed uses a bounded amount
of memory that is needed for a short period of time, while the collection
of shopping lists uses an unbounded amount of memory and will exist for a
longer period of time. For efficiency, we can use a more time-efficient memory
allocator based on a finite buffer for the temporary shopping lists.</em></span>
</p>
<p>
Let's see how <code class="computeroutput"><span class="identifier">ShoppingList</span></code>
can be defined to support an polymorphic memory resource that can allocate
memory from different underlying mechanisms. The most important details are:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
It should declare that supports an allocator defining an <code class="computeroutput"><span class="identifier">allocator_type</span></code> typedef. This <code class="computeroutput"><span class="identifier">allocator_type</span></code> will be of type <code class="computeroutput"><a class="link" href="../boost/container/pmr/memory_resource.html" title="Class memory_resource">memory_resource *</a></code>,
which is a base class for polymorphic resources.
</li>
<li class="listitem">
It must define constructors that take the the allocator as argument.
It can be implemented in two ways:
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">ShoppingList</span></code> has
constructors taking <code class="computeroutput"><a class="link" href="../boost/container/pmr/memory_resource.html" title="Class memory_resource">memory_resource*</a></code>
as the last argument.
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">ShoppingList</span></code> has
constructors taking <code class="computeroutput"><a class="link" href="../boost/container/allocator_arg_t.html" title="Type definition allocator_arg_t">allocator_arg_t</a></code>
as the first argument and <code class="computeroutput"><a class="link" href="../boost/container/pmr/memory_resource.html" title="Class memory_resource">memory_resource*</a></code>
as the second argument.
</li>
</ul></div>
</li>
</ul></div>
<p>
<span class="bold"><strong>Note:</strong></span> <span class="emphasis"><em>In C++03 compilers, it is
required that the programmer specializes as <code class="computeroutput"><span class="keyword">true</span></code>
<code class="computeroutput"><a class="link" href="../boost/container/construc_idm46288248430944.html" title="Struct template constructible_with_allocator_suffix">constructible_with_allocator_suffix</a></code>
or <code class="computeroutput"><a class="link" href="../boost/container/construc_idm46288248441312.html" title="Struct template constructible_with_allocator_prefix">constructible_with_allocator_prefix</a></code>
as in C++03 there is no way to automatically detect the chosen option at
compile time. If no specialization is done, <span class="bold"><strong>Boost.Container</strong></span>
assumes the suffix option</em></span>.
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">//ShoppingList.hpp</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">pmr</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">pmr</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">ShoppingList</span>
<span class="special">{</span>
<span class="comment">// A vector of strings using polymorphic allocators. Every element</span>
<span class="comment">// of the vector will use the same allocator as the vector itself.</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">pmr</span><span class="special">::</span><span class="identifier">vector_of</span>
<span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">pmr</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">m_strvec</span><span class="special">;</span>
<span class="comment">//Alternatively in compilers that support template aliases:</span>
<span class="comment">// boost::container::pmr::vector&lt;boost::container::pmr::string&gt; m_strvec;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="comment">// This makes uses_allocator&lt;ShoppingList, memory_resource*&gt;::value true</span>
<span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">pmr</span><span class="special">::</span><span class="identifier">memory_resource</span><span class="special">*</span> <span class="identifier">allocator_type</span><span class="special">;</span>
<span class="comment">// If the allocator is not specified, "m_strvec" uses pmr::get_default_resource().</span>
<span class="keyword">explicit</span> <span class="identifier">ShoppingList</span><span class="special">(</span><span class="identifier">allocator_type</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">m_strvec</span><span class="special">(</span><span class="identifier">alloc</span><span class="special">)</span> <span class="special">{}</span>
<span class="comment">// Copy constructor. As allocator is not specified,</span>
<span class="comment">// "m_strvec" uses pmr::get_default_resource().</span>
<span class="identifier">ShoppingList</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">ShoppingList</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">m_strvec</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">m_strvec</span><span class="special">)</span> <span class="special">{}</span>
<span class="comment">// Copy construct using the given memory_resource.</span>
<span class="identifier">ShoppingList</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">ShoppingList</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">,</span> <span class="identifier">allocator_type</span> <span class="identifier">a</span><span class="special">)</span>
<span class="special">:</span> <span class="identifier">m_strvec</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">m_strvec</span><span class="special">,</span> <span class="identifier">a</span><span class="special">)</span> <span class="special">{}</span>
<span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span>
<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">m_strvec</span><span class="special">.</span><span class="identifier">get_allocator</span><span class="special">().</span><span class="identifier">resource</span><span class="special">();</span> <span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">add_item</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">item</span><span class="special">)</span>
<span class="special">{</span> <span class="identifier">m_strvec</span><span class="special">.</span><span class="identifier">emplace_back</span><span class="special">(</span><span class="identifier">item</span><span class="special">);</span> <span class="special">}</span>
<span class="comment">//...</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
<span class="emphasis"><em>However, this time-efficient allocator is not appropriate for the
longer lived collection of shopping lists. This example shows how those temporary
shopping lists, using a time-efficient allocator, can be used to populate
the long lived collection of shopping lists, using a general purpose allocator,
something that would be annoyingly difficult without the polymorphic allocators.</em></span>
</p>
<p>
In <span class="bold"><strong>Boost.Container</strong></span> for the time-efficient
allocation we can use <code class="computeroutput"><a class="link" href="../boost/container/pmr/monotonic_buffer_resource.html" title="Class monotonic_buffer_resource">monotonic_buffer_resource</a></code>,
providing an external buffer that will be used until it's exhausted. In the
default configuration, when the buffer is exhausted, the default memory resource
will be used instead.
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="string">"ShoppingList.hpp"</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">pmr</span><span class="special">/</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">pmr</span><span class="special">/</span><span class="identifier">monotonic_buffer_resource</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">processShoppingList</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">ShoppingList</span><span class="special">&amp;)</span>
<span class="special">{</span> <span class="comment">/**/</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//All memory needed by folder and its contained objects will</span>
<span class="comment">//be allocated from the default memory resource (usually new/delete) </span>
<span class="identifier">pmr</span><span class="special">::</span><span class="identifier">list_of</span><span class="special">&lt;</span><span class="identifier">ShoppingList</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">folder</span><span class="special">;</span> <span class="comment">// Default allocator resource</span>
<span class="comment">//Alternatively in compilers that support template aliases:</span>
<span class="comment">// boost::container::pmr::list&lt;ShoppingList&gt; folder;</span>
<span class="special">{</span>
<span class="keyword">char</span> <span class="identifier">buffer</span><span class="special">[</span><span class="number">1024</span><span class="special">];</span>
<span class="identifier">pmr</span><span class="special">::</span><span class="identifier">monotonic_buffer_resource</span> <span class="identifier">buf_rsrc</span><span class="special">(&amp;</span><span class="identifier">buffer</span><span class="special">,</span> <span class="number">1024</span><span class="special">);</span>
<span class="comment">//All memory needed by temporaryShoppingList will be allocated</span>
<span class="comment">//from the local buffer (speeds up "processShoppingList")</span>
<span class="identifier">ShoppingList</span> <span class="identifier">temporaryShoppingList</span><span class="special">(&amp;</span><span class="identifier">buf_rsrc</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(&amp;</span><span class="identifier">buf_rsrc</span> <span class="special">==</span> <span class="identifier">temporaryShoppingList</span><span class="special">.</span><span class="identifier">get_allocator</span><span class="special">());</span>
<span class="comment">//list nodes, and strings "salt" and "pepper" will be allocated</span>
<span class="comment">//in the stack thanks to "monotonic_buffer_resource".</span>
<span class="identifier">temporaryShoppingList</span><span class="special">.</span><span class="identifier">add_item</span><span class="special">(</span><span class="string">"salt"</span><span class="special">);</span>
<span class="identifier">temporaryShoppingList</span><span class="special">.</span><span class="identifier">add_item</span><span class="special">(</span><span class="string">"pepper"</span><span class="special">);</span>
<span class="comment">//...</span>
<span class="comment">//All modifications and additions to "temporaryShoppingList"</span>
<span class="comment">//will use memory from "buffer" until it's exhausted.</span>
<span class="identifier">processShoppingList</span><span class="special">(</span><span class="identifier">temporaryShoppingList</span><span class="special">);</span>
<span class="comment">//Processing done, now insert it in "folder",</span>
<span class="comment">//which uses the default memory resource</span>
<span class="identifier">folder</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">temporaryShoppingList</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">pmr</span><span class="special">::</span><span class="identifier">get_default_resource</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">folder</span><span class="special">.</span><span class="identifier">back</span><span class="special">().</span><span class="identifier">get_allocator</span><span class="special">());</span>
<span class="comment">//temporaryShoppingList, buf_rsrc, and buffer go out of scope</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
<span class="emphasis"><em>Notice that the shopping lists within <code class="computeroutput"><span class="identifier">folder</span></code>
use the default allocator resource whereas the shopping list <code class="computeroutput"><span class="identifier">temporaryShoppingList</span></code> uses the short-lived
but very fast <code class="computeroutput"><span class="identifier">buf_rsrc</span></code>. Despite
using different allocators, you can insert <code class="computeroutput"><span class="identifier">temporaryShoppingList</span></code>
into folder because they have the same <code class="computeroutput"><span class="identifier">ShoppingList</span></code>
type. Also, while <code class="computeroutput"><span class="identifier">ShoppingList</span></code>
uses memory_resource directly, <code class="computeroutput"><a class="link" href="../boost_container_header_reference.html#boost.container.pmr.list">pmr::list</a></code>,
<code class="computeroutput"><a class="link" href="../boost_container_header_reference.html#boost.container.pmr.vector">pmr::vector</a></code> and
<code class="computeroutput"><a class="link" href="../boost_container_header_reference.html#boost.container.pmr.string">pmr::string</a></code> all
use <code class="computeroutput"><a class="link" href="../boost/container/pmr/polymorphic_allocator.html" title="Class template polymorphic_allocator">polymorphic_allocator</a></code>.</em></span>
</p>
<p>
<span class="emphasis"><em>The resource passed to the <code class="computeroutput"><span class="identifier">ShoppingList</span></code>
constructor is propagated to the vector and each string within that <code class="computeroutput"><span class="identifier">ShoppingList</span></code>. Similarly, the resource used
to construct <code class="computeroutput"><span class="identifier">folder</span></code> is propagated
to the constructors of the ShoppingLists that are inserted into the list
(and to the strings within those <code class="computeroutput"><span class="identifier">ShoppingLists</span></code>).
The <code class="computeroutput"><a class="link" href="../boost/container/pmr/polymorphic_allocator.html" title="Class template polymorphic_allocator">polymorphic_allocator</a></code>
template is designed to be almost interchangeable with a pointer to <code class="computeroutput"><a class="link" href="../boost/container/pmr/memory_resource.html" title="Class memory_resource">memory_resource</a></code>,
thus producing a <span class="emphasis"><em>bridge</em></span> between the template-policy
style of allocator and the polymorphic-base-class style of allocator.</em></span>
</p>
<p>
This example actually shows how easy is to use <span class="bold"><strong>Boost.Container</strong></span>
to write type-erasured allocator-capable classes even in C++03 compilers.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.forward_list"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.forward_list" title="forward_list&lt;T&gt;"><code class="computeroutput"><span class="identifier">forward_list</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code></a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span> does not offer C++11 <code class="computeroutput"><span class="identifier">forward_list</span></code> container yet, but it will
be available in future versions.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.vector_exception_guarantees"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.vector_exception_guarantees" title="vector vs. std::vector exception guarantees"><code class="computeroutput"><span class="identifier">vector</span></code> vs. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
exception guarantees</a>
</h3></div></div></div>
<p>
<code class="computeroutput"><a class="link" href="../boost/container/vector.html" title="Class template vector">vector</a></code> does not support
the strong exception guarantees given by <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>
in functions like <code class="computeroutput"><span class="identifier">insert</span></code>,
<code class="computeroutput"><span class="identifier">push_back</span></code>, <code class="computeroutput"><span class="identifier">emplace</span></code>, <code class="computeroutput"><span class="identifier">emplace_back</span></code>,
<code class="computeroutput"><span class="identifier">resize</span></code>, <code class="computeroutput"><span class="identifier">reserve</span></code>
or <code class="computeroutput"><span class="identifier">shrink_to_fit</span></code> for either
copyable or no-throw moveable classes. In C++11 <a href="http://en.cppreference.com/w/cpp/utility/move_if_noexcept" target="_top">move_if_noexcept</a>
is used to maintain C++03 exception safety guarantees combined with C++11
move semantics. This strong exception guarantee degrades the insertion performance
of copyable and throwing-moveable types, degrading moves to copies when such
types are inserted in the vector using the aforementioned members.
</p>
<p>
This strong exception guarantee also precludes the possibility of using some
type of in-place reallocations that can further improve the insertion performance
of <code class="computeroutput"><span class="identifier">vector</span></code> See <a class="link" href="extended_allocators.html" title="Extended functionality: Extended allocators">Extended
Allocators</a> to know more about these optimizations.
</p>
<p>
<code class="computeroutput"><a class="link" href="../boost/container/vector.html" title="Class template vector">vector</a></code> always uses
move constructors/assignments to rearrange elements in the vector and uses
memory expansion mechanisms if the allocator supports them, while offering
only basic safety guarantees. It trades off exception guarantees for an improved
performance.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.container_const_reference_parameters"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.container_const_reference_parameters" title="Parameter taken by const reference that can be changed">Parameter
taken by const reference that can be changed</a>
</h3></div></div></div>
<p>
Several container operations use a parameter taken by const reference that
can be changed during execution of the function. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#526" target="_top">LWG
Issue 526 (<span class="emphasis"><em>Is it undefined if a function in the standard changes
in parameters?</em></span>)</a> discusses them:
</p>
<pre class="programlisting"><span class="comment">//Given std::vector&lt;int&gt; v</span>
<span class="identifier">v</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v</span><span class="special">[</span><span class="number">2</span><span class="special">]);</span>
<span class="comment">//v[2] can be changed by moving elements of vector</span>
<span class="comment">//Given std::list&lt;int&gt; l:</span>
<span class="identifier">l</span><span class="special">.</span><span class="identifier">remove</span><span class="special">(*</span><span class="identifier">l</span><span class="special">.</span><span class="identifier">begin</span><span class="special">())</span>
<span class="comment">//The operation could delete the first element, and then continue trying to access it.</span>
</pre>
<p>
The adopted resolution, NAD (Not A Defect), implies that previous operations
must be well-defined. This requires code to detect a reference to an inserted
element and an additional copy in that case, impacting performance even when
references to already inserted objects are not used. Note that equivalent
functions taking rvalue references or iterator ranges require elements not
already inserted in the container.
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> prioritizes performance
and has not implemented the NAD resolution: in functions that might modify
the argument, the library requires references to elements not stored in the
container. Using references to inserted elements yields to undefined behaviour
(although in debug mode, this precondition violation could be notified via
BOOST_ASSERT).
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.Vector_bool"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.Vector_bool" title="vector&lt;bool&gt; specialization"><code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code> specialization</a>
</h3></div></div></div>
<p>
<code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code> specialization
has been quite problematic, and there have been several unsuccessful tries
to deprecate or remove it from the standard. <span class="bold"><strong>Boost.Container</strong></span>
does not implement it as there is a superior <a href="http://www.boost.org/libs/dynamic_bitset/" target="_top">Boost.DynamicBitset</a>
solution. For issues with <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code>
see the following papers:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a href="http://howardhinnant.github.io/onvectorbool.html" target="_top">On <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code></a>
</li>
<li class="listitem">
<a href="http://www.gotw.ca/publications/N1211.pdf" target="_top">vector&lt;bool&gt;:
N1211: More Problems, Better Solutions</a>,
</li>
<li class="listitem">
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2160.html" target="_top">N2160:
Library Issue 96: Fixing vector&lt;bool&gt;</a>,
</li>
<li class="listitem">
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2204.html" target="_top">N2204
A Specification to deprecate vector&lt;bool&gt;</a>.
</li>
</ul></div>
<p>
Quotes:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>But it is a shame that the C++ committee gave this excellent
data structure the name vector&lt;bool&gt; and that it gives no guidance
nor encouragement on the critical generic algorithms that need to be
optimized for this data structure. Consequently, few std::lib implementations
go to this trouble.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>In 1998, admitting that the committee made a mistake
was controversial. Since then Java has had to deprecate such significant
portions of their libraries that the idea C++ would be ridiculed for
deprecating a single minor template specialization seems quaint.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em><code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code> is not a container and <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;::</span><span class="identifier">iterator</span></code> is not a random-access iterator
(or even a forward or bidirectional iterator either, for that matter).
This has already broken user code in the field in mysterious ways.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em><code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code> forces a specific (and potentially
bad) optimization choice on all users by enshrining it in the standard.
The optimization is premature; different users have different requirements.
This too has already hurt users who have been forced to implement workarounds
to disable the 'optimization' (e.g., by using a vector&lt;char&gt; and
manually casting to/from bool).</em></span></span></span>
</li>
</ul></div>
<p>
So <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;::</span><span class="identifier">iterator</span></code> returns real <code class="computeroutput"><span class="keyword">bool</span></code>
references and works as a fully compliant container. If you need a memory
optimized version of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code>,
please use <a href="http://www.boost.org/libs/dynamic_bitset/" target="_top">Boost.DynamicBitset</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.cpp_conformance.non_standard_memset_initialization"></a><a class="link" href="cpp_conformance.html#container.cpp_conformance.non_standard_memset_initialization" title="Non-standard value initialization using std::memset">Non-standard
value initialization using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">memset</span></code></a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span> uses <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">memset</span></code>
with a zero value to initialize some types as in most platforms this initialization
yields to the desired value initialization with improved performance.
</p>
<p>
Following the C11 standard, <span class="bold"><strong>Boost.Container</strong></span>
assumes that <span class="emphasis"><em>for any integer type, the object representation where
all the bits are zero shall be a representation of the value zero in that
type</em></span>. Since <code class="computeroutput"><span class="identifier">_Bool</span></code>/<code class="computeroutput"><span class="keyword">wchar_t</span></code>/<code class="computeroutput"><span class="keyword">char16_t</span></code>/<code class="computeroutput"><span class="keyword">char32_t</span></code> are also integer types in C, it considers
all C++ integral types as initializable via <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">memset</span></code>.
</p>
<p>
By default, <span class="bold"><strong>Boost.Container</strong></span> also considers
floating point types to be initializable using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">memset</span></code>.
Most platforms are compatible with this initialization, but in case this
initialization is not desirable the user can <code class="computeroutput"><span class="preprocessor">#define</span>
<span class="identifier">BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO</span></code>
before including library headers.
</p>
<p>
By default, it also considers pointer types (pointer and pointer to function
types, excluding member object and member function pointers) to be initializable
using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">memset</span></code>. Most platforms are compatible with
this initialization, but in case this initialization is not desired the user
can <code class="computeroutput"><span class="preprocessor">#define</span> <span class="identifier">BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_ZERO</span></code>
before including library headers.
</p>
<p>
If neither <code class="computeroutput"><span class="identifier">BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO</span></code>
nor <code class="computeroutput"><span class="identifier">BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_ZERO</span></code>
is defined <span class="bold"><strong>Boost.Container</strong></span> also considers
POD types to be value initializable via <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">memset</span></code>
with value zero.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="extended_allocators.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="known_issues.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,141 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Boost.Container and C++ exceptions</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="main_features.html" title="Main features">
<link rel="next" href="non_standard_containers.html" title="Non-standard containers">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="main_features.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="non_standard_containers.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.exception_handling"></a><a class="link" href="exception_handling.html" title="Boost.Container and C++ exceptions">Boost.Container and C++ exceptions</a>
</h2></div></div></div>
<p>
In some environments, such as game development or embedded systems, C++ exceptions
are disabled or a customized error handling is needed. According to document
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html" target="_top">N2271
EASTL -- Electronic Arts Standard Template Library</a> exceptions can be
disabled for several reasons:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>Exception handling incurs some kind of cost in all compiler
implementations, including those that avoid the cost during normal execution.
However, in some cases this cost may arguably offset the cost of the code
that it is replacing.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>Exception handling is often agreed to be a superior solution
for handling a large range of function return values. However, avoiding
the creation of functions that need large ranges of return values is superior
to using exception handling to handle such values.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>Using exception handling correctly can be difficult in
the case of complex software.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>The execution of throw and catch can be significantly
expensive with some implementations.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>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 has
destructible stack objects regardless of whether they use exception handling.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>The approach that game software usually takes is to avoid
the need for exception handling where possible; avoid the possibility of
circumstances that may lead to exceptions. For example, verify up front
that there is enough memory for a subsystem to do its job instead of trying
to deal with the problem via exception handling or any other means after
it occurs.</em></span></span></span>
</li>
<li class="listitem">
<span class="quote"><span class="quote"><span class="emphasis"><em>However, some game libraries may nevertheless benefit
from the use of exception handling. It's best, however, if such libraries
keep the exception handling internal lest they force their usage of exception
handling on the rest of the application.</em></span></span></span>
</li>
</ul></div>
<p>
In order to support environments without C++ exception support or environments
with special error handling needs, <span class="bold"><strong>Boost.Container</strong></span>
changes error signalling behaviour when <code class="computeroutput"><span class="identifier">BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS</span></code>
or <code class="computeroutput"><span class="identifier">BOOST_NO_EXCEPTIONS</span></code> is defined.
The former shall be defined by the user and the latter can be either defined
by the user or implicitly defined by <span class="bold"><strong>Boost.Confg</strong></span>
when the compiler has been invoked with the appropriate flag (like <code class="computeroutput"><span class="special">-</span><span class="identifier">fno</span><span class="special">-</span><span class="identifier">exceptions</span></code> in GCC).
</p>
<p>
When dealing with user-defined classes, (e.g. when constructing user-defined
classes):
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
If <code class="computeroutput"><span class="identifier">BOOST_NO_EXCEPTIONS</span></code>
is defined, the library avoids using <code class="computeroutput"><span class="keyword">try</span></code>/<code class="computeroutput"><span class="keyword">catch</span></code>/<code class="computeroutput"><span class="keyword">throw</span></code>
statements. The class writer must handle and propagate error situations
internally as no error will be propagated through <span class="bold"><strong>Boost.Container</strong></span>.
</li>
<li class="listitem">
If <code class="computeroutput"><span class="identifier">BOOST_NO_EXCEPTIONS</span></code>
is <span class="bold"><strong>not</strong></span> defined, the library propagates
exceptions offering the exception guarantees detailed in the documentation.
</li>
</ul></div>
<p>
When the library needs to throw an exception (such as <code class="computeroutput"><span class="identifier">out_of_range</span></code>
when an incorrect index is used in <code class="computeroutput"><span class="identifier">vector</span><span class="special">::</span><span class="identifier">at</span></code>), the
library calls a throw-callback declared in <code class="computeroutput"><a class="link" href="../boost_container_header_reference.html#header.boost.container.throw_exception_hpp" title="Header &lt;boost/container/throw_exception.hpp&gt;">boost/container/throw_exception.hpp</a></code>:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
If <code class="computeroutput"><span class="identifier">BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS</span></code>
is defined, then the programmer must provide its own definition for all
<code class="computeroutput"><span class="identifier">throw_xxx</span></code> functions. Those
functions can't return, they must throw an exception or call <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exit</span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">abort</span></code>.
</li>
<li class="listitem">
Else if <code class="computeroutput"><span class="identifier">BOOST_NO_EXCEPTIONS</span></code>
is defined, a <code class="computeroutput"><span class="identifier">BOOST_ASSERT_MSG</span></code>
assertion is triggered (see <a href="http://www.boost.org/libs/utility/assert.html" target="_top">Boost.Assert</a>
for more information). If this assertion returns, then <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">abort</span></code>
is called.
</li>
<li class="listitem">
Else, an appropriate standard library exception is thrown (like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">out_of_range</span></code>).
</li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="main_features.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="non_standard_containers.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,159 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Extended functionality: Extended allocators</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="configurable_containers.html" title="Extended functionality: Configurable containers">
<link rel="next" href="cpp_conformance.html" title="C++11/C++14/C++17 Conformance">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="configurable_containers.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="cpp_conformance.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.extended_allocators"></a><a class="link" href="extended_allocators.html" title="Extended functionality: Extended allocators">Extended functionality:
Extended allocators</a>
</h2></div></div></div>
<p>
Many C++ programmers have ever wondered where does good old realloc fit in
C++. And that's a good question. Could we improve <code class="computeroutput"><a class="link" href="../boost/container/vector.html" title="Class template vector">vector</a></code>
performance using memory expansion mechanisms to avoid too many copies? But
<code class="computeroutput"><a class="link" href="../boost/container/vector.html" title="Class template vector">vector</a></code> is not the only
container that could benefit from an improved allocator interface: we could
take advantage of the insertion of multiple elements in <code class="computeroutput"><a class="link" href="../boost/container/list.html" title="Class template list">list</a></code>
using a burst allocation mechanism that could amortize costs (mutex locks,
free memory searches...) that can't be amortized when using single node allocation
strategies.
</p>
<p>
These improvements require extending the STL allocator interface and use make
use of a new general purpose allocator since new and delete don't offer expansion
and burst capabilities.
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Boost.Container</strong></span> containers support an
extended allocator interface based on an evolution of proposals <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1953.html" target="_top">N1953:
Upgrading the Interface of Allocators using API Versioning</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2045.html" target="_top">N2045:
Improving STL allocators</a> and the article <a href="http://www.drivehq.com/web/igaztanaga/allocplus/" target="_top">Applying
classic memory allocation strategies to C++ containers</a>. The extended
allocator interface is implemented by <code class="computeroutput"><a class="link" href="../boost/container/allocator.html" title="Class template allocator">allocator</a></code>,
<code class="computeroutput"><a class="link" href="../boost/container/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</a></code>
and <code class="computeroutput"><a class="link" href="../boost/container/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>
classes.
</li>
<li class="listitem">
Extended allocators use a modified <a href="http://g.oswego.edu/dl/html/malloc.html" target="_top">Doug
Lea Malloc (DLMalloc)</a> low-level allocator and offers an C API to
implement memory expansion and burst allocations. DLmalloc is known to
be very size and speed efficient, and this allocator is used as the basis
of many malloc implementations, including multithreaded allocators built
above DLmalloc (See <a href="http://www.malloc.de/en/" target="_top">ptmalloc2, ptmalloc3</a>
or <a href="http://www.nedprod.com/programs/portable/nedmalloc/" target="_top">nedmalloc</a>).
This low-level allocator is implemented as a separately compiled library
and the following extended allocators depend on the library:
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/allocator.html" title="Class template allocator">allocator</a></code>: This
extended allocator offers expansion, shrink-in place and burst allocation
capabilities implemented as a thin wrapper around the modified DLMalloc.
It can be used with all containers and it should be the default choice
when the programmer wants to use extended allocator capabilities.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>:
It's a <a href="http://www.boost.org/doc/libs/1_55_0/libs/pool/doc/html/boost_pool/pool/pooling.html#boost_pool.pool.pooling.simple" target="_top">Simple
Segregated Storage</a> allocator, similar to <span class="bold"><strong>Boost.Pool</strong></span>
that takes advantage of the modified DLMalloc burst interface. It does
not return memory to the DLMalloc allocator (and thus, to the system),
unless explicitly requested. It does offer a very small memory overhead
so it's suitable for node containers ([boost::container::list list], [boost::container::slist
slist] [boost::container::set set]...) that allocate very small <code class="computeroutput"><span class="identifier">value_type</span></code>s and it offers improved node
allocation times for single node allocations with respecto to <code class="computeroutput"><a class="link" href="../boost/container/allocator.html" title="Class template allocator">allocator</a></code>.
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/container/adaptive_pool.html" title="Class template adaptive_pool">adaptive_pool</a></code>:
It's a low-overhead node allocator that can return memory to the system.
The overhead can be very low (&lt; 5% for small nodes) and it's nearly
as fast as <code class="computeroutput"><a class="link" href="../boost/container/node_allocator.html" title="Class template node_allocator">node_allocator</a></code>.
It's also suitable for node containers.
</li>
</ul></div>
<p>
Use them simply specifying the new allocator in the corresponding template
argument of your favourite container:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">flat_set</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">set</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//"allocator" is a general purpose allocator that can reallocate</span>
<span class="comment">//memory, something useful for vector and flat associative containers</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">allocator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//"adaptive_pool" is a node allocator, specially suited for</span>
<span class="comment">//node-based containers</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">adaptive_pool</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//A vector that can reallocate memory to implement faster insertions</span>
<span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">extended_alloc_vector</span><span class="special">;</span>
<span class="comment">//A flat set that can reallocate memory to implement faster insertions</span>
<span class="identifier">flat_set</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">allocator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">extended_alloc_flat_set</span><span class="special">;</span>
<span class="comment">//A list that can manages nodes to implement faster</span>
<span class="comment">//range insertions and deletions</span>
<span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">adaptive_pool</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">extended_alloc_list</span><span class="special">;</span>
<span class="comment">//A set that can recycle nodes to implement faster</span>
<span class="comment">//range insertions and deletions</span>
<span class="identifier">set</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="identifier">adaptive_pool</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">extended_alloc_set</span><span class="special">;</span>
<span class="comment">//Now user them as always</span>
<span class="identifier">extended_alloc_vector</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="identifier">extended_alloc_flat_set</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="identifier">extended_alloc_list</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="identifier">extended_alloc_set</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
<span class="comment">//...</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="configurable_containers.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="cpp_conformance.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,176 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Extended functionality: Basic extensions</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="non_standard_containers.html" title="Non-standard containers">
<link rel="next" href="configurable_containers.html" title="Extended functionality: Configurable containers">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="non_standard_containers.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="configurable_containers.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.extended_functionality"></a><a class="link" href="extended_functionality.html" title="Extended functionality: Basic extensions">Extended functionality:
Basic extensions</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="extended_functionality.html#container.extended_functionality.default_initialialization">Default
initialization for vector-like containers</a></span></dt>
<dt><span class="section"><a href="extended_functionality.html#container.extended_functionality.ordered_range_insertion">Ordered
range insertion for associative containers (<span class="emphasis"><em>ordered_unique_range</em></span>,
<span class="emphasis"><em>ordered_range</em></span>) </a></span></dt>
<dt><span class="section"><a href="extended_functionality.html#container.extended_functionality.constant_time_range_splice">Constant-time
range splice for <code class="computeroutput"><span class="special">(</span><span class="identifier">s</span><span class="special">)</span><span class="identifier">list</span></code></a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.extended_functionality.default_initialialization"></a><a class="link" href="extended_functionality.html#container.extended_functionality.default_initialialization" title="Default initialization for vector-like containers">Default
initialization for vector-like containers</a>
</h3></div></div></div>
<p>
STL and most other containers value initialize new elements in common operations
like <code class="computeroutput"><span class="identifier">vector</span><span class="special">::</span><span class="identifier">resize</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">)</span></code> or <code class="computeroutput"><span class="keyword">explicit</span>
<span class="identifier">vector</span><span class="special">::</span><span class="identifier">vector</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">)</span></code>.
</p>
<p>
In some performance-sensitive environments, where vectors are used as a replacement
for variable-size buffers for file or network operations, <a href="http://en.cppreference.com/w/cpp/language/value_initialization" target="_top">value
initialization</a> is a cost that is not negligible as elements are going
to be overwritten by an external source shortly after new elements are added
to the container.
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> offers two new members for
<code class="computeroutput"><span class="identifier">vector</span></code>, <code class="computeroutput"><span class="identifier">static_vector</span></code>
and <code class="computeroutput"><span class="identifier">stable_vector</span></code>: <code class="computeroutput"><span class="keyword">explicit</span> <span class="identifier">container</span><span class="special">::</span><span class="identifier">container</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">,</span> <span class="identifier">default_init_t</span><span class="special">)</span></code> and <code class="computeroutput"><span class="identifier">container</span><span class="special">::</span><span class="identifier">resize</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">,</span> <span class="identifier">default_init_t</span><span class="special">)</span></code>, where new elements are constructed using
<a href="http://en.cppreference.com/w/cpp/language/default_initialization" target="_top">default
initialization</a>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.extended_functionality.ordered_range_insertion"></a><a class="link" href="extended_functionality.html#container.extended_functionality.ordered_range_insertion" title="Ordered range insertion for associative containers (ordered_unique_range, ordered_range)">Ordered
range insertion for associative containers (<span class="emphasis"><em>ordered_unique_range</em></span>,
<span class="emphasis"><em>ordered_range</em></span>) </a>
</h3></div></div></div>
<p>
When filling associative containers big performance gains can be achieved
if the input range to be inserted is guaranteed by the user to be ordered
according to the predicate. This can happen when inserting values from a
<code class="computeroutput"><span class="identifier">set</span></code> to a <code class="computeroutput"><span class="identifier">multiset</span></code>
or between different associative container families (<code class="computeroutput"><span class="special">[</span><span class="identifier">multi</span><span class="special">]</span><span class="identifier">set</span><span class="special">/</span><span class="identifier">map</span></code>
vs. <code class="computeroutput"><span class="identifier">flat_</span><span class="special">[</span><span class="identifier">multi</span><span class="special">]</span><span class="identifier">set</span><span class="special">/</span><span class="identifier">map</span></code>).
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> has some overloads for constructors
and insertions taking an <code class="computeroutput"><span class="identifier">ordered_unique_range_t</span></code>
or an <code class="computeroutput"><span class="identifier">ordered_range_t</span></code> tag
parameters as the first argument. When an <code class="computeroutput"><span class="identifier">ordered_unique_range_t</span></code>
overload is used, the user notifies the container that the input range is
ordered according to the container predicate and has no duplicates. When
an <code class="computeroutput"><span class="identifier">ordered_range_t</span></code> overload
is used, the user notifies the container that the input range is ordered
according to the container predicate but it might have duplicates. With this
information, the container can avoid multiple predicate calls and improve
insertion times.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.extended_functionality.constant_time_range_splice"></a><a class="link" href="extended_functionality.html#container.extended_functionality.constant_time_range_splice" title="Constant-time range splice for (s)list">Constant-time
range splice for <code class="computeroutput"><span class="special">(</span><span class="identifier">s</span><span class="special">)</span><span class="identifier">list</span></code></a>
</h3></div></div></div>
<p>
In the first C++ standard <code class="computeroutput"><span class="identifier">list</span><span class="special">::</span><span class="identifier">size</span><span class="special">()</span></code> was not required to be constant-time, and
that caused some controversy in the C++ community. Quoting Howard Hinnant's
<a href="http://howardhinnant.github.io/On_list_size.html" target="_top"><span class="emphasis"><em>On
List Size</em></span></a> paper:
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
<span class="emphasis"><em>There is a considerable debate on whether <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">size</span><span class="special">()</span></code> should be O(1) or O(N). The usual argument
notes that it is a tradeoff with:</em></span>
</p>
<p>
<code class="computeroutput"><span class="identifier">splice</span><span class="special">(</span><span class="identifier">iterator</span> <span class="identifier">position</span><span class="special">,</span> <span class="identifier">list</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">iterator</span>
<span class="identifier">first</span><span class="special">,</span>
<span class="identifier">iterator</span> <span class="identifier">last</span><span class="special">);</span></code>
</p>
<p>
<span class="emphasis"><em>If size() is O(1) and this != &amp;x, then this method must perform
a linear operation so that it can adjust the size member in each list</em></span>
</p>
</blockquote></div>
<p>
C++11 definitely required <code class="computeroutput"><span class="identifier">size</span><span class="special">()</span></code> to be O(1), so range splice became O(N).
However, Howard Hinnant's paper proposed a new <code class="computeroutput"><span class="identifier">splice</span></code>
overload so that even O(1) <code class="computeroutput"><span class="identifier">list</span><span class="special">:</span><span class="identifier">size</span><span class="special">()</span></code>
implementations could achieve O(1) range splice when the range size was known
to the caller:
</p>
<div class="blockquote"><blockquote class="blockquote">
<p>
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">splice</span><span class="special">(</span><span class="identifier">iterator</span> <span class="identifier">position</span><span class="special">,</span> <span class="identifier">list</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">iterator</span>
<span class="identifier">first</span><span class="special">,</span>
<span class="identifier">iterator</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">size_type</span>
<span class="identifier">n</span><span class="special">);</span></code>
</p>
<p>
<span class="bold"><strong>Effects</strong></span>: Inserts elements in the range
[first, last) before position and removes the elements from x.
</p>
<p>
<span class="bold"><strong>Requires</strong></span>: [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).
</p>
<p>
<span class="bold"><strong>Throws</strong></span>: Nothing.
</p>
<p>
<span class="bold"><strong>Complexity</strong></span>: Constant time.
</p>
</blockquote></div>
<p>
This new splice signature allows the client to pass the distance of the input
range in. This information is often available at the call site. If it is
passed in, then the operation is constant time, even with an O(1) size.
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> implements this overload
for <code class="computeroutput"><span class="identifier">list</span></code> and a modified version
of it for <code class="computeroutput"><span class="identifier">slist</span></code> (as <code class="computeroutput"><span class="identifier">slist</span><span class="special">::</span><span class="identifier">size</span><span class="special">()</span></code>
is also <code class="computeroutput"><span class="identifier">O</span><span class="special">(</span><span class="number">1</span><span class="special">)</span></code>).
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="non_standard_containers.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="configurable_containers.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,133 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>History and reasons to use Boost.Container</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="known_issues.html" title="Known Issues">
<link rel="next" href="index.html" title="Indexes">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="known_issues.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="index.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.history_and_reasons"></a><a class="link" href="history_and_reasons.html" title="History and reasons to use Boost.Container">History and reasons to use
Boost.Container</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="history_and_reasons.html#container.history_and_reasons.boost_container_history">Boost.Container
history</a></span></dt>
<dt><span class="section"><a href="history_and_reasons.html#container.history_and_reasons.Why_boost_container">Why
Boost.Container?</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.history_and_reasons.boost_container_history"></a><a class="link" href="history_and_reasons.html#container.history_and_reasons.boost_container_history" title="Boost.Container history">Boost.Container
history</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span> is a product of a long development
effort that started <a href="http://lists.boost.org/Archives/boost/2004/11/76263.php" target="_top">in
2004 with the experimental Shmem library</a>, which pioneered the use
of standard containers in shared memory. Shmem included modified SGI STL
container code tweaked to support non-raw <code class="computeroutput"><span class="identifier">allocator</span><span class="special">::</span><span class="identifier">pointer</span></code>
types and stateful allocators. Once reviewed, Shmem was accepted as <a href="http://www.boost.org/libs/interprocess/" target="_top">Boost.Interprocess</a>
and this library continued to refine and improve those containers.
</p>
<p>
In 2007, container code from node containers (<code class="computeroutput"><span class="identifier">map</span></code>,
<code class="computeroutput"><span class="identifier">list</span></code>, <code class="computeroutput"><span class="identifier">slist</span></code>)
was rewritten, refactored and expanded to build the intrusive container library
<a href="http://www.boost.org/libs/intrusive/" target="_top">Boost.Intrusive</a>.
<span class="bold"><strong>Boost.Interprocess</strong></span> containers were refactored
to take advantage of <span class="bold"><strong>Boost.Intrusive</strong></span> containers
and code duplication was minimized. Both libraries continued to gain support
and bug fixes for years. They introduced move semantics, emplacement insertion
and more features of then unreleased C++0x standard.
</p>
<p>
<span class="bold"><strong>Boost.Interprocess</strong></span> containers were always
standard compliant, and those containers and new containers like <code class="computeroutput"><span class="identifier">stable_vector</span></code> and <code class="computeroutput"><span class="identifier">flat_</span><span class="special">[</span><span class="identifier">multi</span><span class="special">]</span><span class="identifier">set</span><span class="special">/</span><span class="identifier">map</span></code> were used outside <span class="bold"><strong>Boost.Interprocess</strong></span>
with success. As containers were mature enough to get their own library,
it was a natural step to collect them containers and build <span class="bold"><strong>Boost.Container</strong></span>,
a library targeted to a wider audience.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.history_and_reasons.Why_boost_container"></a><a class="link" href="history_and_reasons.html#container.history_and_reasons.Why_boost_container" title="Why Boost.Container?">Why
Boost.Container?</a>
</h3></div></div></div>
<p>
With so many high quality standard library implementations out there, why
would you want to use <span class="bold"><strong>Boost.Container</strong></span>? There
are several reasons for that:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Even if you have a earlier standard conforming compiler, you still can
have access to many of the latest C++ standard features and have an easy
code migration when you change your compiler.
</li>
<li class="listitem">
It's compatible with <span class="bold"><strong>Boost.Interprocess</strong></span>
shared memory allocators.
</li>
<li class="listitem">
You have extremely useful new containers like <code class="computeroutput"><span class="special">[</span><span class="identifier">stable</span><span class="special">/</span><span class="keyword">static</span><span class="special">/</span><span class="identifier">small</span><span class="special">]</span><span class="identifier">_vector</span></code> and <code class="computeroutput"><span class="identifier">flat_</span><span class="special">[</span><span class="identifier">multi</span><span class="special">]</span><span class="identifier">set</span><span class="special">/</span><span class="identifier">map</span></code>.
</li>
<li class="listitem">
If you work on multiple platforms, you'll have a portable behaviour without
depending on the std-lib implementation conformance of each platform.
Some examples:
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
Default constructors don't allocate memory at all, which improves
performance and usually implies a no-throw guarantee (if predicate's
or allocator's default constructor doesn't throw).
</li>
<li class="listitem">
Small string optimization for <code class="computeroutput"><a class="link" href="../boost/container/basic_string.html" title="Class template basic_string">basic_string</a></code>.
</li>
</ul></div>
</li>
<li class="listitem">
<a class="link" href="extended_functionality.html" title="Extended functionality: Basic extensions">Extended functionality</a>
beyond the standard based on user feedback to improve code performance.
</li>
<li class="listitem">
You need a portable implementation that works when compiling without
exceptions support or you need to customize the error handling when a
container needs to signal an exceptional error.
</li>
</ul></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="known_issues.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="index.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Known Issues</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="cpp_conformance.html" title="C++11/C++14/C++17 Conformance">
<link rel="next" href="history_and_reasons.html" title="History and reasons to use Boost.Container">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp_conformance.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="history_and_reasons.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.known_issues"></a><a class="link" href="known_issues.html" title="Known Issues">Known Issues</a>
</h2></div></div></div>
<div class="toc"><dl class="toc"><dt><span class="section"><a href="known_issues.html#container.known_issues.move_emulation_limitations">Move
emulation limitations in C++03 compilers</a></span></dt></dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.known_issues.move_emulation_limitations"></a><a class="link" href="known_issues.html#container.known_issues.move_emulation_limitations" title="Move emulation limitations in C++03 compilers">Move
emulation limitations in C++03 compilers</a>
</h3></div></div></div>
<p>
<span class="bold"><strong>Boost.Container</strong></span> uses <span class="bold"><strong>Boost.Move</strong></span>
to implement move semantics both in C++03 and C++11 compilers. However, as
explained in <a href="http://www.boost.org/doc/libs/release/doc/html/move/emulation_limitations.html" target="_top">Emulation
limitations</a>, there are some limitations in C++03 compilers that might
surprise <span class="bold"><strong>Boost.Container</strong></span> users.
</p>
<p>
The most noticeable problem is when <span class="bold"><strong>Boost.Container</strong></span>
containers are placed in a struct with a compiler-generated assignment operator:
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">holder</span>
<span class="special">{</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">MyType</span><span class="special">&gt;</span> <span class="identifier">vect</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">void</span> <span class="identifier">func</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">holder</span><span class="special">&amp;</span> <span class="identifier">h</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">holder</span> <span class="identifier">copy_h</span><span class="special">(</span><span class="identifier">h</span><span class="special">);</span> <span class="comment">//&lt;--- ERROR: can't convert 'const holder&amp;' to 'holder&amp;'</span>
<span class="comment">//Compiler-generated copy constructor is non-const:</span>
<span class="comment">// holder&amp; operator(holder &amp;)</span>
<span class="comment">//!!!</span>
<span class="special">}</span>
</pre>
<p>
This limitation forces the user to define a const version of the copy assignment,
in all classes holding containers, which might be annoying in some cases.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="cpp_conformance.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="history_and_reasons.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,510 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Main features</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="next" href="exception_handling.html" title="Boost.Container and C++ exceptions">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../container.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception_handling.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.main_features"></a><a class="link" href="main_features.html" title="Main features">Main features</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="main_features.html#container.main_features.move_emplace">Efficient insertion</a></span></dt>
<dt><span class="section"><a href="main_features.html#container.main_features.containers_of_incomplete_types">Containers
of Incomplete Types</a></span></dt>
<dt><span class="section"><a href="main_features.html#container.main_features.scary_iterators">SCARY iterators</a></span></dt>
<dt><span class="section"><a href="main_features.html#container.main_features.other_features">Other features</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.main_features.move_emplace"></a><a class="link" href="main_features.html#container.main_features.move_emplace" title="Efficient insertion">Efficient insertion</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="main_features.html#container.main_features.move_emplace.move_containers">Move-aware
containers</a></span></dt>
<dt><span class="section"><a href="main_features.html#container.main_features.move_emplace.emplace">Emplace:
Placement insertion</a></span></dt>
</dl></div>
<p>
Move semantics and placement insertion are two features brought by C++11
containers that can have a very positive impact in your C++ applications.
Boost.Container implements both techniques both for C++11 and C++03 compilers.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="container.main_features.move_emplace.move_containers"></a><a class="link" href="main_features.html#container.main_features.move_emplace.move_containers" title="Move-aware containers">Move-aware
containers</a>
</h4></div></div></div>
<p>
All containers offered by <span class="bold"><strong>Boost.Container</strong></span>
can store movable-only types and actual requirements for <code class="computeroutput"><span class="identifier">value_type</span></code> depend on each container operations.
Following C++11 requirements even for C++03 compilers, many operations
now require movable or default constructible types instead of just copy
constructible types.
</p>
<p>
Containers themselves are also movable, with no-throw guarantee if allocator
or predicate (if present) copy operations are no-throw. This allows high
performance operations when transferring data between vectors. Let's see
an example:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">move</span><span class="special">/</span><span class="identifier">utility_core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="comment">//Non-copyable class</span>
<span class="keyword">class</span> <span class="identifier">non_copyable</span>
<span class="special">{</span>
<span class="identifier">BOOST_MOVABLE_BUT_NOT_COPYABLE</span><span class="special">(</span><span class="identifier">non_copyable</span><span class="special">)</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">non_copyable</span><span class="special">(){}</span>
<span class="identifier">non_copyable</span><span class="special">(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">non_copyable</span><span class="special">))</span> <span class="special">{}</span>
<span class="identifier">non_copyable</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="identifier">BOOST_RV_REF</span><span class="special">(</span><span class="identifier">non_copyable</span><span class="special">))</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span>
<span class="special">};</span>
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//Store non-copyable objects in a vector</span>
<span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">non_copyable</span><span class="special">&gt;</span> <span class="identifier">v</span><span class="special">;</span>
<span class="identifier">non_copyable</span> <span class="identifier">nc</span><span class="special">;</span>
<span class="identifier">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">nc</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="comment">//Reserve no longer needs copy-constructible</span>
<span class="identifier">v</span><span class="special">.</span><span class="identifier">reserve</span><span class="special">(</span><span class="number">100</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">&gt;=</span> <span class="number">100</span><span class="special">);</span>
<span class="comment">//This resize overload only needs movable and default constructible</span>
<span class="identifier">v</span><span class="special">.</span><span class="identifier">resize</span><span class="special">(</span><span class="number">200</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">200</span><span class="special">);</span>
<span class="comment">//Containers are also movable</span>
<span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">non_copyable</span><span class="special">&gt;</span> <span class="identifier">v_other</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">v</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">v_other</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">200</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">empty</span><span class="special">());</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="container.main_features.move_emplace.emplace"></a><a class="link" href="main_features.html#container.main_features.move_emplace.emplace" title="Emplace: Placement insertion">Emplace:
Placement insertion</a>
</h4></div></div></div>
<p>
All containers offered by <span class="bold"><strong>Boost.Container</strong></span>
implement placement insertion, which means that objects can be built directly
into the container from user arguments without creating any temporary object.
For compilers without variadic templates support placement insertion is
emulated up to a finite (10) number of arguments.
</p>
<p>
Expensive to move types are perfect candidates emplace functions and in
case of node containers (<code class="computeroutput"><a class="link" href="../boost/container/list.html" title="Class template list">list</a></code>,
<code class="computeroutput"><a class="link" href="../boost/container/set.html" title="Class template set">set</a></code>, ...) emplace allows
storing non-movable and non-copyable types in containers! Let's see an
example:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="comment">//Non-copyable and non-movable class</span>
<span class="keyword">class</span> <span class="identifier">non_copy_movable</span>
<span class="special">{</span>
<span class="identifier">non_copy_movable</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">non_copy_movable</span> <span class="special">&amp;);</span>
<span class="identifier">non_copy_movable</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">non_copy_movable</span> <span class="special">&amp;);</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">non_copy_movable</span><span class="special">(</span><span class="keyword">int</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
<span class="special">};</span>
<span class="keyword">int</span> <span class="identifier">main</span> <span class="special">()</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="comment">//Store non-copyable and non-movable objects in a list</span>
<span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">non_copy_movable</span><span class="special">&gt;</span> <span class="identifier">l</span><span class="special">;</span>
<span class="identifier">non_copy_movable</span> <span class="identifier">ncm</span><span class="special">;</span>
<span class="comment">//A new element will be built calling non_copy_movable(int) constructor</span>
<span class="identifier">l</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="identifier">l</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="number">0</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">l</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="comment">//A new element will be value initialized</span>
<span class="identifier">l</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="identifier">l</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">l</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">2</span><span class="special">);</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.main_features.containers_of_incomplete_types"></a><a class="link" href="main_features.html#container.main_features.containers_of_incomplete_types" title="Containers of Incomplete Types">Containers
of Incomplete Types</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="main_features.html#container.main_features.containers_of_incomplete_types.recursive_containers">Recursive
containers</a></span></dt>
<dt><span class="section"><a href="main_features.html#container.main_features.containers_of_incomplete_types.type_erasure">Type
Erasure</a></span></dt>
</dl></div>
<p>
Incomplete types allow <a href="http://en.wikipedia.org/wiki/Type_erasure" target="_top"><span class="bold"><strong>type erasure </strong></span></a> and <a href="http://en.wikipedia.org/wiki/Recursive_data_type" target="_top"><span class="bold"><strong>recursive data types</strong></span></a>, and C and C++ programmers
have been using it for years to build complex data structures, like tree
structures where a node may have an arbitrary number of children.
</p>
<p>
What about standard containers? Containers of incomplete types have been
under discussion for a long time, as explained in Matt Austern's great article
(<a href="http://drdobbs.com/184403814" target="_top"><span class="bold"><strong>The Standard
Librarian: Containers of Incomplete Types</strong></span></a>):
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>Unlike most of my columns, this one is about something you
can't do with the C++ Standard library: put incomplete types in one of the
standard containers. This column explains why you might want to do this,
why the standardization committee banned it even though they knew it was
useful, and what you might be able to do to get around the restriction.</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>In 1997, shortly before the C++ Standard was completed,
the standardization committee received a query: Is it possible to create
standard containers with incomplete types? It took a while for the committee
to understand the question. What would such a thing even mean, and why on
earth would you ever want to do it? The committee eventually worked it out
and came up with an answer to the question. (Just so you don't have to skip
ahead to the end, the answer is "no.") But the question is much
more interesting than the answer: it points to a useful, and insufficiently
discussed, programming technique. The standard library doesn't directly support
that technique, but the two can be made to coexist.</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>In a future revision of C++, it might make sense to relax
the restriction on instantiating standard library templates with incomplete
types. Clearly, the general prohibition should stay in place - instantiating
templates with incomplete types is a delicate business, and there are too
many classes in the standard library where it would make no sense. But perhaps
it should be relaxed on a case-by-case basis, and <code class="computeroutput"><span class="identifier">vector</span></code>
looks like a good candidate for such special-case treatment: it's the one
standard container class where there are good reasons to instantiate it with
an incomplete type and where Standard Library implementors want to make it
work. As of today, in fact, implementors would have to go out of their way
to prohibit it!</em></span></span></span>
</p>
<p>
C++11 standard is also cautious about incomplete types and STL: <span class="quote"><span class="quote"><span class="emphasis"><em>17.6.4.8
Other functions (...) 2. the effects are undefined in the following cases:
(...) In particular - if an incomplete type (3.9) is used as a template argument
when instantiating a template component, unless specifically allowed for
that component</em></span></span></span>.
</p>
<p>
Finally C++17 added support for incomplete types in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>,
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_list</span></code>
(see <a href="https://wg21.link/n4510" target="_top"><span class="emphasis"><em>N4510: Minimal incomplete
type support for standard containers, revision 4</em></span></a> for details),
but no other containers like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">set</span><span class="special">/</span><span class="identifier">map</span><span class="special">/</span><span class="identifier">unordered_set</span><span class="special">/</span><span class="identifier">unordered_map</span></code>,
</p>
<p>
Fortunately all <span class="bold"><strong>Boost.Container</strong></span> containers
except <code class="computeroutput"><a class="link" href="../boost/container/static_vector.html" title="Class template static_vector">static_vector</a></code>
and <code class="computeroutput"><a class="link" href="../boost/container/small_vector.html" title="Class template small_vector">small_vector</a></code>
and <code class="computeroutput"><a class="link" href="../boost/container/basic_string.html" title="Class template basic_string">basic_string</a></code>
are designed to support incomplete types. <code class="computeroutput"><a class="link" href="../boost/container/static_vector.html" title="Class template static_vector">static_vector</a></code>
and <code class="computeroutput"><a class="link" href="../boost/container/small_vector.html" title="Class template small_vector">small_vector</a></code>
are special because they statically allocates memory for <code class="computeroutput"><span class="identifier">value_type</span></code>
and this requires complete types. <code class="computeroutput"><a class="link" href="../boost/container/basic_string.html" title="Class template basic_string">basic_string</a></code>
implements Small String Optimization which also requires complete types.
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> containers supporting incomplete
types also support instantiating iterators to those incomplete elements.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="container.main_features.containers_of_incomplete_types.recursive_containers"></a><a class="link" href="main_features.html#container.main_features.containers_of_incomplete_types.recursive_containers" title="Recursive containers">Recursive
containers</a>
</h4></div></div></div>
<p>
Most <span class="bold"><strong>Boost.Container</strong></span> containers can be
used to define recursive containers:
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">stable_vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">deque</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">map</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">;</span>
<span class="keyword">struct</span> <span class="identifier">data</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">i_</span><span class="special">;</span>
<span class="comment">//A vector holding still undefined class 'data'</span>
<span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;</span> <span class="identifier">v_</span><span class="special">;</span>
<span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">vi_</span><span class="special">;</span>
<span class="comment">//A stable_vector holding still undefined class 'data'</span>
<span class="identifier">stable_vector</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;</span> <span class="identifier">sv_</span><span class="special">;</span>
<span class="identifier">stable_vector</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">svi_</span><span class="special">;</span>
<span class="comment">//A stable_vector holding still undefined class 'data'</span>
<span class="identifier">deque</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;</span> <span class="identifier">d_</span><span class="special">;</span>
<span class="identifier">deque</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">di_</span><span class="special">;</span>
<span class="comment">//A list holding still undefined 'data'</span>
<span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;</span> <span class="identifier">l_</span><span class="special">;</span>
<span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">li_</span><span class="special">;</span>
<span class="comment">//A map holding still undefined 'data'</span>
<span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">data</span><span class="special">&gt;</span> <span class="identifier">m_</span><span class="special">;</span>
<span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">,</span> <span class="identifier">data</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">mi_</span><span class="special">;</span>
<span class="keyword">friend</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;(</span><span class="keyword">const</span> <span class="identifier">data</span> <span class="special">&amp;</span><span class="identifier">l</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">data</span> <span class="special">&amp;</span><span class="identifier">r</span><span class="special">)</span>
<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">l</span><span class="special">.</span><span class="identifier">i_</span> <span class="special">&lt;</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">i_</span><span class="special">;</span> <span class="special">}</span>
<span class="special">};</span>
<span class="keyword">struct</span> <span class="identifier">tree_node</span>
<span class="special">{</span>
<span class="identifier">string</span> <span class="identifier">name</span><span class="special">;</span>
<span class="identifier">string</span> <span class="identifier">value</span><span class="special">;</span>
<span class="comment">//children nodes of this node</span>
<span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">tree_node</span><span class="special">&gt;</span> <span class="identifier">children_</span><span class="special">;</span>
<span class="identifier">list</span><span class="special">&lt;</span><span class="identifier">tree_node</span><span class="special">&gt;::</span><span class="identifier">iterator</span> <span class="identifier">selected_child_</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">//a container holding a recursive data type</span>
<span class="identifier">stable_vector</span><span class="special">&lt;</span><span class="identifier">data</span><span class="special">&gt;</span> <span class="identifier">sv</span><span class="special">;</span>
<span class="identifier">sv</span><span class="special">.</span><span class="identifier">resize</span><span class="special">(</span><span class="number">100</span><span class="special">);</span>
<span class="comment">//Let's build a tree based in</span>
<span class="comment">//a recursive data type</span>
<span class="identifier">tree_node</span> <span class="identifier">root</span><span class="special">;</span>
<span class="identifier">root</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">"root"</span><span class="special">;</span>
<span class="identifier">root</span><span class="special">.</span><span class="identifier">value</span> <span class="special">=</span> <span class="string">"root_value"</span><span class="special">;</span>
<span class="identifier">root</span><span class="special">.</span><span class="identifier">children_</span><span class="special">.</span><span class="identifier">resize</span><span class="special">(</span><span class="number">7</span><span class="special">);</span>
<span class="identifier">root</span><span class="special">.</span><span class="identifier">selected_child_</span> <span class="special">=</span> <span class="identifier">root</span><span class="special">.</span><span class="identifier">children_</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="container.main_features.containers_of_incomplete_types.type_erasure"></a><a class="link" href="main_features.html#container.main_features.containers_of_incomplete_types.type_erasure" title="Type Erasure">Type
Erasure</a>
</h4></div></div></div>
<p>
Containers of incomplete types are useful to break header file dependencies
and improve compilation types. With Boost.Container, you can write a header
file defining a class with containers of incomplete types as data members,
if you carefully put all the implementation details that require knowing
the size of the <code class="computeroutput"><span class="identifier">value_type</span></code>
in your implementation file:
</p>
<p>
In this header file we define a class (<code class="computeroutput"><span class="identifier">MyClassHolder</span><span class="special">)</span></code> that holds a <code class="computeroutput"><span class="identifier">vector</span></code>
of an incomplete type (<code class="computeroutput"><span class="identifier">MyClass</span></code>)
that it's only forward declared.
</p>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">container</span><span class="special">/</span><span class="identifier">vector</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="comment">//MyClassHolder.h</span>
<span class="comment">//We don't need to include "MyClass.h"</span>
<span class="comment">//to store vector&lt;MyClass&gt;</span>
<span class="keyword">class</span> <span class="identifier">MyClass</span><span class="special">;</span>
<span class="keyword">class</span> <span class="identifier">MyClassHolder</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">void</span> <span class="identifier">AddNewObject</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span><span class="identifier">o</span><span class="special">);</span>
<span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span> <span class="identifier">GetLastObject</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="special">::</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">container</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">MyClass</span><span class="special">&gt;</span> <span class="identifier">vector_</span><span class="special">;</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
Then we can define <code class="computeroutput"><span class="identifier">MyClass</span></code>
in its own header file.
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">//MyClass.h</span>
<span class="keyword">class</span> <span class="identifier">MyClass</span>
<span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">int</span> <span class="identifier">value_</span><span class="special">;</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">MyClass</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">val</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">value_</span><span class="special">(</span><span class="identifier">val</span><span class="special">){}</span>
<span class="keyword">friend</span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span><span class="identifier">l</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span><span class="identifier">r</span><span class="special">)</span>
<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">l</span><span class="special">.</span><span class="identifier">value_</span> <span class="special">==</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">value_</span><span class="special">;</span> <span class="special">}</span>
<span class="comment">//...</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
And include it only in the implementation file of <code class="computeroutput"><span class="identifier">MyClassHolder</span></code>
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">//MyClassHolder.cpp</span>
<span class="preprocessor">#include</span> <span class="string">"MyClassHolder.h"</span>
<span class="comment">//In the implementation MyClass must be a complete</span>
<span class="comment">//type so we include the appropriate header</span>
<span class="preprocessor">#include</span> <span class="string">"MyClass.h"</span>
<span class="keyword">void</span> <span class="identifier">MyClassHolder</span><span class="special">::</span><span class="identifier">AddNewObject</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span><span class="identifier">o</span><span class="special">)</span>
<span class="special">{</span> <span class="identifier">vector_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">o</span><span class="special">);</span> <span class="special">}</span>
<span class="keyword">const</span> <span class="identifier">MyClass</span> <span class="special">&amp;</span> <span class="identifier">MyClassHolder</span><span class="special">::</span><span class="identifier">GetLastObject</span><span class="special">()</span> <span class="keyword">const</span>
<span class="special">{</span> <span class="keyword">return</span> <span class="identifier">vector_</span><span class="special">.</span><span class="identifier">back</span><span class="special">();</span> <span class="special">}</span>
</pre>
<p>
</p>
<p>
Finally, we can just compile, link, and run!
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">//Main.cpp</span>
<span class="preprocessor">#include</span> <span class="string">"MyClassHolder.h"</span>
<span class="preprocessor">#include</span> <span class="string">"MyClass.h"</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">MyClass</span> <span class="identifier">mc</span><span class="special">(</span><span class="number">7</span><span class="special">);</span>
<span class="identifier">MyClassHolder</span> <span class="identifier">myclassholder</span><span class="special">;</span>
<span class="identifier">myclassholder</span><span class="special">.</span><span class="identifier">AddNewObject</span><span class="special">(</span><span class="identifier">mc</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">myclassholder</span><span class="special">.</span><span class="identifier">GetLastObject</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">mc</span> <span class="special">?</span> <span class="number">0</span> <span class="special">:</span> <span class="number">1</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.main_features.scary_iterators"></a><a class="link" href="main_features.html#container.main_features.scary_iterators" title="SCARY iterators">SCARY iterators</a>
</h3></div></div></div>
<p>
The paper N2913, titled <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2913.pdf" target="_top">SCARY
Iterator Assignment and Initialization</a>, proposed a requirement that
a standard container's iterator types have no dependency on any type argument
apart from the container's <code class="computeroutput"><span class="identifier">value_type</span></code>,
<code class="computeroutput"><span class="identifier">difference_type</span></code>, <code class="computeroutput"><span class="identifier">pointer</span> <span class="identifier">type</span></code>,
and <code class="computeroutput"><span class="identifier">const_pointer</span></code> type. In
particular, according to the proposal, the types of a standard container's
iterators should not depend on the container's <code class="computeroutput"><span class="identifier">key_compare</span></code>,
<code class="computeroutput"><span class="identifier">hasher</span></code>, <code class="computeroutput"><span class="identifier">key_equal</span></code>,
or <code class="computeroutput"><span class="identifier">allocator</span></code> types.
</p>
<p>
That paper demonstrated that SCARY operations were crucial to the performant
implementation of common design patterns using STL components. It showed
that implementations that support SCARY operations reduce object code bloat
by eliminating redundant specializations of iterator and algorithm templates.
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> containers implement SCARY
iterators so the iterator type of a container is only dependent on the <code class="computeroutput"><span class="identifier">allocator_traits</span><span class="special">&lt;</span><span class="identifier">allocator_type</span><span class="special">&gt;::</span><span class="identifier">pointer</span></code> type (the pointer type of the
<code class="computeroutput"><span class="identifier">value_type</span></code> to be inserted
in the container). Reference types and all other typedefs are deduced from
the pointer type using the C++11 <code class="computeroutput"><span class="identifier">pointer_traits</span></code>
utility. This leads to lower code bloat in algorithms and classes templated
on iterators.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.main_features.other_features"></a><a class="link" href="main_features.html#container.main_features.other_features" title="Other features">Other features</a>
</h3></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Default constructors don't allocate memory which improves performance
and usually implies a no-throw guarantee (if predicate's or allocator's
default constructor doesn't throw).
</li>
<li class="listitem">
Small string optimization for <code class="computeroutput"><a class="link" href="../boost/container/basic_string.html" title="Class template basic_string">basic_string</a></code>,
with an internal buffer of 11/23 bytes (32/64 bit systems) <span class="bold"><strong>without</strong></span> increasing the usual <code class="computeroutput"><span class="keyword">sizeof</span></code>
of the string (3 words).
</li>
<li class="listitem">
<code class="computeroutput"><span class="special">[</span><span class="identifier">multi</span><span class="special">]</span><span class="identifier">set</span><span class="special">/</span><span class="identifier">map</span></code>
containers are size optimized embedding the color bit of the red-black
tree nodes in the parent pointer.
</li>
<li class="listitem">
<code class="computeroutput"><span class="special">[</span><span class="identifier">multi</span><span class="special">]</span><span class="identifier">set</span><span class="special">/</span><span class="identifier">map</span></code>
containers use no recursive functions so stack problems are avoided.
</li>
</ul></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../container.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception_handling.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,534 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Non-standard containers</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../container.html" title="Chapter 9. Boost.Container">
<link rel="prev" href="exception_handling.html" title="Boost.Container and C++ exceptions">
<link rel="next" href="extended_functionality.html" title="Extended functionality: Basic extensions">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="exception_handling.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="extended_functionality.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="container.non_standard_containers"></a><a class="link" href="non_standard_containers.html" title="Non-standard containers">Non-standard containers</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="non_standard_containers.html#container.non_standard_containers.stable_vector"><span class="emphasis"><em>stable_vector</em></span></a></span></dt>
<dt><span class="section"><a href="non_standard_containers.html#container.non_standard_containers.flat_xxx"><span class="emphasis"><em>flat_(multi)map/set</em></span>
associative containers</a></span></dt>
<dt><span class="section"><a href="non_standard_containers.html#container.non_standard_containers.devector"><span class="emphasis"><em>devector</em></span></a></span></dt>
<dt><span class="section"><a href="non_standard_containers.html#container.non_standard_containers.slist"><span class="emphasis"><em>slist</em></span></a></span></dt>
<dt><span class="section"><a href="non_standard_containers.html#container.non_standard_containers.static_vector"><span class="emphasis"><em>static_vector</em></span></a></span></dt>
<dt><span class="section"><a href="non_standard_containers.html#container.non_standard_containers.small_vector"><span class="emphasis"><em>small_vector</em></span></a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.non_standard_containers.stable_vector"></a><a class="link" href="non_standard_containers.html#container.non_standard_containers.stable_vector" title="stable_vector"><span class="emphasis"><em>stable_vector</em></span></a>
</h3></div></div></div>
<p>
This useful, fully STL-compliant stable container <a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" target="_top">designed
by Joaquín M. López Muñoz</a> is an hybrid between <code class="computeroutput"><span class="identifier">vector</span></code> and <code class="computeroutput"><span class="identifier">list</span></code>,
providing most of the features of <code class="computeroutput"><span class="identifier">vector</span></code>
except <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#69" target="_top">element
contiguity</a>.
</p>
<p>
Extremely convenient as they are, <code class="computeroutput"><span class="identifier">vector</span></code>s
have a limitation that many novice C++ programmers frequently stumble upon:
iterators and references to an element of an <code class="computeroutput"><span class="identifier">vector</span></code>
are invalidated when a preceding element is erased or when the vector expands
and needs to migrate its internal storage to a wider memory region (i.e.
when the required size exceeds the vector's capacity). We say then that
<code class="computeroutput"><span class="identifier">vector</span></code>s are unstable: by
contrast, stable containers are those for which references and iterators
to a given element remain valid as long as the element is not erased: examples
of stable containers within the C++ standard library are <code class="computeroutput"><span class="identifier">list</span></code>
and the standard associative containers (<code class="computeroutput"><span class="identifier">set</span></code>,
<code class="computeroutput"><span class="identifier">map</span></code>, etc.).
</p>
<p>
Sometimes stability is too precious a feature to live without, but one particular
property of <code class="computeroutput"><span class="identifier">vector</span></code>s, element
contiguity, makes it impossible to add stability to this container. So, provided
we sacrifice element contiguity, how much can a stable design approach the
behavior of <code class="computeroutput"><span class="identifier">vector</span></code> (random
access iterators, amortized constant time end insertion/deletion, minimal
memory overhead, etc.)? The following image describes the layout of a possible
data structure upon which to base the design of a stable vector:
</p>
<p>
<span class="inlinemediaobject"><img src="../../../libs/container/doc/images/stable_vector.png" align="middle" width="50%" alt="stable_vector"></span>
</p>
<p>
Each element is stored in its own separate node. All the nodes are referenced
from a contiguous array of pointers, but also every node contains an "up"
pointer referring back to the associated array cell. This up pointer is the
key element to implementing stability and random accessibility:
</p>
<p>
Iterators point to the nodes rather than to the pointer array. This ensures
stability, as it is only the pointer array that needs to be shifted or relocated
upon insertion or deletion. Random access operations can be implemented by
using the pointer array as a convenient intermediate zone. For instance,
if the iterator it holds a node pointer <code class="computeroutput"><span class="identifier">it</span><span class="special">.</span><span class="identifier">p</span></code> and
we want to advance it by n positions, we simply do:
</p>
<pre class="programlisting"><span class="identifier">it</span><span class="special">.</span><span class="identifier">p</span> <span class="special">=</span> <span class="special">*(</span><span class="identifier">it</span><span class="special">.</span><span class="identifier">p</span><span class="special">-&gt;</span><span class="identifier">up</span><span class="special">+</span><span class="identifier">n</span><span class="special">);</span>
</pre>
<p>
That is, we go "up" to the pointer array, add n there and then
go "down" to the resulting node.
</p>
<p>
<span class="bold"><strong>General properties</strong></span>. <code class="computeroutput"><span class="identifier">stable_vector</span></code>
satisfies all the requirements of a container, a reversible container and
a sequence and provides all the optional operations present in vector. Like
vector, iterators are random access. <code class="computeroutput"><span class="identifier">stable_vector</span></code>
does not provide element contiguity; in exchange for this absence, the container
is stable, i.e. references and iterators to an element of a <code class="computeroutput"><span class="identifier">stable_vector</span></code> remain valid as long as the
element is not erased, and an iterator that has been assigned the return
value of end() always remain valid until the destruction of the associated
<code class="computeroutput"><span class="identifier">stable_vector</span></code>.
</p>
<p>
<span class="bold"><strong>Operation complexity</strong></span>. The big-O complexities
of <code class="computeroutput"><span class="identifier">stable_vector</span></code> operations
match exactly those of vector. In general, insertion/deletion is constant
time at the end of the sequence and linear elsewhere. Unlike vector, <code class="computeroutput"><span class="identifier">stable_vector</span></code> does not internally perform
any value_type destruction, copy/move construction/assignment operations
other than those exactly corresponding to the insertion of new elements or
deletion of stored elements, which can sometimes compensate in terms of performance
for the extra burden of doing more pointer manipulation and an additional
allocation per element.
</p>
<p>
<span class="bold"><strong>Exception safety</strong></span>. (according to <a href="http://www.boost.org/community/exception_safety.html" target="_top">Abrahams'
terminology</a>) As <code class="computeroutput"><span class="identifier">stable_vector</span></code>
does not internally copy/move elements around, some operations provide stronger
exception safety guarantees than in vector:
</p>
<div class="table">
<a name="container.non_standard_containers.stable_vector.stable_vector_req"></a><p class="title"><b>Table 9.1. Exception safety</b></p>
<div class="table-contents"><table class="table" summary="Exception safety">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
operation
</p>
</th>
<th>
<p>
exception safety for <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
</p>
</th>
<th>
<p>
exception safety for <code class="computeroutput"><span class="identifier">stable_vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
insert
</p>
</td>
<td>
<p>
strong unless copy/move construction/assignment of <code class="computeroutput"><span class="identifier">T</span></code> throw (basic)
</p>
</td>
<td>
<p>
strong
</p>
</td>
</tr>
<tr>
<td>
<p>
erase
</p>
</td>
<td>
<p>
no-throw unless copy/move construction/assignment of <code class="computeroutput"><span class="identifier">T</span></code> throw (basic)
</p>
</td>
<td>
<p>
no-throw
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><p>
<span class="bold"><strong>Memory overhead</strong></span>. The C++ standard does not
specify requirements on memory consumption, but virtually any implementation
of <code class="computeroutput"><span class="identifier">vector</span></code> has the same behavior
with respect to memory usage: the memory allocated by a <code class="computeroutput"><span class="identifier">vector</span></code>
v with n elements of type T is
</p>
<p>
m<sub>v</sub> = c∙e,
</p>
<p>
where c is <code class="computeroutput"><span class="identifier">v</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">()</span></code>
and e is <code class="computeroutput"><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code>. c can
be as low as n if the user has explicitly reserved the exact capacity required;
otherwise, the average value c for a growing <code class="computeroutput"><span class="identifier">vector</span></code>
oscillates between 1.25∙n and 1.5∙n for typical resizing policies.
For <code class="computeroutput"><span class="identifier">stable_vector</span></code>, the memory
usage is
</p>
<p>
m<sub>sv</sub> = (c + 1)p + (n + 1)(e + p),
</p>
<p>
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 the sequence. If we call f
the capacity to size ratio c/n and assume that n is large enough, we have
that
</p>
<p>
m<sub>sv</sub>/m<sub>v</sub> ≃ (fp + e + p)/fe.
</p>
<p>
So, <code class="computeroutput"><span class="identifier">stable_vector</span></code> uses less
memory than <code class="computeroutput"><span class="identifier">vector</span></code> only when
e &gt; p and the capacity to size ratio exceeds a given threshold:
</p>
<p>
m<sub>sv</sub> &lt; m<sub>v</sub> &lt;-&gt; f &gt; (e + p)/(e - p). (provided e &gt; p)
</p>
<p>
This threshold approaches typical values of f below 1.5 when e &gt; 5p; in
a 32-bit architecture, when e &gt; 20 bytes.
</p>
<p>
<span class="bold"><strong>Summary</strong></span>. <code class="computeroutput"><span class="identifier">stable_vector</span></code>
is a drop-in replacement for <code class="computeroutput"><span class="identifier">vector</span></code>
providing stability of references and iterators, in exchange for missing
element contiguity and also some performance and memory overhead. When the
element objects are expensive to move around, the performance overhead can
turn into a net performance gain for <code class="computeroutput"><span class="identifier">stable_vector</span></code>
if many middle insertions or deletions are performed or if resizing is very
frequent. Similarly, if the elements are large there are situations when
the memory used by <code class="computeroutput"><span class="identifier">stable_vector</span></code>
can actually be less than required by vector.
</p>
<p>
<span class="emphasis"><em>Note: Text and explanations taken from <a href="http://bannalia.blogspot.com/2008/09/introducing-stablevector.html" target="_top">Joaquín's
blog</a></em></span>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.non_standard_containers.flat_xxx"></a><a class="link" href="non_standard_containers.html#container.non_standard_containers.flat_xxx" title="flat_(multi)map/set associative containers"><span class="emphasis"><em>flat_(multi)map/set</em></span>
associative containers</a>
</h3></div></div></div>
<p>
Using sorted vectors instead of tree-based associative containers is a well-known
technique in C++ world. Matt Austern's classic article <a href="http://lafstern.org/matt/col1.pdf" target="_top">Why
You Shouldn't Use set, and What You Should Use Instead</a> (C++ Report
12:4, April 2000) was enlightening:
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>Red-black trees aren't the only way to organize data that
permits lookup in logarithmic time. One of the basic algorithms of computer
science is binary search, which works by successively dividing a range in
half. Binary search is log N and it doesn't require any fancy data structures,
just a sorted collection of elements. (...) You can use whatever data structure
is convenient, so long as it provides STL iterator; usually it's easiest
to use a C array, or a vector.</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>Both std::lower_bound and set::find take time proportional
to log N, but the constants of proportionality are very different. Using
g++ (...) it takes X seconds to perform a million lookups in a sorted vector&lt;double&gt;
of a million elements, and almost twice as long (...) using a set. Moreover,
the set uses almost three times as much memory (48 million bytes) as the
vector (16.8 million).</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>Using a sorted vector instead of a set gives you faster
lookup and much faster iteration, but at the cost of slower insertion. Insertion
into a set, using set::insert, is proportional to log N, but insertion into
a sorted vector, (...) , is proportional to N. Whenever you insert something
into a vector, vector::insert has to make room by shifting all of the elements
that follow it. On average, if you're equally likely to insert a new element
anywhere, you'll be shifting N/2 elements.</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>It may sometimes be convenient to bundle all of this together
into a small container adaptor. This class does not satisfy the requirements
of a Standard Associative Container, since the complexity of insert is O(N)
rather than O(log N), but otherwise it is almost a drop-in replacement for
set.</em></span></span></span>
</p>
<p>
Following Matt Austern's indications, Andrei Alexandrescu's <a href="http://www.bestwebbuys.com/Modern-C-Design-Generic-Programming-and-Design-Patterns-Applied-ISBN-9780201704310?isrc=-rd" target="_top">Modern
C++ Design</a> showed <code class="computeroutput"><span class="identifier">AssocVector</span></code>,
a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> drop-in replacement designed in his
<a href="http://loki-lib.sourceforge.net/" target="_top">Loki</a> library:
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>It seems as if we're better off with a sorted vector. The
disadvantages of a sorted vector are linear-time insertions and linear-time
deletions (...). In exchange, a vector offers about twice the lookup speed
and a much smaller working set (...). Loki saves the trouble of maintaining
a sorted vector by hand by defining an AssocVector class template. AssocVector
is a drop-in replacement for std::map (it supports the same set of member
functions), implemented on top of std::vector. AssocVector differs from a
map in the behavior of its erase functions (AssocVector::erase invalidates
all iterators into the object) and in the complexity guarantees of insert
and erase (linear as opposed to constant). </em></span></span></span>
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> <code class="computeroutput"><span class="identifier">flat_</span><span class="special">[</span><span class="identifier">multi</span><span class="special">]</span><span class="identifier">map</span><span class="special">/</span><span class="identifier">set</span></code> containers are ordered, vector-like
container based, associative containers following Austern's and Alexandrescu's
guidelines. These ordered vector containers have also benefited with the
addition of <code class="computeroutput"><span class="identifier">move</span> <span class="identifier">semantics</span></code>
to C++11, speeding up insertion and erasure times considerably. Flat associative
containers have the following attributes:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Faster lookup than standard associative containers
</li>
<li class="listitem">
Much faster iteration than standard associative containers. Random-access
iterators instead of bidirectional iterators.
</li>
<li class="listitem">
Less memory consumption for small objects (and for big objects if <code class="computeroutput"><span class="identifier">shrink_to_fit</span></code> is used)
</li>
<li class="listitem">
Improved cache performance (data is stored in contiguous memory)
</li>
<li class="listitem">
Non-stable iterators (iterators are invalidated when inserting and erasing
elements)
</li>
<li class="listitem">
Non-copyable and non-movable values types can't be stored
</li>
<li class="listitem">
Weaker exception safety than standard associative containers (copy/move
constructors can throw when shifting values in erasures and insertions)
</li>
<li class="listitem">
Slower insertion and erasure than standard associative containers (specially
for non-movable types)
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.non_standard_containers.devector"></a><a class="link" href="non_standard_containers.html#container.non_standard_containers.devector" title="devector"><span class="emphasis"><em>devector</em></span></a>
</h3></div></div></div>
<p>
<code class="computeroutput"><span class="identifier">devector</span></code> is a hybrid of the
standard vector and deque containers originally written by Thaler Benedek.
It offers cheap (amortized constant time) insertion at both the front and
back ends, while also providing the regular features of <code class="computeroutput"><span class="identifier">vector</span></code>,
in particular the contiguous underlying memory.
</p>
<p>
Unlike <code class="computeroutput"><span class="identifier">vector</span></code>, devector can
have free capacity both before and after the elements. This enables efficient
implementation of methods that modify the devector at the front. In general,
<code class="computeroutput"><span class="identifier">devector</span></code>'s available methods
are a superset of those of <code class="computeroutput"><span class="identifier">vector</span></code>
with identical behaviour, barring a couple of iterator invalidation guarantees
that differ.
</p>
<p>
The overhead for devector is one extra <code class="computeroutput"><span class="identifier">size_t</span></code>
per container: Usually sizeof(devector) == 4*sizeof(T*).
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.non_standard_containers.slist"></a><a class="link" href="non_standard_containers.html#container.non_standard_containers.slist" title="slist"><span class="emphasis"><em>slist</em></span></a>
</h3></div></div></div>
<p>
When the standard template library was designed, it contained a singly linked
list called <code class="computeroutput"><span class="identifier">slist</span></code>. Unfortunately,
this container was not standardized and remained as an extension for many
standard library implementations until C++11 introduced <code class="computeroutput"><span class="identifier">forward_list</span></code>,
which is a bit different from the the original SGI <code class="computeroutput"><span class="identifier">slist</span></code>.
According to <a href="http://www.sgi.com/tech/stl/Slist.html" target="_top">SGI STL
documentation</a>:
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>An <code class="computeroutput"><span class="identifier">slist</span></code>
is a singly linked list: a list where each element is linked to the next
element, but not to the previous element. That is, it is a Sequence that
supports forward but not backward traversal, and (amortized) constant time
insertion and removal of elements. Slists, like lists, have the important
property that insertion and splicing do not invalidate iterators to list
elements, and that even removal invalidates only the iterators that point
to the elements that are removed. The ordering of iterators may be changed
(that is, slist&lt;T&gt;::iterator might have a different predecessor or
successor after a list operation than it did before), but the iterators themselves
will not be invalidated or made to point to different elements unless that
invalidation or mutation is explicit.</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>The main difference between <code class="computeroutput"><span class="identifier">slist</span></code>
and list is that list's iterators are bidirectional iterators, while slist's
iterators are forward iterators. This means that <code class="computeroutput"><span class="identifier">slist</span></code>
is less versatile than list; frequently, however, bidirectional iterators
are unnecessary. You should usually use <code class="computeroutput"><span class="identifier">slist</span></code>
unless you actually need the extra functionality of list, because singly
linked lists are smaller and faster than double linked lists.</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>Important performance note: like every other Sequence,
<code class="computeroutput"><span class="identifier">slist</span></code> defines the member
functions insert and erase. Using these member functions carelessly, however,
can result in disastrously slow programs. The problem is that insert's first
argument is an iterator pos, and that it inserts the new element(s) before
pos. This means that insert must find the iterator just before pos; this
is a constant-time operation for list, since list has bidirectional iterators,
but for <code class="computeroutput"><span class="identifier">slist</span></code> it must find
that iterator by traversing the list from the beginning up to pos. In other
words: insert and erase are slow operations anywhere but near the beginning
of the slist.</em></span></span></span>
</p>
<p>
<span class="quote"><span class="quote"><span class="emphasis"><em>Slist provides the member functions insert_after and erase_after,
which are constant time operations: you should always use insert_after and
erase_after whenever possible. If you find that insert_after and erase_after
aren't adequate for your needs, and that you often need to use insert and
erase in the middle of the list, then you should probably use list instead
of slist.</em></span></span></span>
</p>
<p>
<span class="bold"><strong>Boost.Container</strong></span> updates the classic <code class="computeroutput"><span class="identifier">slist</span></code> container with C++11 features like
move semantics and placement insertion and implements it a bit differently
than the standard C++ <code class="computeroutput"><span class="identifier">forward_list</span></code>.
<code class="computeroutput"><span class="identifier">forward_list</span></code> has no <code class="computeroutput"><span class="identifier">size</span><span class="special">()</span></code>
method, so it's been designed to allow (or in practice, encourage) implementations
without tracking list size with every insertion/erasure, allowing constant-time
<code class="computeroutput"><span class="identifier">splice_after</span><span class="special">(</span><span class="identifier">iterator</span><span class="special">,</span> <span class="identifier">forward_list</span> <span class="special">&amp;,</span>
<span class="identifier">iterator</span><span class="special">,</span>
<span class="identifier">iterator</span><span class="special">)</span></code>-based
list merging. On the other hand <code class="computeroutput"><span class="identifier">slist</span></code>
offers constant-time <code class="computeroutput"><span class="identifier">size</span><span class="special">()</span></code> for those that don't care about linear-time
<code class="computeroutput"><span class="identifier">splice_after</span><span class="special">(</span><span class="identifier">iterator</span><span class="special">,</span> <span class="identifier">slist</span> <span class="special">&amp;,</span>
<span class="identifier">iterator</span><span class="special">,</span>
<span class="identifier">iterator</span><span class="special">)</span></code>
<code class="computeroutput"><span class="identifier">size</span><span class="special">()</span></code>
and offers an additional <code class="computeroutput"><span class="identifier">splice_after</span><span class="special">(</span><span class="identifier">iterator</span><span class="special">,</span> <span class="identifier">slist</span> <span class="special">&amp;,</span> <span class="identifier">iterator</span><span class="special">,</span> <span class="identifier">iterator</span><span class="special">,</span> <span class="identifier">size_type</span><span class="special">)</span></code> method that can speed up <code class="computeroutput"><span class="identifier">slist</span></code>
merging when the programmer already knows the size. <code class="computeroutput"><span class="identifier">slist</span></code>
and <code class="computeroutput"><span class="identifier">forward_list</span></code> are therefore
complementary.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.non_standard_containers.static_vector"></a><a class="link" href="non_standard_containers.html#container.non_standard_containers.static_vector" title="static_vector"><span class="emphasis"><em>static_vector</em></span></a>
</h3></div></div></div>
<p>
<code class="computeroutput"><span class="identifier">static_vector</span></code> is an hybrid
between <code class="computeroutput"><span class="identifier">vector</span></code> and <code class="computeroutput"><span class="identifier">array</span></code>: like <code class="computeroutput"><span class="identifier">vector</span></code>,
it's a sequence container with contiguous storage that can change in size,
along with the static allocation, low overhead, and fixed capacity of <code class="computeroutput"><span class="identifier">array</span></code>. <code class="computeroutput"><span class="identifier">static_vector</span></code>
is based on Adam Wulkiewicz and Andrew Hundt's high-performance <a href="https://svn.boost.org/svn/boost/sandbox/varray/doc/html/index.html" target="_top">varray</a>
class.
</p>
<p>
The number of elements in a <code class="computeroutput"><span class="identifier">static_vector</span></code>
may vary dynamically up to a fixed capacity because elements are stored within
the object itself similarly to an array. However, objects are initialized
as they are inserted into <code class="computeroutput"><span class="identifier">static_vector</span></code>
unlike C arrays or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code> which must construct all elements
on instantiation. The behavior of <code class="computeroutput"><span class="identifier">static_vector</span></code>
enables the use of statically allocated elements in cases with complex object
lifetime requirements that would otherwise not be trivially possible. Some
other properties:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Random access to elements
</li>
<li class="listitem">
Constant time insertion and removal of elements at the end
</li>
<li class="listitem">
Linear time insertion and removal of elements at the beginning or in
the middle.
</li>
</ul></div>
<p>
<code class="computeroutput"><span class="identifier">static_vector</span></code> is well suited
for use in a buffer, the internal implementation of other classes, or use
cases where there is a fixed limit to the number of elements that must be
stored. Embedded and realtime applications where allocation either may not
be available or acceptable are a particular case where <code class="computeroutput"><span class="identifier">static_vector</span></code>
can be beneficial.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="container.non_standard_containers.small_vector"></a><a class="link" href="non_standard_containers.html#container.non_standard_containers.small_vector" title="small_vector"><span class="emphasis"><em>small_vector</em></span></a>
</h3></div></div></div>
<p>
<code class="computeroutput"><span class="identifier">small_vector</span></code> is a vector-like
container optimized for the case when it contains few elements. It contains
some preallocated elements in-place, which allows it to avoid the use of
dynamic storage allocation when the actual number of elements is below that
preallocated threshold. <code class="computeroutput"><span class="identifier">small_vector</span></code>
is inspired by <a href="http://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h" target="_top">LLVM's
<code class="computeroutput"><span class="identifier">SmallVector</span></code></a> container.
Unlike <code class="computeroutput"><span class="identifier">static_vector</span></code>, <code class="computeroutput"><span class="identifier">small_vector</span></code>'s capacity can grow beyond
the initial preallocated capacity.
</p>
<p>
<code class="computeroutput"><span class="identifier">small_vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">N</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">&gt;</span></code> is convertible to <code class="computeroutput"><span class="identifier">small_vector_base</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span>
<span class="identifier">Allocator</span><span class="special">&gt;</span></code>,
a type that is independent from the preallocated element count, allowing
client code that does not need to be templated on that N argument. <code class="computeroutput"><span class="identifier">small_vector</span></code> inherits all <code class="computeroutput"><span class="identifier">vector</span></code>'s member functions so it supports
all standard features like emplacement, stateful allocators, etc.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2009-2018 Ion Gaztanaga<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="exception_handling.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../container.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="extended_functionality.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff