mirror of
https://github.com/boostorg/optional.git
synced 2025-07-29 12:07:21 +02:00
Improved documentation. Added some noexcept.
This commit is contained in:
@ -28,8 +28,36 @@
|
||||
Guarantees</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
Because of the current implementation (see <a class="link" href="implementation_notes.html" title="Implementation Notes">Implementation
|
||||
Notes</a>), all of the assignment methods:
|
||||
This library assumes that <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
destructor does not throw exceptions. If it does, the behaviour of many operations
|
||||
on <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> is
|
||||
undefined.
|
||||
</p>
|
||||
<p>
|
||||
The following mutating operations never throw exceptions:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
In addition, the following constructors and the destructor never throw exceptions:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">optional</span><span class="special">()</span>
|
||||
<span class="keyword">noexcept</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Regarding the following assignment functions:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
@ -52,88 +80,71 @@
|
||||
<span class="special">)</span> </code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&)</span></code>
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Can only <span class="emphasis"><em>guarantee</em></span> the <span class="underline">basic
|
||||
exception safety</span>: The lvalue optional is left <span class="underline">uninitialized</span>
|
||||
if an exception is thrown (any previous value is <span class="emphasis"><em>first</em></span>
|
||||
destroyed using <code class="computeroutput"><span class="identifier">T</span><span class="special">::~</span><span class="identifier">T</span><span class="special">()</span></code>)
|
||||
They forward calls to the corresponding <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
constructors or assignments (depending on whether the optional object is initialized
|
||||
or not); so if both <code class="computeroutput"><span class="identifier">T</span></code>'s constructor
|
||||
and the assignment provide strong exception safety guarantee, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>'s assignment
|
||||
also provides strong exception safety guarantee; otherwise we only get the
|
||||
basic guarantee. Additionally, if both involved <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
constructor and the assignment never throw, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>'s
|
||||
assignment also never throws.
|
||||
</p>
|
||||
<p>
|
||||
On the other hand, the <span class="emphasis"><em>uninitializing</em></span> methods:
|
||||
Unless <code class="computeroutput"><span class="identifier">T</span></code>'s constructor or assignment
|
||||
throws, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> does
|
||||
not throw anything else on its own. A throw during assignment never changes
|
||||
the initialization state of any optional object involved:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">none_t</span> <span class="special">)</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span><span class="special">()</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Provide the no-throw guarantee (assuming a no-throw <code class="computeroutput"><span class="identifier">T</span><span class="special">::~</span><span class="identifier">T</span><span class="special">()</span></code>)
|
||||
</p>
|
||||
<p>
|
||||
However, since <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code>
|
||||
itself doesn't throw any exceptions, the only source for exceptions here are
|
||||
<code class="computeroutput"><span class="identifier">T</span></code>'s constructor, so if you
|
||||
know the exception guarantees for <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span> <span class="special">(</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span></code>, you
|
||||
know that <code class="computeroutput"><span class="identifier">optional</span></code>'s assignment
|
||||
and reset has the same guarantees.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="comment">//</span>
|
||||
<span class="comment">// Case 1: Exception thrown during assignment.</span>
|
||||
<span class="comment">//</span>
|
||||
<span class="identifier">T</span> <span class="identifier">v0</span><span class="special">(</span><span class="number">123</span><span class="special">);</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt0</span><span class="special">(</span><span class="identifier">v0</span><span class="special">);</span>
|
||||
<pre class="programlisting"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt1</span><span class="special">(</span><span class="identifier">val1</span><span class="special">);</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt2</span><span class="special">(</span><span class="identifier">val2</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt1</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt2</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">v1</span><span class="special">(</span><span class="number">456</span><span class="special">);</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt1</span><span class="special">(</span><span class="identifier">v1</span><span class="special">);</span>
|
||||
<span class="identifier">opt0</span> <span class="special">=</span> <span class="identifier">opt1</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// If no exception was thrown, assignment succeeded.</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span> <span class="special">*</span><span class="identifier">opt0</span> <span class="special">==</span> <span class="identifier">v1</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">opt1</span> <span class="special">=</span> <span class="identifier">opt2</span><span class="special">;</span> <span class="comment">// throws</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(...)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// If any exception was thrown, 'opt0' is reset to uninitialized.</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span> <span class="special">!</span><span class="identifier">opt0</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="comment">//</span>
|
||||
<span class="comment">// Case 2: Exception thrown during reset(v)</span>
|
||||
<span class="comment">//</span>
|
||||
<span class="identifier">T</span> <span class="identifier">v0</span><span class="special">(</span><span class="number">123</span><span class="special">);</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt</span><span class="special">(</span><span class="identifier">v0</span><span class="special">);</span>
|
||||
<span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">T</span> <span class="identifier">v1</span><span class="special">(</span><span class="number">456</span><span class="special">);</span>
|
||||
<span class="identifier">opt</span><span class="special">.</span><span class="identifier">reset</span> <span class="special">(</span> <span class="identifier">v1</span> <span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// If no exception was thrown, reset succeeded.</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span> <span class="special">*</span><span class="identifier">opt</span> <span class="special">==</span> <span class="identifier">v1</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(...)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// If any exception was thrown, 'opt' is reset to uninitialized.</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span> <span class="special">!</span><span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt1</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt2</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
This also applies to move assignments/constructors. However, move operations
|
||||
are made no-throw more often.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="boost_optional.exception_safety_guarantees.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.exception_safety_guarantees.swap"></a></span><a class="link" href="exception_safety_guarantees.html#boost_optional.exception_safety_guarantees.swap">Swap</a>
|
||||
</h4>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&,</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="special">)</span></code> has the same exception guarantee as <code class="computeroutput"><span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&,</span><span class="identifier">T</span><span class="special">&)</span></code>
|
||||
when both optionals are initialized. If only one of the optionals is initialized,
|
||||
it gives the same <span class="emphasis"><em>basic</em></span> exception guarantee as <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span></code> (since
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span><span class="special">()</span></code> doesn't throw). If none of the optionals
|
||||
is initialized, it has no-throw guarantee since it is a no-op.
|
||||
Unless <code class="computeroutput"><span class="identifier">swap</span></code> on optional is
|
||||
customized, its primary implementation forwards calls to <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
<code class="computeroutput"><span class="identifier">swap</span></code> or move constructor (depending
|
||||
on the initialization state of the optional objects). Thus, if both <code class="computeroutput"><span class="identifier">T</span></code>'s <code class="computeroutput"><span class="identifier">swap</span></code>
|
||||
and move constructor never throw, <code class="computeroutput"><span class="identifier">swap</span></code>
|
||||
on <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> never
|
||||
throws. similarly, if both <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
<code class="computeroutput"><span class="identifier">swap</span></code> and move constructor offer
|
||||
strong guarantee, <code class="computeroutput"><span class="identifier">swap</span></code> on
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> also
|
||||
offers a strong guarantee.
|
||||
</p>
|
||||
<p>
|
||||
In case <code class="computeroutput"><span class="identifier">swap</span></code> on optional is
|
||||
customized, the call to <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
move constructor are replaced with the calls to <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
default constructor followed by <code class="computeroutput"><span class="identifier">swap</span></code>.
|
||||
(This is more useful on older compilers that do not support move semantics,
|
||||
when one wants to acheive stronger exception safety guarantees.) In this case
|
||||
the exception safety guarantees for <code class="computeroutput"><span class="identifier">swap</span></code>
|
||||
are reliant on the guarantees of <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
<code class="computeroutput"><span class="identifier">swap</span></code> and default constructor
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
|
Reference in New Issue
Block a user