681 lines
61 KiB
HTML
681 lines
61 KiB
HTML
<!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"><</span><span class="identifier">T</span><span class="special">></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"><</span><span class="keyword">bool</span><span class="special">></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"><</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">>::</span><span class="identifier">value</span></code> and <code class="computeroutput"><span class="identifier">is_constructible</span><span class="special"><</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">...>::</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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">>::</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"><</span><span class="keyword">double</span><span class="special">>::</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"><</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">></span>
|
||
<span class="preprocessor">#include</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">pmr</span><span class="special">/</span><span class="identifier">string</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></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"><</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">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<boost::container::pmr::string> m_strvec;</span>
|
||
<span class="keyword">public</span><span class="special">:</span>
|
||
|
||
<span class="comment">// This makes uses_allocator<ShoppingList, memory_resource*>::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">&</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">&</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"><</span><span class="identifier">cassert</span><span class="special">></span>
|
||
<span class="preprocessor">#include</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">pmr</span><span class="special">/</span><span class="identifier">list</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||
<span class="preprocessor">#include</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">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">></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">&)</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"><</span><span class="identifier">ShoppingList</span><span class="special">>::</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<ShoppingList> 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">(&</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">(&</span><span class="identifier">buf_rsrc</span><span class="special">);</span>
|
||
<span class="identifier">assert</span><span class="special">(&</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<T>"><code class="computeroutput"><span class="identifier">forward_list</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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<int> 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<int> 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<bool> specialization"><code class="computeroutput"><span class="identifier">vector</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span></code> specialization</a>
|
||
</h3></div></div></div>
|
||
<p>
|
||
<code class="computeroutput"><span class="identifier">vector</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></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"><</span><span class="keyword">bool</span><span class="special">></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"><</span><span class="keyword">bool</span><span class="special">></span></code></a>
|
||
</li>
|
||
<li class="listitem">
|
||
<a href="http://www.gotw.ca/publications/N1211.pdf" target="_top">vector<bool>:
|
||
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<bool></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<bool></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<bool> 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"><</span><span class="keyword">bool</span><span class="special">></span></code> is not a container and <code class="computeroutput"><span class="identifier">vector</span><span class="special"><</span><span class="keyword">bool</span><span class="special">>::</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"><</span><span class="keyword">bool</span><span class="special">></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<char> 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"><</span><span class="keyword">bool</span><span class="special">>::</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"><</span><span class="keyword">bool</span><span class="special">></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>
|