|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r56928 - sandbox/committee/rvalue_ref
From: dave_at_[hidden]
Date: 2009-10-16 14:19:56
Author: dave
Date: 2009-10-16 14:19:55 EDT (Fri, 16 Oct 2009)
New Revision: 56928
URL: http://svn.boost.org/trac/boost/changeset/56928
Log:
Polish
Text files modified:
sandbox/committee/rvalue_ref/N2983-throwing-move.rst | 16 ++++++
sandbox/committee/rvalue_ref/N2983.html | 82 ++++++++++++++++++++++++---------------
2 files changed, 64 insertions(+), 34 deletions(-)
Modified: sandbox/committee/rvalue_ref/N2983-throwing-move.rst
==============================================================================
--- sandbox/committee/rvalue_ref/N2983-throwing-move.rst (original)
+++ sandbox/committee/rvalue_ref/N2983-throwing-move.rst 2009-10-16 14:19:55 EDT (Fri, 16 Oct 2009)
@@ -22,6 +22,9 @@
(including N2855_ itself) have taken one basic approach: *ban throwing
move constructors, and be sure never to generate one*.
+Motivation
+**********
+
Consider, for a moment, the actual magnitude of the problem we're
addressing: it's a backward-compatibility/code evolution issue that
only arises when *all* these conditions are satisfied:
@@ -70,6 +73,9 @@
.. _N2904: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2904.pdf
+Solution
+********
+
Fortunately, there is a better way. Instead of imposing this burden
on every class author, we can deal with the issue more selectively in
the operation being move-enabled. There, we know whether a throwing
@@ -94,7 +100,7 @@
second( move(rhs.second) )
{}
-However, ``std::vector::reserve`` would be move-enabled this way:
+However, ``std::vector::reserve`` could be move-enabled this way: [#default-construct-swap]_
.. parsed-literal::
@@ -131,7 +137,7 @@
circumstances. In particular, it would never be required in new code,
which could simply give a *conditional* strong guarantee, e.g. âif an
exception is thrown other than by ``T``\ 's move constructor, there are
-no effects.â
+no effects.â We recommend that approach as best practice for new code.
Implementing ``std::legacy_move``
*********************************
@@ -480,3 +486,9 @@
.. [#is_nothrow_constructible] See N2953_ for a definition of
``is_nothrow_constructible``.
+
+.. [#default-construct-swap] Actually ``reserve`` and other such
+ operations can be optimized even for a type without non-throwing
+ move constructors but with a default constructor and a non-throwing
+ swap, by first default-constructing elements in the new array and
+ swapping each element into place.
Modified: sandbox/committee/rvalue_ref/N2983.html
==============================================================================
--- sandbox/committee/rvalue_ref/N2983.html (original)
+++ sandbox/committee/rvalue_ref/N2983.html 2009-10-16 14:19:55 EDT (Fri, 16 Oct 2009)
@@ -320,30 +320,35 @@
<div class="contents topic" id="index">
<p class="topic-title first">index</p>
<ul class="simple">
-<li><a class="reference internal" href="#introduction" id="id5">Introduction</a></li>
-<li><a class="reference internal" href="#implementing-std-legacy-move" id="id6">Implementing <tt class="docutils literal"><span class="pre">std::legacy_move</span></tt></a></li>
-<li><a class="reference internal" href="#an-optimization-hint" id="id7">An Optimization Hint</a></li>
-<li><a class="reference internal" href="#interactions-with-other-proposals" id="id8">Interactions with Other Proposals</a></li>
-<li><a class="reference internal" href="#existing-practice" id="id9">Existing Practice</a></li>
-<li><a class="reference internal" href="#proposed-changes-to-standard-wording" id="id10">Proposed Changes to Standard Wording</a><ul>
-<li><a class="reference internal" href="#exception-specifications-except-spec" id="id11">15.4 Exception specifications [except.spec]</a></li>
-<li><a class="reference internal" href="#a-13-exception-handling-gram-except" id="id12">A.13 Exception handling [gram.except]</a></li>
-<li><a class="reference internal" href="#header-type-traits-synopsis-meta-type-synop" id="id13">20.6.2 Header <type_traits> synopsis [meta.type.synop]</a></li>
-<li><a class="reference internal" href="#type-properties-meta-unary-prop" id="id14">20.6.4.3 Type properties [meta.unary.prop]</a></li>
-<li><a class="reference internal" href="#deque-modifiers-deque-modifiers" id="id15">23.3.2.3 deque modifiers [deque.modifiers]</a></li>
-<li><a class="reference internal" href="#vector-capacity-vector-capacity" id="id16">23.3.6.2 vector capacity [vector.capacity]</a></li>
-<li><a class="reference internal" href="#vector-modifiers-vector-modifiers" id="id17">23.3.6.4 vector modifiers [vector.modifiers]</a></li>
+<li><a class="reference internal" href="#introduction" id="id6">Introduction</a></li>
+<li><a class="reference internal" href="#motivation" id="id7">Motivation</a></li>
+<li><a class="reference internal" href="#solution" id="id8">Solution</a></li>
+<li><a class="reference internal" href="#implementing-std-legacy-move" id="id9">Implementing <tt class="docutils literal"><span class="pre">std::legacy_move</span></tt></a></li>
+<li><a class="reference internal" href="#an-optimization-hint" id="id10">An Optimization Hint</a></li>
+<li><a class="reference internal" href="#interactions-with-other-proposals" id="id11">Interactions with Other Proposals</a></li>
+<li><a class="reference internal" href="#existing-practice" id="id12">Existing Practice</a></li>
+<li><a class="reference internal" href="#proposed-changes-to-standard-wording" id="id13">Proposed Changes to Standard Wording</a><ul>
+<li><a class="reference internal" href="#exception-specifications-except-spec" id="id14">15.4 Exception specifications [except.spec]</a></li>
+<li><a class="reference internal" href="#a-13-exception-handling-gram-except" id="id15">A.13 Exception handling [gram.except]</a></li>
+<li><a class="reference internal" href="#header-type-traits-synopsis-meta-type-synop" id="id16">20.6.2 Header <type_traits> synopsis [meta.type.synop]</a></li>
+<li><a class="reference internal" href="#type-properties-meta-unary-prop" id="id17">20.6.4.3 Type properties [meta.unary.prop]</a></li>
+<li><a class="reference internal" href="#deque-modifiers-deque-modifiers" id="id18">23.3.2.3 deque modifiers [deque.modifiers]</a></li>
+<li><a class="reference internal" href="#vector-capacity-vector-capacity" id="id19">23.3.6.2 vector capacity [vector.capacity]</a></li>
+<li><a class="reference internal" href="#vector-modifiers-vector-modifiers" id="id20">23.3.6.4 vector modifiers [vector.modifiers]</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="introduction">
-<h1><a class="toc-backref" href="#id5">Introduction</a></h1>
+<h1><a class="toc-backref" href="#id6">Introduction</a></h1>
<p>In <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html">N2855</a>, Doug Gregor and Dave Abrahams discussed a problematic
interaction between move constructors, templates, and certain standard
library member functions. To date, attempts to solve the problem
(including <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html">N2855</a> itself) have taken one basic approach: <em>ban throwing
move constructors, and be sure never to generate one</em>.</p>
+</div>
+<div class="section" id="motivation">
+<h1><a class="toc-backref" href="#id7">Motivation</a></h1>
<p>Consider, for a moment, the actual magnitude of the problem we're
addressing: it's a backward-compatibility/code evolution issue that
only arises when <em>all</em> these conditions are satisfied:</p>
@@ -384,6 +389,9 @@
for move constructors, whose only purpose is in solving this
particular problem.<a class="footnote-reference" href="#attribute" id="id2"><sup>1</sup></a></li>
</ul>
+</div>
+<div class="section" id="solution">
+<h1><a class="toc-backref" href="#id8">Solution</a></h1>
<p>Fortunately, there is a better way. Instead of imposing this burden
on every class author, we can deal with the issue more selectively in
the operation being move-enabled. There, we know whether a throwing
@@ -407,7 +415,7 @@
second( move(rhs.second) )
{}
</pre>
-<p>However, <tt class="docutils literal"><span class="pre">std::vector::reserve</span></tt> would be move-enabled this way:</p>
+<p>However, <tt class="docutils literal"><span class="pre">std::vector::reserve</span></tt> could be move-enabled this way:<a class="footnote-reference" href="#default-construct-swap" id="id3"><sup>5</sup></a></p>
<pre class="literal-block">
void reserve(size_type n)
{
@@ -441,10 +449,10 @@
circumstances. In particular, it would never be required in new code,
which could simply give a <em>conditional</em> strong guarantee, e.g. âif an
exception is thrown other than by <tt class="docutils literal"><span class="pre">T</span></tt>'s move constructor, there are
-no effects.â</p>
+no effects.â We recommend that approach as best practice for new code.</p>
</div>
<div class="section" id="implementing-std-legacy-move">
-<h1><a class="toc-backref" href="#id6">Implementing <tt class="docutils literal"><span class="pre">std::legacy_move</span></tt></a></h1>
+<h1><a class="toc-backref" href="#id9">Implementing <tt class="docutils literal"><span class="pre">std::legacy_move</span></tt></a></h1>
<p>One possible implementation of <tt class="docutils literal"><span class="pre">std::legacy_move</span></tt> might be:</p>
<pre class="literal-block">
template <class T>
@@ -468,7 +476,7 @@
constructor can throw.</p>
</div>
<div class="section" id="an-optimization-hint">
-<h1><a class="toc-backref" href="#id7">An Optimization Hint</a></h1>
+<h1><a class="toc-backref" href="#id10">An Optimization Hint</a></h1>
<p>To help the library deduce the correct result for these traits, we
propose to add a new kind of exception-specification, spelled:</p>
<pre class="literal-block">
@@ -476,7 +484,7 @@
</pre>
<p>The only impact of such an exception-specification is this: if a
function decorated with <tt class="docutils literal"><span class="pre">throw(false)</span></tt> throws an exception, the
-behavior is undefined.<a class="footnote-reference" href="#no-diagnostic" id="id3"><sup>3</sup></a> That effect is sufficient to
+behavior is undefined.<a class="footnote-reference" href="#no-diagnostic" id="id4"><sup>3</sup></a> That effect is sufficient to
allow these <em>xxx</em><tt class="docutils literal"><span class="pre">_nothrow_</span></tt><em>xxx</em> traits to report <tt class="docutils literal"><span class="pre">true</span></tt> for
any operation decorated with <tt class="docutils literal"><span class="pre">throw(false)</span></tt>. Class maintainers could
label their move constructors <tt class="docutils literal"><span class="pre">throw(false)</span></tt> to indicate non-throwing
@@ -498,7 +506,7 @@
template <class First2, Second2>
pair( pair<First2,Second2>&& rhs )
<strong>throw( !is_nothrow_constructible<First,First2&&>::value
- || !is_nothrow_constructible<Second,Second2&&>::value )</strong><a class="footnote-reference" href="#is-nothrow-constructible" id="id4"><sup>4</sup></a>
+ || !is_nothrow_constructible<Second,Second2&&>::value )</strong><a class="footnote-reference" href="#is-nothrow-constructible" id="id5"><sup>4</sup></a>
: first( move(rhs.first) ),
second( move(rhs.second) )
{}
@@ -509,7 +517,7 @@
absence doesn't affect the correctness of a move constructor.</p>
</div>
<div class="section" id="interactions-with-other-proposals">
-<h1><a class="toc-backref" href="#id8">Interactions with Other Proposals</a></h1>
+<h1><a class="toc-backref" href="#id11">Interactions with Other Proposals</a></h1>
<p>The generation of default move constructors, first proposed by Bjarne
Stroustrup in <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2904.pdf">N2904</a>, and again by Bjarne Stroustrup and Lawrence
Crowl in <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2953.html">N2953</a>, is harmonious with our proposal. For example, since
@@ -525,7 +533,7 @@
<tt class="docutils literal"><span class="pre">pair</span></tt>'s move constructor above. We suggest it be dropped.</p>
</div>
<div class="section" id="existing-practice">
-<h1><a class="toc-backref" href="#id9">Existing Practice</a></h1>
+<h1><a class="toc-backref" href="#id12">Existing Practice</a></h1>
<p>The Microsoft compiler has always treated empty
exception-specifications as though they have the same meaning we
propose for <tt class="docutils literal"><span class="pre">throw(false)</span></tt>. That is, Microsoft omits the
@@ -537,9 +545,9 @@
to this optimization tool.</p>
</div>
<div class="section" id="proposed-changes-to-standard-wording">
-<h1><a class="toc-backref" href="#id10">Proposed Changes to Standard Wording</a></h1>
+<h1><a class="toc-backref" href="#id13">Proposed Changes to Standard Wording</a></h1>
<div class="section" id="exception-specifications-except-spec">
-<h2><a class="toc-backref" href="#id11">15.4 Exception specifications [except.spec]</a></h2>
+<h2><a class="toc-backref" href="#id14">15.4 Exception specifications [except.spec]</a></h2>
<p>Change paragraph 1 as follows:</p>
<blockquote>
<p>1 A function declaration lists exceptions that its function might directly
@@ -569,7 +577,7 @@
</blockquote>
</div>
<div class="section" id="a-13-exception-handling-gram-except">
-<h2><a class="toc-backref" href="#id12">A.13 Exception handling [gram.except]</a></h2>
+<h2><a class="toc-backref" href="#id15">A.13 Exception handling [gram.except]</a></h2>
<pre class="literal-block">
exception-specification
throw ( type-id-listopt )
@@ -577,7 +585,7 @@
</pre>
</div>
<div class="section" id="header-type-traits-synopsis-meta-type-synop">
-<h2><a class="toc-backref" href="#id13">20.6.2 Header <type_traits> synopsis [meta.type.synop]</a></h2>
+<h2><a class="toc-backref" href="#id16">20.6.2 Header <type_traits> synopsis [meta.type.synop]</a></h2>
<pre class="literal-block">
template <class T> struct has_nothrow_assign;
<span class="ins">template <class T> struct has_move_constructor;
@@ -594,7 +602,7 @@
</pre>
</div>
<div class="section" id="type-properties-meta-unary-prop">
-<h2><a class="toc-backref" href="#id14">20.6.4.3 Type properties [meta.unary.prop]</a></h2>
+<h2><a class="toc-backref" href="#id17">20.6.4.3 Type properties [meta.unary.prop]</a></h2>
<p>Add entries to table 43:</p>
<table border="1" class="docutils">
<colgroup>
@@ -668,7 +676,7 @@
</table>
</div>
<div class="section" id="deque-modifiers-deque-modifiers">
-<h2><a class="toc-backref" href="#id15">23.3.2.3 deque modifiers [deque.modifiers]</a></h2>
+<h2><a class="toc-backref" href="#id18">23.3.2.3 deque modifiers [deque.modifiers]</a></h2>
<p>Change paragraph 2 as follows:</p>
<blockquote>
2 Remarks: If an exception is thrown other than by the copy constructor,
@@ -681,7 +689,7 @@
or assignment operator of <tt class="docutils literal"><span class="pre">T</span></tt>.</blockquote>
</div>
<div class="section" id="vector-capacity-vector-capacity">
-<h2><a class="toc-backref" href="#id16">23.3.6.2 vector capacity [vector.capacity]</a></h2>
+<h2><a class="toc-backref" href="#id19">23.3.6.2 vector capacity [vector.capacity]</a></h2>
<p>Context:</p>
<pre class="literal-block">
void reserve(size_type n);
@@ -714,7 +722,7 @@
<code>T</code></span></span> there are no effects.</blockquote>
</div>
<div class="section" id="vector-modifiers-vector-modifiers">
-<h2><a class="toc-backref" href="#id17">23.3.6.4 vector modifiers [vector.modifiers]</a></h2>
+<h2><a class="toc-backref" href="#id20">23.3.6.4 vector modifiers [vector.modifiers]</a></h2>
<p>Context:</p>
<pre class="literal-block">
iterator insert(const_iterator position, const T& x);
@@ -776,7 +784,7 @@
<table class="docutils footnote" frame="void" id="no-diagnostic" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id3">[3]</a></td><td>In particular, we are not proposing to mandate
+<tr><td class="label"><a class="fn-backref" href="#id4">[3]</a></td><td>In particular, we are not proposing to mandate
static checking: a <tt class="docutils literal"><span class="pre">throw(false)</span></tt> function can call a <tt class="docutils literal"><span class="pre">throw(true)</span></tt>
function without causing the program to become ill-formed or
generating a diagnostic. Generating a diagnostic in such cases
@@ -786,10 +794,20 @@
<table class="docutils footnote" frame="void" id="is-nothrow-constructible" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id4">[4]</a></td><td>See <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2953.html">N2953</a> for a definition of
+<tr><td class="label"><a class="fn-backref" href="#id5">[4]</a></td><td>See <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2953.html">N2953</a> for a definition of
<tt class="docutils literal"><span class="pre">is_nothrow_constructible</span></tt>.</td></tr>
</tbody>
</table>
+<table class="docutils footnote" frame="void" id="default-construct-swap" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id3">[5]</a></td><td>Actually <tt class="docutils literal"><span class="pre">reserve</span></tt> and other such
+operations can be optimized even for a type without non-throwing
+move constructors but with a default constructor and a non-throwing
+swap, by first default-constructing elements in the new array and
+swapping each element into place.</td></tr>
+</tbody>
+</table>
</div>
</div>
</div>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk