|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r57077 - sandbox/committee/rvalue_ref
From: dave_at_[hidden]
Date: 2009-10-22 17:54:48
Author: dave
Date: 2009-10-22 17:54:47 EDT (Thu, 22 Oct 2009)
New Revision: 57077
URL: http://svn.boost.org/trac/boost/changeset/57077
Log:
Edits per Evolution Working Group, preparing to send to Core.
Text files modified:
sandbox/committee/rvalue_ref/N2983-throwing-move.rst | 198 +++++++++++++++++++++-----------------
sandbox/committee/rvalue_ref/N2983.html | 201 +++++++++++++++++++++------------------
sandbox/committee/rvalue_ref/rst.css | 8 +
3 files changed, 228 insertions(+), 179 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-22 17:54:47 EDT (Thu, 22 Oct 2009)
@@ -88,7 +88,7 @@
move can disturb existing guarantees. We propose that instead of
using ``std::move(x)`` in those cases, thus granting permission for
the compiler to use *any* available move constructor, maintainers of
-these particular operations should use ``std::legacy_move(x)``, which
+these particular operations should use ``std::move_if_noexcept(x)``, which
grants permission move *unless* it could throw and the type is
copyable. Unless ``x`` is a move-only type, or is known to have a
nonthrowing move constructor, the operation would fall back to copying
@@ -118,7 +118,7 @@
try
{
for (;i < s; ++i)
- new ((void*)(new_begin + i)) value_type( **std::legacy_move(** (\*this)[i]) **)** );
+ new ((void*)(new_begin + i)) value_type( **std::move_if_noexcept(** (\*this)[i]) **)** );
}
catch(...)
{
@@ -137,7 +137,7 @@
}
-We stress again that the use of ``std::legacy_move`` as opposed to
+We stress again that the use of ``std::move_if_noexcept`` as opposed to
``move`` would only be necessary under an *extremely* limited set of
circumstances. In particular, it would never be required in new code,
which could simply give a *conditional* strong guarantee, e.g. âif an
@@ -145,24 +145,24 @@
are no effects.â We recommend that approach as best practice for new
code.
-Implementing ``std::legacy_move``
-*********************************
+Implementing ``std::move_if_noexcept``
+**************************************
-One possible implementation of ``std::legacy_move`` might be::
+One possible implementation of ``std::move_if_noexcept`` might be::
template <class T>
typename conditional<
- !has_nothrow_move_constructor<T>::value
+ !nothrow_move_constructible<T>::value
&& has_copy_constructor<T>::value,
T const&,
T&&
>::type
- legacy_move(T& x)
+ move_if_noexcept(T& x)
{
return std::move(x);
}
-We propose that ``has_nothrow_move_constructor<T>`` be a conservative
+We propose that ``nothrow_move_constructible<T>`` be a conservative
trait very much like ``has_nothrow_copy_constructor<T>`` from the
current working draft; it would be identical to the proposed
``is_nothrow_constructible<T,T&&>`` from N2953_. In other words, it
@@ -178,18 +178,18 @@
.. parsed-literal::
- throw( *integral constant expression* )
+ noexcept( *integral constant expression* )
The only impact of such an exception-specification is this: if a
-function decorated with ``throw(false)`` throws an exception, the
+function decorated with ``noexcept(true)`` throws an exception, the
behavior is undefined. [#no-diagnostic]_ That effect is sufficient to
allow these *xxx*\ ``_nothrow_``\ *xxx* traits to report ``true`` for
-any operation decorated with ``throw(false)``. Class maintainers could
-label their move constructors ``throw(false)`` to indicate non-throwing
+any operation decorated with ``noexcept(true)``. Class maintainers could
+label their move constructors ``noexcept(true)`` to indicate non-throwing
behavior, and the library is permitted to take advantage of that
labelling if it can be detected (via âcompiler magicâ).
-Note that the usefulness of ``throw(false)`` as an optimization hint
+Note that the usefulness of ``noexcept(true)`` as an optimization hint
goes way beyond the narrow case introduced by N2855_. In fact, it
goes beyond move construction: when the compiler can detect
non-throwing operations with certainty, it can optimize away a great
@@ -242,12 +242,12 @@
The Microsoft compiler has always treated empty
exception-specifications as though they have the same meaning we
-propose for ``throw(false)``. That is, Microsoft omits the
+propose for ``noexcept(true)``. That is, Microsoft omits the
standard-mandated runtime behavior if the function throws, and it
performs optimizations based on the assumption that the function
doesn't throw. This interpretation of ``throw()`` has proven to be
successful in practice and is regarded by many as superior to the one
-in the standard. Standardizing ``throw(false)`` gives everyone access
+in the standard. Standardizing ``noexcept(true)`` gives everyone access
to this optimization tool.
Low-Hanging Fruit
@@ -256,17 +256,17 @@
There are a couple of additional features we think the committee
should consider if this proposal is accepted.
-Implicit ``throw(false)`` for Destructors
-=========================================
+Implicit ``noexcept(true)`` for Destructors
+===========================================
So few destructors can throw exceptions that the default
exception-specification for destructors could be changed from nothing
-(i.e. ``throw(true)``) to ``throw(false)`` with only a tiny amount of code
+(i.e. ``noexcept(false)``) to ``noexcept(true)`` with only a tiny amount of code
breakage. Such code is already very dangerous, and where used
properly, ought to be a well-known âcaution areaâ that is reasonably
easily migrated.
-operator ``may_throw(``\ *expression*\ ``)``
+operator ``noexcept(``\ *expression*\ ``)``
============================================
It seems that ``has_nothrow_``\ *xxx* traits are proliferating (and
@@ -280,6 +280,8 @@
Proposed Changes to Standard Wording
************************************
+.. role:: sub
+
.. role:: ins
.. role:: del
@@ -302,40 +304,59 @@
or indirectly throw by using an exception-specification as a suffix of its
declarator.
- .. parsed-literal::
-
- exception-specification
- throw ( type-id-listopt )
- type-id-list:
- type-id ...opt
- type-id-list , type-id ...opt
- :ins:`throw( constant-expression )`
+ :raw-html:`<p><em>
+ exception-specification:
+ <blockquote class="grammar">
+ <span class="ins">dynamic-exception-specification</span>
+ <br />
+ <span class="ins">noexcept-specification</span>
+ </blockquote>
+ <em></p>`
+
+ :raw-html:`<p><span class="ins">
+ <em>dynamic-exception-specification:</em>
+ </span>
+ <blockquote>
+ <code>throw (</code> <em>type-id-list<span class="sub">opt</span></em> <code>)</code>
+ </blockquote>
+ </em>
+ </p>`
+
+ :raw-html:`<p><em>
+ type-id-list:
+ <blockquote>
+ type-id ...<span class="sub">opt</span><br />
+ type-id-list, type-id ...<span class="sub">opt</span>
+ </blockquote>
+ <em>
+ </p>`
+
+ :raw-html:`<p>
+ <span class="ins"><em>noexcept-specification:</em></span>
+ <blockquote>
+ <span class="ins"><code>noexcept (</code> <em>constant-expression<span class="sub">opt</span></em> <code>)</code></span>
+ </blockquote>
+ </em>
+ </p>`
Add these paragraphs:
- :raw-html:`<span class="ins">15 In an exception-specification of
- the form <code>throw(</code> <em>constant-expression</em>
- <code>)</code>, the constant-expression shall be a constant
- expression (5.19) that can be contextually converted to
- <code>bool</code> (Clause 4).</span>`
+ :raw-html:`<span class="ins">15 In a noexcept-specification, the
+ constant-expression, if supplied, shall be a constant expression
+ (5.19) that can be contextually converted to <code>bool</code>
+ (Clause 4).</span>`
:raw-html:`<span class="ins">16 If a function with the
- exception-specification <code>throw(false)</code> throws an
+ noexcept-specification <code>noexcept(true)</code> throws an
exception, the behavior is undefined. The exception-specification
- <code>throw(false)</code> is in all other respects equivalent to
+ <code>noexcept(true)</code> is in all other respects equivalent to
<code>throw()</code>. The exception-specification
- <code>throw(true)</code> is equivalent to omitting the exception
+ <code>noexcept(false)</code> is equivalent to omitting the exception
specification altogether.</span>`
-A.13 Exception handling [gram.except]
-=====================================
-
-.. parsed-literal::
-
- exception-specification
- throw ( type-id-listopt )
- :ins:`throw(constant-expression)`
+ :raw-html:`<span class="ins">17 <code>noexcept()</code> is
+ equivalent to <code>noexcept(true)</code>.</span>`
20.3 Utility components [utility]
=================================
@@ -349,8 +370,8 @@
template <class T> T&& forward(typename identity<T>::type&&);
template <class T> typename remove_reference<T>::type&& move(T&&);
:ins:`template <class T> typename conditional<
- !has_nothrow_move_constructor<T>::value && has_copy_constructor<T>::value,
- T const&, T&&>::type legacy_move(T& x);`
+ !nothrow_move_constructible<T>::value && has_copy_constructor<T>::value,
+ T const&, T&&>::type move_if_noexcept(T& x);`
20.3.2 forward/move helpers [forward]
=====================================
@@ -360,10 +381,10 @@
.. parsed-literal::
:ins:`template <class T> typename conditional<
- !has_nothrow_move_constructor<T>::value && has_copy_constructor<T>::value,
- T const&, T&&>::type legacy_move(T& x);`
+ !nothrow_move_constructible<T>::value && has_copy_constructor<T>::value,
+ T const&, T&&>::type move_if_noexcept(T& x);`
- :raw-html:`<span class="ins">10 <em>Returns:</em> <code>t</code></span>`
+ :raw-html:`<span class="ins">10 <em>Returns:</em> <code>std::move(t)</code></span>`
20.6.2 Header ``<type_traits>`` synopsis [meta.type.synop]
==========================================================
@@ -372,10 +393,10 @@
template <class T> struct has_nothrow_assign;
:ins:`template <class T> struct has_move_constructor;
- template <class T> struct has_nothrow_move_constructor;
+ template <class T> struct nothrow_move_constructible;
template <class T> struct has_move_assign;
- template <class T> struct has_nothrow_move_assign;
+ template <class T> struct nothrow_move_assignable;
template <class T> struct has_copy_constructor;
template <class T> struct has_default_constructor;
@@ -390,40 +411,41 @@
Add entries to table 43:
-+--------------------------------+---------------------------+-----------------------------------+
-| Template |Condition |Preconditions |
-+================================+===========================+===================================+
-| ``template <class T> |``T`` has a move |``T`` shall be a complete type. |
-| struct has_move_constructor;`` |constructor (17.3.14). | |
-+--------------------------------+---------------------------+-----------------------------------+
-| ``template <class T> |``T`` is a type with a move|``T`` shall be a complete type. |
-| struct |constructor that is known | |
-| has_nothrow_move_constructor;``|not to throw any | |
-| |exceptions. | |
-+--------------------------------+---------------------------+-----------------------------------+
-| ``template <class T> |``T`` has a move assignment|``T`` shall be a complete type. |
-| struct has_move_assign;`` |operator (17.3.13). | |
-+--------------------------------+---------------------------+-----------------------------------+
-| ``template <class T> |``T`` is a type with a move|``T`` shall be a complete type. |
-| struct |assignment operator that is| |
-| has_nothrow_move_assign;`` |known not to throw any | |
-| |exceptions. | |
-+--------------------------------+---------------------------+-----------------------------------+
-| ``template <class T> |``T`` has a copy |``T`` shall be a complete type, an |
-| struct has_copy_constructor;`` |constructor (12.8). |array of unknown bound, or |
-| | |(possibly cv-qualified) ``void.`` |
-| | | |
-+--------------------------------+---------------------------+-----------------------------------+
-| ``template <class T> |``T`` has a default |``T`` shall be a complete type, an |
-| struct |constructor (12.1). |array of unknown bound, or |
-| has_default_constructor;`` | |(possibly cv-qualified) ``void.`` |
-| | | |
-+--------------------------------+---------------------------+-----------------------------------+
-| ``template <class T> |``T`` has a copy assignment|``T`` shall be a complete type, an |
-| struct has_copy_assign;`` |operator (12.8). |array of unknown bound, or |
-| | |(possibly cv-qualified) ``void``. |
-| | | |
-+--------------------------------+---------------------------+-----------------------------------+
++--------------------------------+-----------------------------------+-----------------------------------+
+| Template |Condition |Preconditions |
++================================+===================================+===================================+
+| ``template <class T> |``T`` has a move constructor |``T`` shall be a complete type. |
+| struct has_move_constructor;`` |(17.3.14). | |
++--------------------------------+-----------------------------------+-----------------------------------+
+| ``template <class T> |``noexcept( T( make<T>() ) )`` |``T`` shall be a complete type. |
+| struct | | |
+| nothrow_move_constructible;`` | | |
+| | | |
+| | | |
++--------------------------------+-----------------------------------+-----------------------------------+
+| ``template <class T> |``T`` has a move assignment |``T`` shall be a complete type. |
+| struct has_move_assign;`` |operator (17.3.13). | |
++--------------------------------+-----------------------------------+-----------------------------------+
+| ``template <class T> |``noexcept( *(T*)0 = make<T> )`` |``T`` shall be a complete type. |
+| struct | | |
+| nothrow_move_assignable;`` | | |
+| | | |
++--------------------------------+-----------------------------------+-----------------------------------+
+| ``template <class T> |``T`` has a copy constructor |``T`` shall be a complete type, an |
+| struct has_copy_constructor;`` |(12.8). |array of unknown bound, or |
+| | |(possibly cv-qualified) ``void.`` |
+| | | |
++--------------------------------+-----------------------------------+-----------------------------------+
+| ``template <class T> |``T`` has a default constructor |``T`` shall be a complete type, an |
+| struct |(12.1). |array of unknown bound, or |
+| has_default_constructor;`` | |(possibly cv-qualified) ``void.`` |
+| | | |
++--------------------------------+-----------------------------------+-----------------------------------+
+| ``template <class T> |``T`` has a copy assignment |``T`` shall be a complete type, an |
+| struct has_copy_assign;`` |operator (12.8). |array of unknown bound, or |
+| | |(possibly cv-qualified) ``void``. |
+| | | |
++--------------------------------+-----------------------------------+-----------------------------------+
23.3.2.3 deque modifiers [deque.modifiers]
==========================================
@@ -476,8 +498,8 @@
Remove paragraph 2:
- :del:`2 Requires: If value_type has a move constructor, that constructor shall
- not throw any exceptions.`
+ :del:`2 Requires: If value_type has a move constructor, that
+ constructor shall not throw any exceptions.`
Change paragraph 3 as follows:
@@ -573,7 +595,7 @@
from locations observable by the caller.
.. [#no-diagnostic] In particular, we are not proposing to mandate
- static checking: a ``throw(false)`` function can call a ``throw(true)``
+ static checking: a ``noexcept(true)`` function can call a ``noexcept(false)``
function without causing the program to become ill-formed or
generating a diagnostic. Generating a diagnostic in such cases
can, of course, be implemented by any compiler as a matter of QOI.
Modified: sandbox/committee/rvalue_ref/N2983.html
==============================================================================
--- sandbox/committee/rvalue_ref/N2983.html (original)
+++ sandbox/committee/rvalue_ref/N2983.html 2009-10-22 17:54:47 EDT (Thu, 22 Oct 2009)
@@ -296,6 +296,14 @@
.ins {background-color:#A0FFA0;border-bottom: 1px solid black}
.del {background-color:#FFA0A0;text-decoration:line-through}
+.grammar { padding: 0 }
+
+.sub {
+ position: relative;
+ bottom: -0.5em;
+ font-size: 0.8em;
+}
+
</style>
</head>
<body>
@@ -328,25 +336,24 @@
<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="#implementing-std-move-if-noexcept" id="id9">Implementing <tt class="docutils literal"><span class="pre">std::move_if_noexcept</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="#low-hanging-fruit" id="id13">Low-Hanging Fruit</a><ul>
-<li><a class="reference internal" href="#implicit-throw-false-for-destructors" id="id14">Implicit <tt class="docutils literal"><span class="pre">throw(false)</span></tt> for Destructors</a></li>
-<li><a class="reference internal" href="#operator-may-throw-expression" id="id15">operator <tt class="docutils literal"><span class="pre">may_throw(</span></tt><em>expression</em><tt class="docutils literal"><span class="pre">)</span></tt></a></li>
+<li><a class="reference internal" href="#implicit-noexcept-true-for-destructors" id="id14">Implicit <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> for Destructors</a></li>
+<li><a class="reference internal" href="#operator-noexcept-expression" id="id15">operator <tt class="docutils literal"><span class="pre">noexcept(</span></tt><em>expression</em><tt class="docutils literal"><span class="pre">)</span></tt></a></li>
</ul>
</li>
<li><a class="reference internal" href="#proposed-changes-to-standard-wording" id="id16">Proposed Changes to Standard Wording</a><ul>
<li><a class="reference internal" href="#exception-specifications-except-spec" id="id17">15.4 Exception specifications [except.spec]</a></li>
-<li><a class="reference internal" href="#a-13-exception-handling-gram-except" id="id18">A.13 Exception handling [gram.except]</a></li>
-<li><a class="reference internal" href="#utility-components-utility" id="id19">20.3 Utility components [utility]</a></li>
-<li><a class="reference internal" href="#forward-move-helpers-forward" id="id20">20.3.2 forward/move helpers [forward]</a></li>
-<li><a class="reference internal" href="#header-type-traits-synopsis-meta-type-synop" id="id21">20.6.2 Header <tt class="docutils literal"><span class="pre"><type_traits></span></tt> synopsis [meta.type.synop]</a></li>
-<li><a class="reference internal" href="#type-properties-meta-unary-prop" id="id22">20.6.4.3 Type properties [meta.unary.prop]</a></li>
-<li><a class="reference internal" href="#deque-modifiers-deque-modifiers" id="id23">23.3.2.3 deque modifiers [deque.modifiers]</a></li>
-<li><a class="reference internal" href="#vector-capacity-vector-capacity" id="id24">23.3.6.2 vector capacity [vector.capacity]</a></li>
-<li><a class="reference internal" href="#vector-modifiers-vector-modifiers" id="id25">23.3.6.4 vector modifiers [vector.modifiers]</a></li>
+<li><a class="reference internal" href="#utility-components-utility" id="id18">20.3 Utility components [utility]</a></li>
+<li><a class="reference internal" href="#forward-move-helpers-forward" id="id19">20.3.2 forward/move helpers [forward]</a></li>
+<li><a class="reference internal" href="#header-type-traits-synopsis-meta-type-synop" id="id20">20.6.2 Header <tt class="docutils literal"><span class="pre"><type_traits></span></tt> synopsis [meta.type.synop]</a></li>
+<li><a class="reference internal" href="#type-properties-meta-unary-prop" id="id21">20.6.4.3 Type properties [meta.unary.prop]</a></li>
+<li><a class="reference internal" href="#deque-modifiers-deque-modifiers" id="id22">23.3.2.3 deque modifiers [deque.modifiers]</a></li>
+<li><a class="reference internal" href="#vector-capacity-vector-capacity" id="id23">23.3.6.2 vector capacity [vector.capacity]</a></li>
+<li><a class="reference internal" href="#vector-modifiers-vector-modifiers" id="id24">23.3.6.4 vector modifiers [vector.modifiers]</a></li>
</ul>
</li>
</ul>
@@ -410,7 +417,7 @@
move can disturb existing guarantees. We propose that instead of
using <tt class="docutils literal"><span class="pre">std::move(x)</span></tt> in those cases, thus granting permission for
the compiler to use <em>any</em> available move constructor, maintainers of
-these particular operations should use <tt class="docutils literal"><span class="pre">std::legacy_move(x)</span></tt>, which
+these particular operations should use <tt class="docutils literal"><span class="pre">std::move_if_noexcept(x)</span></tt>, which
grants permission move <em>unless</em> it could throw and the type is
copyable. Unless <tt class="docutils literal"><span class="pre">x</span></tt> is a move-only type, or is known to have a
nonthrowing move constructor, the operation would fall back to copying
@@ -437,7 +444,7 @@
try
{
for (;i < s; ++i)
- new ((void*)(new_begin + i)) value_type( <strong>std::legacy_move(</strong> (*this)[i]) <strong>)</strong> );
+ new ((void*)(new_begin + i)) value_type( <strong>std::move_if_noexcept(</strong> (*this)[i]) <strong>)</strong> );
}
catch(...)
{
@@ -455,7 +462,7 @@
}
}
</pre>
-<p>We stress again that the use of <tt class="docutils literal"><span class="pre">std::legacy_move</span></tt> as opposed to
+<p>We stress again that the use of <tt class="docutils literal"><span class="pre">std::move_if_noexcept</span></tt> as opposed to
<tt class="docutils literal"><span class="pre">move</span></tt> would only be necessary under an <em>extremely</em> limited set of
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
@@ -463,23 +470,23 @@
are 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="#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>
+<div class="section" id="implementing-std-move-if-noexcept">
+<h1><a class="toc-backref" href="#id9">Implementing <tt class="docutils literal"><span class="pre">std::move_if_noexcept</span></tt></a></h1>
+<p>One possible implementation of <tt class="docutils literal"><span class="pre">std::move_if_noexcept</span></tt> might be:</p>
<pre class="literal-block">
template <class T>
typename conditional<
- !has_nothrow_move_constructor<T>::value
+ !nothrow_move_constructible<T>::value
&& has_copy_constructor<T>::value,
T const&,
T&&
>::type
-legacy_move(T& x)
+move_if_noexcept(T& x)
{
return std::move(x);
}
</pre>
-<p>We propose that <tt class="docutils literal"><span class="pre">has_nothrow_move_constructor<T></span></tt> be a conservative
+<p>We propose that <tt class="docutils literal"><span class="pre">nothrow_move_constructible<T></span></tt> be a conservative
trait very much like <tt class="docutils literal"><span class="pre">has_nothrow_copy_constructor<T></span></tt> from the
current working draft; it would be identical to the proposed
<tt class="docutils literal"><span class="pre">is_nothrow_constructible<T,T&&></span></tt> from <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2953.html">N2953</a>. In other words, it
@@ -492,17 +499,17 @@
<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">
-throw( <em>integral constant expression</em> )
+noexcept( <em>integral constant expression</em> )
</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
+function decorated with <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> throws an exception, the
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
+any operation decorated with <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt>. Class maintainers could
+label their move constructors <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> to indicate non-throwing
behavior, and the library is permitted to take advantage of that
labelling if it can be detected (via âcompiler magicâ).</p>
-<p>Note that the usefulness of <tt class="docutils literal"><span class="pre">throw(false)</span></tt> as an optimization hint
+<p>Note that the usefulness of <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> as an optimization hint
goes way beyond the narrow case introduced by <a class="reference external" href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2855.html">N2855</a>. In fact, it
goes beyond move construction: when the compiler can detect
non-throwing operations with certainty, it can optimize away a great
@@ -548,29 +555,29 @@
<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
+propose for <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt>. That is, Microsoft omits the
standard-mandated runtime behavior if the function throws, and it
performs optimizations based on the assumption that the function
doesn't throw. This interpretation of <tt class="docutils literal"><span class="pre">throw()</span></tt> has proven to be
successful in practice and is regarded by many as superior to the one
-in the standard. Standardizing <tt class="docutils literal"><span class="pre">throw(false)</span></tt> gives everyone access
+in the standard. Standardizing <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> gives everyone access
to this optimization tool.</p>
</div>
<div class="section" id="low-hanging-fruit">
<h1><a class="toc-backref" href="#id13">Low-Hanging Fruit</a></h1>
<p>There are a couple of additional features we think the committee
should consider if this proposal is accepted.</p>
-<div class="section" id="implicit-throw-false-for-destructors">
-<h2><a class="toc-backref" href="#id14">Implicit <tt class="docutils literal"><span class="pre">throw(false)</span></tt> for Destructors</a></h2>
+<div class="section" id="implicit-noexcept-true-for-destructors">
+<h2><a class="toc-backref" href="#id14">Implicit <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> for Destructors</a></h2>
<p>So few destructors can throw exceptions that the default
exception-specification for destructors could be changed from nothing
-(i.e. <tt class="docutils literal"><span class="pre">throw(true)</span></tt>) to <tt class="docutils literal"><span class="pre">throw(false)</span></tt> with only a tiny amount of code
+(i.e. <tt class="docutils literal"><span class="pre">noexcept(false)</span></tt>) to <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> with only a tiny amount of code
breakage. Such code is already very dangerous, and where used
properly, ought to be a well-known âcaution areaâ that is reasonably
easily migrated.</p>
</div>
-<div class="section" id="operator-may-throw-expression">
-<h2><a class="toc-backref" href="#id15">operator <tt class="docutils literal"><span class="pre">may_throw(</span></tt><em>expression</em><tt class="docutils literal"><span class="pre">)</span></tt></a></h2>
+<div class="section" id="operator-noexcept-expression">
+<h2><a class="toc-backref" href="#id15">operator <tt class="docutils literal"><span class="pre">noexcept(</span></tt><em>expression</em><tt class="docutils literal"><span class="pre">)</span></tt></a></h2>
<p>It seems that <tt class="docutils literal"><span class="pre">has_nothrow_</span></tt><em>xxx</em> traits are proliferating (and
not just in this proposal). Once we have <tt class="docutils literal"><span class="pre">throw(</span></tt><em>bool-constant-expr</em><tt class="docutils literal"><span class="pre">)</span></tt> available to make the information
available, it makes sense to generalize the traits into an operator
@@ -587,41 +594,59 @@
<p>1 A function declaration lists exceptions that its function might directly
or indirectly throw by using an exception-specification as a suffix of its
declarator.</p>
-<pre class="literal-block">
-exception-specification
- throw ( type-id-listopt )
- type-id-list:
- type-id ...opt
- type-id-list , type-id ...opt
- <span class="ins">throw( constant-expression )</span>
-</pre>
+<blockquote>
+<p><span class="raw-html"><p><em>
+exception-specification:
+<blockquote class="grammar">
+<span class="ins">dynamic-exception-specification</span>
+<br />
+<span class="ins">noexcept-specification</span>
+</blockquote>
+<em></p></span></p>
+<p><span class="raw-html"><p><span class="ins">
+<em>dynamic-exception-specification:</em>
+</span>
+<blockquote>
+<code>throw (</code> <em>type-id-list<span class="sub">opt</span></em> <code>)</code>
+</blockquote>
+</em>
+</p></span></p>
+<p><span class="raw-html"><p><em>
+type-id-list:
+<blockquote>
+type-id ...<span class="sub">opt</span><br />
+type-id-list, type-id ...<span class="sub">opt</span>
+</blockquote>
+<em>
+</p></span></p>
+<p><span class="raw-html"><p>
+<span class="ins"><em>noexcept-specification:</em></span>
+<blockquote>
+<span class="ins"><code>noexcept (</code> <em>constant-expression<span class="sub">opt</span></em> <code>)</code></span>
+</blockquote>
+</em>
+</p></span></p>
+</blockquote>
</blockquote>
<p>Add these paragraphs:</p>
<blockquote>
-<p><span class="raw-html"><span class="ins">15 In an exception-specification of
-the form <code>throw(</code> <em>constant-expression</em>
-<code>)</code>, the constant-expression shall be a constant
-expression (5.19) that can be contextually converted to
-<code>bool</code> (Clause 4).</span></span></p>
+<p><span class="raw-html"><span class="ins">15 In a noexcept-specification, the
+constant-expression, if supplied, shall be a constant expression
+(5.19) that can be contextually converted to <code>bool</code>
+(Clause 4).</span></span></p>
<p><span class="raw-html"><span class="ins">16 If a function with the
-exception-specification <code>throw(false)</code> throws an
+noexcept-specification <code>noexcept(true)</code> throws an
exception, the behavior is undefined. The exception-specification
-<code>throw(false)</code> is in all other respects equivalent to
+<code>noexcept(true)</code> is in all other respects equivalent to
<code>throw()</code>. The exception-specification
-<code>throw(true)</code> is equivalent to omitting the exception
+<code>noexcept(false)</code> is equivalent to omitting the exception
specification altogether.</span></span></p>
+<p><span class="raw-html"><span class="ins">17 <code>noexcept()</code> is
+equivalent to <code>noexcept(true)</code>.</span></span></p>
</blockquote>
</div>
-<div class="section" id="a-13-exception-handling-gram-except">
-<h2><a class="toc-backref" href="#id18">A.13 Exception handling [gram.except]</a></h2>
-<pre class="literal-block">
-exception-specification
-throw ( type-id-listopt )
-<span class="ins">throw(constant-expression)</span>
-</pre>
-</div>
<div class="section" id="utility-components-utility">
-<h2><a class="toc-backref" href="#id19">20.3 Utility components [utility]</a></h2>
+<h2><a class="toc-backref" href="#id18">20.3 Utility components [utility]</a></h2>
<p>Change Header <tt class="docutils literal"><span class="pre"><utility></span></tt> synopsis as follows:</p>
<pre class="literal-block">
// 20.3.2, forward/move:
@@ -629,31 +654,31 @@
template <class T> T&& forward(typename identity<T>::type&&);
template <class T> typename remove_reference<T>::type&& move(T&&);
<span class="ins">template <class T> typename conditional<
- !has_nothrow_move_constructor<T>::value && has_copy_constructor<T>::value,
- T const&, T&&>::type legacy_move(T& x);</span>
+ !nothrow_move_constructible<T>::value && has_copy_constructor<T>::value,
+ T const&, T&&>::type move_if_noexcept(T& x);</span>
</pre>
</div>
<div class="section" id="forward-move-helpers-forward">
-<h2><a class="toc-backref" href="#id20">20.3.2 forward/move helpers [forward]</a></h2>
+<h2><a class="toc-backref" href="#id19">20.3.2 forward/move helpers [forward]</a></h2>
<p>Append the following:</p>
<blockquote>
<pre class="literal-block">
<span class="ins">template <class T> typename conditional<
- !has_nothrow_move_constructor<T>::value && has_copy_constructor<T>::value,
- T const&, T&&>::type legacy_move(T& x);</span>
+ !nothrow_move_constructible<T>::value && has_copy_constructor<T>::value,
+ T const&, T&&>::type move_if_noexcept(T& x);</span>
</pre>
-<p><span class="raw-html"><span class="ins">10 <em>Returns:</em> <code>t</code></span></span></p>
+<p><span class="raw-html"><span class="ins">10 <em>Returns:</em> <code>std::move(t)</code></span></span></p>
</blockquote>
</div>
<div class="section" id="header-type-traits-synopsis-meta-type-synop">
-<h2><a class="toc-backref" href="#id21">20.6.2 Header <tt class="docutils literal"><span class="pre"><type_traits></span></tt> synopsis [meta.type.synop]</a></h2>
+<h2><a class="toc-backref" href="#id20">20.6.2 Header <tt class="docutils literal"><span class="pre"><type_traits></span></tt> 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;
-template <class T> struct has_nothrow_move_constructor;
+template <class T> struct nothrow_move_constructible;
template <class T> struct has_move_assign;
-template <class T> struct has_nothrow_move_assign;
+template <class T> struct nothrow_move_assignable;
template <class T> struct has_copy_constructor;
template <class T> struct has_default_constructor;
@@ -663,13 +688,13 @@
</pre>
</div>
<div class="section" id="type-properties-meta-unary-prop">
-<h2><a class="toc-backref" href="#id22">20.6.4.3 Type properties [meta.unary.prop]</a></h2>
+<h2><a class="toc-backref" href="#id21">20.6.4.3 Type properties [meta.unary.prop]</a></h2>
<p>Add entries to table 43:</p>
<table border="1" class="docutils">
<colgroup>
+<col width="31%" />
+<col width="34%" />
<col width="34%" />
-<col width="29%" />
-<col width="37%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Template</th>
@@ -680,17 +705,14 @@
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">T></span>
<span class="pre">struct</span> <span class="pre">has_move_constructor;</span></tt></td>
-<td><tt class="docutils literal"><span class="pre">T</span></tt> has a move
-constructor (17.3.14).</td>
+<td><tt class="docutils literal"><span class="pre">T</span></tt> has a move constructor
+(17.3.14).</td>
<td><tt class="docutils literal"><span class="pre">T</span></tt> shall be a complete type.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">T></span>
<span class="pre">struct</span>
-<span class="pre">has_nothrow_move_constructor;</span></tt></td>
-<td><tt class="docutils literal"><span class="pre">T</span></tt> is a type with a move
-constructor that is known
-not to throw any
-exceptions.</td>
+<span class="pre">nothrow_move_constructible;</span></tt></td>
+<td><tt class="docutils literal"><span class="pre">noexcept(</span> <span class="pre">T(</span> <span class="pre">make<T>()</span> <span class="pre">)</span> <span class="pre">)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">T</span></tt> shall be a complete type.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">T></span>
@@ -701,17 +723,14 @@
</tr>
<tr><td><tt class="docutils literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">T></span>
<span class="pre">struct</span>
-<span class="pre">has_nothrow_move_assign;</span></tt></td>
-<td><tt class="docutils literal"><span class="pre">T</span></tt> is a type with a move
-assignment operator that is
-known not to throw any
-exceptions.</td>
+<span class="pre">nothrow_move_assignable;</span></tt></td>
+<td><tt class="docutils literal"><span class="pre">noexcept(</span> <span class="pre">*(T*)0</span> <span class="pre">=</span> <span class="pre">make<T></span> <span class="pre">)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">T</span></tt> shall be a complete type.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">T></span>
<span class="pre">struct</span> <span class="pre">has_copy_constructor;</span></tt></td>
-<td><tt class="docutils literal"><span class="pre">T</span></tt> has a copy
-constructor (12.8).</td>
+<td><tt class="docutils literal"><span class="pre">T</span></tt> has a copy constructor
+(12.8).</td>
<td><tt class="docutils literal"><span class="pre">T</span></tt> shall be a complete type, an
array of unknown bound, or
(possibly cv-qualified) <tt class="docutils literal"><span class="pre">void.</span></tt></td>
@@ -719,8 +738,8 @@
<tr><td><tt class="docutils literal"><span class="pre">template</span> <span class="pre"><class</span> <span class="pre">T></span>
<span class="pre">struct</span>
<span class="pre">has_default_constructor;</span></tt></td>
-<td><tt class="docutils literal"><span class="pre">T</span></tt> has a default
-constructor (12.1).</td>
+<td><tt class="docutils literal"><span class="pre">T</span></tt> has a default constructor
+(12.1).</td>
<td><tt class="docutils literal"><span class="pre">T</span></tt> shall be a complete type, an
array of unknown bound, or
(possibly cv-qualified) <tt class="docutils literal"><span class="pre">void.</span></tt></td>
@@ -737,7 +756,7 @@
</table>
</div>
<div class="section" id="deque-modifiers-deque-modifiers">
-<h2><a class="toc-backref" href="#id23">23.3.2.3 deque modifiers [deque.modifiers]</a></h2>
+<h2><a class="toc-backref" href="#id22">23.3.2.3 deque modifiers [deque.modifiers]</a></h2>
<p>Context:</p>
<pre class="literal-block">
iterator insert(const_iterator position, const T& x);
@@ -776,15 +795,15 @@
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="#id24">23.3.6.2 vector capacity [vector.capacity]</a></h2>
+<h2><a class="toc-backref" href="#id23">23.3.6.2 vector capacity [vector.capacity]</a></h2>
<p>Context:</p>
<pre class="literal-block">
void reserve(size_type n);
</pre>
<p>Remove paragraph 2:</p>
<blockquote>
-<span class="del">2 Requires: If value_type has a move constructor, that constructor shall
-not throw any exceptions.</span></blockquote>
+<span class="del">2 Requires: If value_type has a move constructor, that
+constructor shall not throw any exceptions.</span></blockquote>
<p>Change paragraph 3 as follows:</p>
<blockquote>
<span class="del">3</span><span class="ins">2</span> Effects: A directive that informs a vector of a planned change in
@@ -809,7 +828,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="#id25">23.3.6.4 vector modifiers [vector.modifiers]</a></h2>
+<h2><a class="toc-backref" href="#id24">23.3.6.4 vector modifiers [vector.modifiers]</a></h2>
<p>Change the section as follows:</p>
<blockquote>
<pre class="literal-block">
@@ -876,7 +895,7 @@
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<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>
+static checking: a <tt class="docutils literal"><span class="pre">noexcept(true)</span></tt> function can call a <tt class="docutils literal"><span class="pre">noexcept(false)</span></tt>
function without causing the program to become ill-formed or
generating a diagnostic. Generating a diagnostic in such cases
can, of course, be implemented by any compiler as a matter of QOI.</td></tr>
Modified: sandbox/committee/rvalue_ref/rst.css
==============================================================================
--- sandbox/committee/rvalue_ref/rst.css (original)
+++ sandbox/committee/rvalue_ref/rst.css 2009-10-22 17:54:47 EDT (Thu, 22 Oct 2009)
@@ -283,3 +283,11 @@
.ins {background-color:#A0FFA0;border-bottom: 1px solid black}
.del {background-color:#FFA0A0;text-decoration:line-through}
+
+.grammar { padding: 0 }
+
+.sub {
+ position: relative;
+ bottom: -0.5em;
+ font-size: 0.8em;
+}
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