Merge branch 'feature/move-semantics' into develop

Conflicts:
	doc/html/index.html
	include/boost/optional/optional.hpp
	test/Jamfile.v2
This commit is contained in:
Andrzej Krzemienski
2014-04-29 01:24:10 +02:00
16 changed files with 1656 additions and 71 deletions

View File

@ -72,7 +72,7 @@
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
<a name="reference_optional_constructor"></a><div class="blockquote"><blockquote class="blockquote"><p> <a name="reference_optional_constructor"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">();</span></code> <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span></code>
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
@ -82,11 +82,7 @@
<span class="bold"><strong>Postconditions:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is <span class="underline">uninitialized</span>. <span class="bold"><strong>Postconditions:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is <span class="underline">uninitialized</span>.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Nothing. <span class="bold"><strong>Notes:</strong></span> T's default constructor <span class="underline">is not</span> called.
</li>
<li class="listitem">
Notes: T's default constructor <span class="underline">is not</span>
called.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Example:</strong></span> <span class="bold"><strong>Example:</strong></span>
@ -99,7 +95,7 @@
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
<a name="reference_optional_constructor_none_t"></a><div class="blockquote"><blockquote class="blockquote"><p> <a name="reference_optional_constructor_none_t"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">none_t</span> <span class="special">);</span></code> <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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><span class="special">;</span></code>
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
@ -109,9 +105,6 @@
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is <span class="underline">uninitialized</span>. <span class="bold"><strong>Postconditions:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is <span class="underline">uninitialized</span>.
</li> </li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Nothing.
</li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Notes:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>'s <span class="bold"><strong>Notes:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>'s
default constructor <span class="underline">is not</span> called. default constructor <span class="underline">is not</span> called.
@ -132,12 +125,16 @@
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span> </code><span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span></code> <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span> </code><span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span></code>
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">is_copy_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
is <code class="computeroutput"><span class="keyword">true</span></code>.
</li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Directly-Constructs an <code class="computeroutput"><span class="identifier">optional</span></code>. <span class="bold"><strong>Effect:</strong></span> Directly-Constructs an <code class="computeroutput"><span class="identifier">optional</span></code>.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is <span class="underline">initialized</span> <span class="bold"><strong>Postconditions:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is <span class="underline">initialized</span>
and its value is a<span class="emphasis"><em>copy</em></span> of <code class="computeroutput"><span class="identifier">v</span></code>. and its value is a <span class="emphasis"><em>copy</em></span> of <code class="computeroutput"><span class="identifier">v</span></code>.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span> <span class="bold"><strong>Throws:</strong></span> Whatever <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span>
@ -193,6 +190,58 @@
</pre> </pre>
</li> </li>
</ul></div> </ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_constructor_move_value"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span> </code><span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span>
<span class="identifier">v</span> <span class="special">)</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">is_move_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
is <code class="computeroutput"><span class="keyword">true</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Directly-Move-Constructs an <code class="computeroutput"><span class="identifier">optional</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is <span class="underline">initialized</span>
and its value is move-constructed from <code class="computeroutput"><span class="identifier">v</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever <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="special">&amp;&amp;</span>
<span class="special">)</span></code> throws.
</li>
<li class="listitem">
<span class="bold"><strong>Notes: </strong></span> <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="special">&amp;&amp;</span>
<span class="special">)</span></code> is called.
</li>
<li class="listitem">
<span class="bold"><strong>Exception Safety:</strong></span> Exceptions can only
be thrown during <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="special">&amp;&amp;</span> <span class="special">);</span></code>
in that case, the state of <code class="computeroutput"><span class="identifier">v</span></code>
is determined by exception safety 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="special">&amp;&amp;)</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v1</span><span class="special">,</span> <span class="identifier">v2</span><span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">v1</span><span class="special">));</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">v2</span> <span class="special">)</span> <span class="special">;</span>
</pre>
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">ref</span> <span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
<span class="bold"><strong>Notes:</strong></span> This constructor is deleted
</li></ul></div>
<p> <p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
@ -229,6 +278,10 @@
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span> </code><span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">optional</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">);</span></code> <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span> </code><span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">optional</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">);</span></code>
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">is_copy_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
is <code class="computeroutput"><span class="keyword">true</span></code>.
</li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Copy-Constructs an <code class="computeroutput"><span class="identifier">optional</span></code>. <span class="bold"><strong>Effect:</strong></span> Copy-Constructs an <code class="computeroutput"><span class="identifier">optional</span></code>.
</li> </li>
@ -320,6 +373,116 @@
</pre> </pre>
</li> </li>
</ul></div> </ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_move_constructor_optional"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span> </code><span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">optional</span><span class="special">&amp;&amp;</span> <span class="identifier">rhs</span>
<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">(</span></code><span class="emphasis"><em>see below</em></span><code class="computeroutput"><span class="special">);</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">is_move_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code>
is <code class="computeroutput"><span class="keyword">true</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Move-constructs an <code class="computeroutput"><span class="identifier">optional</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initialized and its value is move constructed from <code class="computeroutput"><span class="identifier">rhs</span></code>;
else <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is uninitialized.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever <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="special">&amp;&amp;</span>
<span class="special">)</span></code> throws.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, <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="special">&amp;&amp;</span> <span class="special">)</span></code>
is called. The expression inside <code class="computeroutput"><span class="keyword">noexcept</span></code>
is equivalent to <code class="computeroutput"><span class="identifier">is_nothrow_move_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Exception Safety:</strong></span> Exceptions can only
be thrown during <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="special">&amp;&amp;</span> <span class="special">);</span></code>
in that case, <code class="computeroutput"><span class="identifier">rhs</span></code> remains
initialized and the value of <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code> is determined by exception safety
of <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="special">&amp;&amp;)</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span> <span class="identifier">uninit</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(!</span><span class="identifier">uninit</span><span class="special">);</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span> <span class="identifier">uinit2</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">uninit</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">uninit2</span> <span class="special">==</span> <span class="identifier">uninit</span> <span class="special">);</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span> <span class="identifier">init</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">uniqye_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="keyword">new</span> <span class="identifier">T</span><span class="special">(</span><span class="number">2</span><span class="special">))</span> <span class="special">);</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">**</span><span class="identifier">init</span> <span class="special">==</span> <span class="identifier">T</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span> <span class="identifier">init2</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">init</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">init</span> <span class="special">);</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">*</span><span class="identifier">init</span> <span class="special">==</span> <span class="keyword">nullptr</span> <span class="special">);</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">init2</span> <span class="special">);</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">**</span><span class="identifier">init2</span> <span class="special">==</span> <span class="identifier">T</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
</pre>
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">optional</span> <span class="special">&amp;&amp;</span>
<span class="identifier">rhs</span> <span class="special">);</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Move-Constructs an <code class="computeroutput"><span class="identifier">optional</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initialized and its value is another reference to the same object referenced
by <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code>;
else <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is uninitialized.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Nothing.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, both <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
and <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code>
will reefer to the same object (they alias).
</li>
<li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;&gt;</span> <span class="identifier">uninit</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(!</span><span class="identifier">uninit</span><span class="special">);</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;&gt;</span> <span class="identifier">uinit2</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">uninit</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">uninit2</span> <span class="special">==</span> <span class="identifier">uninit</span> <span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">v</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">T</span><span class="special">(</span><span class="number">2</span><span class="special">))</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;&gt;</span> <span class="identifier">init</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">*</span><span class="identifier">init</span> <span class="special">==</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_ptr</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;&gt;</span> <span class="identifier">init2</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">init</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">*</span><span class="identifier">init2</span> <span class="special">==</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span>
<span class="special">*</span><span class="identifier">v</span> <span class="special">=</span> <span class="number">3</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">**</span><span class="identifier">init</span> <span class="special">==</span> <span class="number">3</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">**</span><span class="identifier">init2</span> <span class="special">==</span> <span class="number">3</span> <span class="special">)</span> <span class="special">;</span>
</pre>
</li>
</ul></div>
<p> <p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
@ -368,6 +531,52 @@
</pre> </pre>
</li> </li>
</ul></div> </ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_move_constructor_other_optional"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span></code>
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</span>
<span class="identifier">rhs</span> <span class="special">);</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Move-constructs an <code class="computeroutput"><span class="identifier">optional</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initialized and its value is move constructed from <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code>; else <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is uninitialized.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span>
<span class="identifier">U</span><span class="special">&amp;&amp;</span>
<span class="special">)</span></code> throws.
</li>
<li class="listitem">
<span class="bold"><strong>Notes: </strong></span> <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span>
<span class="identifier">U</span><span class="special">&amp;&amp;</span>
<span class="special">)</span></code> is called if <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, which requires a valid conversion from <code class="computeroutput"><span class="identifier">U</span></code>
to <code class="computeroutput"><span class="identifier">T</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Exception Safety:</strong></span> Exceptions can only
be thrown during <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span> <span class="identifier">U</span><span class="special">&amp;&amp;</span> <span class="special">);</span></code>
in that case, <code class="computeroutput"><span class="identifier">rhs</span></code> remains
initialized and the value of <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code> is determined by exception safety
guarantee of <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span> <span class="identifier">U</span><span class="special">&amp;&amp;</span> <span class="special">)</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">x</span><span class="special">(</span><span class="number">123.4</span><span class="special">);</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">*</span><span class="identifier">x</span> <span class="special">==</span> <span class="number">123.4</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">y</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">x</span><span class="special">))</span> <span class="special">;</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="special">*</span><span class="identifier">y</span> <span class="special">==</span> <span class="number">123</span> <span class="special">)</span> <span class="special">;</span>
</pre>
</li>
</ul></div>
<p> <p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
@ -511,6 +720,66 @@
</pre> </pre>
</li> </li>
</ul></div> </ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_operator_move_equal_value"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">rhs</span>
<span class="special">)</span> <span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Moves the value <code class="computeroutput"><span class="identifier">rhs</span></code> to an <code class="computeroutput"><span class="identifier">optional</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Postconditions: </strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized and its value is moved
from <code class="computeroutput"><span class="identifier">rhs</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="special">)</span></code>
or <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="special">&amp;&amp;)</span></code> throws.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> was initialized, <code class="computeroutput"><span class="identifier">T</span></code>'s
move-assignment operator is used, otherwise, its move-constructor is used.
</li>
<li class="listitem">
<span class="bold"><strong>Exception Safety:</strong></span> In the event of an exception,
the initialization state of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is unchanged and its value unspecified
as far as <code class="computeroutput"><span class="identifier">optional</span></code> is concerned
(it is up to <code class="computeroutput"><span class="identifier">T</span></code>'s <code class="computeroutput"><span class="keyword">operator</span><span class="special">=()</span></code>).
If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initially uninitialized and <code class="computeroutput"><span class="identifier">T</span></code>'s
<span class="emphasis"><em>move constructor</em></span> fails, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is left properly uninitialized.
</li>
<li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">x</span><span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">def</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">;</span>
<span class="identifier">T</span> <span class="identifier">y1</span><span class="special">,</span> <span class="identifier">y2</span><span class="special">,</span> <span class="identifier">yR</span><span class="special">;</span>
<span class="identifier">def</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">y1</span><span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">*</span><span class="identifier">def</span> <span class="special">==</span> <span class="identifier">yR</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">opt</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">y2</span><span class="special">)</span> <span class="special">;</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">yR</span> <span class="special">)</span> <span class="special">;</span>
</pre>
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span>
<span class="identifier">rhs</span> <span class="special">)</span>
<span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
<span class="bold"><strong>Notes:</strong></span> This assignment operator is deleted.
</li></ul></div>
<p> <p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
@ -613,6 +882,75 @@
</pre> </pre>
</li> </li>
</ul></div> </ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_operator_move_equal_optional"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&amp;&amp;</span> <span class="identifier">rhs</span>
<span class="special">)</span> <span class="keyword">noexcept</span><span class="special">(</span></code><span class="emphasis"><em>see below</em></span><code class="computeroutput"><span class="special">);</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Move-assigns another <code class="computeroutput"><span class="identifier">optional</span></code> to an <code class="computeroutput"><span class="identifier">optional</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initialized and its value is moved from <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code>, <code class="computeroutput"><span class="identifier">rhs</span></code>
remains initialized; else <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is uninitialized.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="keyword">operator</span><span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span>
<span class="special">)</span></code> or <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="special">&amp;&amp;</span>
<span class="special">)</span></code> throws.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> If both <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> and <code class="computeroutput"><span class="identifier">rhs</span></code>
are initially initialized, <code class="computeroutput"><span class="identifier">T</span></code>'s
<span class="emphasis"><em>move assignment operator</em></span> is used. If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is
initially initialized but <code class="computeroutput"><span class="identifier">rhs</span></code>
is uninitialized, <code class="computeroutput"><span class="identifier">T</span></code>'s [destructor]
is called. If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initially uninitialized but <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, <code class="computeroutput"><span class="identifier">T</span></code>'s <span class="emphasis"><em>move
constructor</em></span> is called. The expression inside <code class="computeroutput"><span class="keyword">noexcept</span></code>
is equivalent to <code class="computeroutput"><span class="identifier">is_nothrow_move_constructible</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span>
<span class="special">&amp;&amp;</span> <span class="identifier">is_nothrow_move_assignable</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Exception Safety:</strong></span> In the event of an exception,
the initialization state of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is unchanged and its value unspecified
as far as optional is concerned (it is up to <code class="computeroutput"><span class="identifier">T</span></code>'s
<code class="computeroutput"><span class="keyword">operator</span><span class="special">=()</span></code>).
If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initially uninitialized and <code class="computeroutput"><span class="identifier">T</span></code>'s
<span class="emphasis"><em>move constructor</em></span> fails, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is left properly uninitialized.
</li>
<li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt</span><span class="special">(</span><span class="identifier">T</span><span class="special">(</span><span class="number">2</span><span class="special">))</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">def</span> <span class="special">;</span>
<span class="identifier">opt</span> <span class="special">=</span> <span class="identifier">def</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">def</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</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="special">*</span><span class="identifier">opt</span> <span class="special">==</span> <span class="identifier">T</span><span class="special">(</span><span class="number">2</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
</pre>
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</span> <span class="special">&amp;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;&amp;&amp;</span>
<span class="identifier">rhs</span> <span class="special">)</span>
<span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Same as <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span></code>.
</li></ul></div>
<p> <p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
@ -673,6 +1011,59 @@
</pre> </pre>
</li> </li>
</ul></div> </ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_operator_move_equal_other_optional"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</span>
<span class="identifier">rhs</span> <span class="special">)</span>
<span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Effect:</strong></span> Move-assigns another convertible
optional to an optional.
</li>
<li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initialized and its value is moved from the value of <code class="computeroutput"><span class="identifier">rhs</span></code>;
else <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is uninitialized.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">U</span><span class="special">&amp;&amp;</span> <span class="special">)</span></code>
or <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span> <span class="identifier">U</span><span class="special">&amp;&amp;</span> <span class="special">)</span></code>
throws.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> If both <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> and <code class="computeroutput"><span class="identifier">rhs</span></code>
are initially initialized, <code class="computeroutput"><span class="identifier">T</span></code>'s
<span class="emphasis"><em>assignment operator</em></span> (from <code class="computeroutput"><span class="identifier">U</span><span class="special">&amp;&amp;</span></code>) is used. If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initially initialized but <code class="computeroutput"><span class="identifier">rhs</span></code> is uninitialized, <code class="computeroutput"><span class="identifier">T</span></code>'s
<span class="emphasis"><em>destructor</em></span> is called. If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initially uninitialized but <code class="computeroutput"><span class="identifier">rhs</span></code> is initialized, <code class="computeroutput"><span class="identifier">T</span></code>'s
<span class="emphasis"><em>converting constructor</em></span> (from <code class="computeroutput"><span class="identifier">U</span><span class="special">&amp;&amp;</span></code>) is called.
</li>
<li class="listitem">
<span class="bold"><strong>Exception Safety:</strong></span> In the event of an exception,
the initialization state of <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is unchanged and its value unspecified
as far as optional is concerned (it is up to <code class="computeroutput"><span class="identifier">T</span></code>'s
<code class="computeroutput"><span class="keyword">operator</span><span class="special">=()</span></code>).
If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initially uninitialized and <code class="computeroutput"><span class="identifier">T</span></code>'s
converting constructor fails, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is left properly uninitialized.
</li>
<li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span><span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt0</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">opt1</span><span class="special">;</span>
<span class="identifier">opt1</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">opt0</span><span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">*</span><span class="identifier">opt1</span> <span class="special">==</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
</pre>
</li>
</ul></div>
<p> <p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
@ -768,7 +1159,7 @@
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Requirements:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized <span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Returns:</strong></span> A reference to the contained <span class="bold"><strong>Returns:</strong></span> A reference to the contained
@ -870,7 +1261,7 @@
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Requirements: </strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized <span class="bold"><strong>Requires: </strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Returns:</strong></span> <span class="underline">The</span> <span class="bold"><strong>Returns:</strong></span> <span class="underline">The</span>
@ -956,7 +1347,7 @@
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Requirements: </strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized. <span class="bold"><strong>Requires: </strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Returns:</strong></span> A pointer to the contained value. <span class="bold"><strong>Returns:</strong></span> A pointer to the contained value.
@ -1008,16 +1399,13 @@
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p> </p>
<a name="reference_optional_operator_not"></a><div class="blockquote"><blockquote class="blockquote"><p> <a name="reference_optional_operator_not"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="keyword">bool</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">!()</span> <span class="special">;</span></code> <code class="computeroutput"><span class="keyword">bool</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">noexcept</span> <span class="special">;</span></code>
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Returns:</strong></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is uninitialized, <code class="computeroutput"><span class="keyword">true</span></code>; <span class="bold"><strong>Returns:</strong></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is uninitialized, <code class="computeroutput"><span class="keyword">true</span></code>;
else <code class="computeroutput"><span class="keyword">false</span></code>. else <code class="computeroutput"><span class="keyword">false</span></code>.
</li> </li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Nothing.
</li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Notes:</strong></span> This operator is provided for those <span class="bold"><strong>Notes:</strong></span> This operator is provided for those
compilers which can't use the <span class="emphasis"><em>unspecified-bool-type operator</em></span> compilers which can't use the <span class="emphasis"><em>unspecified-bool-type operator</em></span>
@ -1291,7 +1679,7 @@
<a name="reference_swap_optional_optional"></a><div class="blockquote"><blockquote class="blockquote"><p> <a name="reference_swap_optional_optional"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">swap</span> <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">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span>
<span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">y</span> <span class="special">);</span></code> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span></code>
</p></blockquote></div> </p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
@ -1308,19 +1696,21 @@
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Throws:</strong></span> If both are initialized, whatever <span class="bold"><strong>Throws:</strong></span> If both are initialized, whatever
<code class="computeroutput"><span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;,</span><span class="identifier">T</span><span class="special">&amp;)</span></code> <code class="computeroutput"><span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;,</span><span class="identifier">T</span><span class="special">&amp;)</span></code>
throws. If only one is initialized, whatever <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">&amp;</span> <span class="special">)</span></code> throws. throws. If only one is initialized, whatever <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="special">&amp;&amp;</span>
<span class="special">)</span></code> throws.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Notes:</strong></span> If both are initialized, <code class="computeroutput"><span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;,</span><span class="identifier">T</span><span class="special">&amp;)</span></code> <span class="bold"><strong>Notes:</strong></span> If both are initialized, <code class="computeroutput"><span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;,</span><span class="identifier">T</span><span class="special">&amp;)</span></code>
is used unqualified but with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">swap</span></code> is used unqualified but with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">swap</span></code>
introduced in scope. If only one is initialized, <code class="computeroutput"><span class="identifier">T</span><span class="special">::~</span><span class="identifier">T</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span> introduced in scope. If only one is initialized, <code class="computeroutput"><span class="identifier">T</span><span class="special">::~</span><span class="identifier">T</span><span class="special">()</span></code> and <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">&amp;</span> <span class="special">)</span></code> <span class="identifier">T</span><span class="special">&amp;&amp;</span>
is called. <span class="special">)</span></code> is called.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Exception Safety:</strong></span> If both are initialized, <span class="bold"><strong>Exception Safety:</strong></span> If both are initialized,
this operation has the exception safety guarantees of <code class="computeroutput"><span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;,</span><span class="identifier">T</span><span class="special">&amp;)</span></code>. this operation has the exception safety guarantees of <code class="computeroutput"><span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;,</span><span class="identifier">T</span><span class="special">&amp;)</span></code>.
If only one is initialized, it has the same basic guarantee as <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span></code>. If only one is initialized, it has the same basic guarantee as <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span>
<span class="special">)</span></code>.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Example:</strong></span> <span class="bold"><strong>Example:</strong></span>

View File

@ -68,6 +68,22 @@
than the reference itself. than the reference itself.
</li> </li>
</ul></div> </ul></div>
<h4>
<a name="boost_optional.optional_references.h0"></a>
<span class="phrase"><a name="boost_optional.optional_references.rvalue_references"></a></span><a class="link" href="optional_references.html#boost_optional.optional_references.rvalue_references">Rvalue
references</a>
</h4>
<p>
Rvalue references and lvalue references to const have the ability in C++ to
extend the life time of a temporary they bind to. Optional references do not
have this capability, therefore to avoid surprising effects it is not possible
to initialize an optional references from a temporary. Optional rvalue references
are disabled altogether. Also, the initialization and assignment of an optional
reference to const from rvalue reference is disabled.
</p>
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// legal</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;&gt;</span> <span class="identifier">oi</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// illegal</span>
</pre>
</div> </div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td> <td align="left"></td>

View File

@ -37,19 +37,25 @@
<span class="comment">// (If T is of reference type, the parameters and results by reference are by value)</span> <span class="comment">// (If T is of reference type, the parameters and results by reference are by value)</span>
<span class="identifier">optional</span> <span class="special">()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">optional</span> <span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_none_t"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_none_t"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_move_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="comment">// [new in 1.34]</span> <span class="comment">// [new in 1.34]</span>
<span class="identifier">optional</span> <span class="special">(</span> <span class="keyword">bool</span> <span class="identifier">condition</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_bool_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">optional</span> <span class="special">(</span> <span class="keyword">bool</span> <span class="identifier">condition</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_bool_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&amp;&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">noexcept</span><span class="special">(</span><span class="emphasis"><em>see below</em></span><span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_move_constructor_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_other_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_other_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_move_constructor_other_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
@ -58,10 +64,16 @@
<span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_move_equal_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&amp;&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">noexcept</span><span class="special">(</span><span class="emphasis"><em>see below</em></span><span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_move_equal_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_other_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_other_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_move_equal_other_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
@ -83,7 +95,7 @@
<span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_bool"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_bool"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_not"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_not"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="comment">// deprecated methods</span> <span class="comment">// deprecated methods</span>

View File

@ -163,7 +163,7 @@
</div> </div>
</div> </div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: April 26, 2014 at 08:58:33 GMT</small></p></td> <td align="left"><p><small>Last revised: April 28, 2014 at 23:21:56 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td> <td align="right"><div class="copyright-footer"></div></td>
</tr></table> </tr></table>
<hr> <hr>

View File

@ -22,19 +22,25 @@
// (If T is of reference type, the parameters and results by reference are by value) // (If T is of reference type, the parameters and results by reference are by value)
optional () ; ``[link reference_optional_constructor __GO_TO__]`` optional () noexcept ; ``[link reference_optional_constructor __GO_TO__]``
optional ( none_t ) ; ``[link reference_optional_constructor_none_t __GO_TO__]`` optional ( none_t ) noexcept ; ``[link reference_optional_constructor_none_t __GO_TO__]``
optional ( T const& v ) ; ``[link reference_optional_constructor_value __GO_TO__]`` optional ( T const& v ) ; ``[link reference_optional_constructor_value __GO_TO__]``
optional ( T&& v ) ; ``[link reference_optional_constructor_move_value __GO_TO__]``
// [new in 1.34] // [new in 1.34]
optional ( bool condition, T const& v ) ; ``[link reference_optional_constructor_bool_value __GO_TO__]`` optional ( bool condition, T const& v ) ; ``[link reference_optional_constructor_bool_value __GO_TO__]``
optional ( optional const& rhs ) ; ``[link reference_optional_constructor_optional __GO_TO__]`` optional ( optional const& rhs ) ; ``[link reference_optional_constructor_optional __GO_TO__]``
optional ( optional&& rhs ) noexcept(``['see below]``) ; ``[link reference_optional_move_constructor_optional __GO_TO__]``
template<class U> explicit optional ( optional<U> const& rhs ) ; ``[link reference_optional_constructor_other_optional __GO_TO__]`` template<class U> explicit optional ( optional<U> const& rhs ) ; ``[link reference_optional_constructor_other_optional __GO_TO__]``
template<class U> explicit optional ( optional<U>&& rhs ) ; ``[link reference_optional_move_constructor_other_optional __GO_TO__]``
template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ; ``[link reference_optional_constructor_factory __GO_TO__]`` template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ; ``[link reference_optional_constructor_factory __GO_TO__]``
template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ; ``[link reference_optional_constructor_factory __GO_TO__]`` template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ; ``[link reference_optional_constructor_factory __GO_TO__]``
@ -43,10 +49,16 @@
optional& operator = ( T const& v ) ; ``[link reference_optional_operator_equal_value __GO_TO__]`` optional& operator = ( T const& v ) ; ``[link reference_optional_operator_equal_value __GO_TO__]``
optional& operator = ( T&& v ) ; ``[link reference_optional_operator_move_equal_value __GO_TO__]``
optional& operator = ( optional const& rhs ) ; ``[link reference_optional_operator_equal_optional __GO_TO__]`` optional& operator = ( optional const& rhs ) ; ``[link reference_optional_operator_equal_optional __GO_TO__]``
optional& operator = ( optional&& rhs ) noexcept(``['see below]``) ; ``[link reference_optional_operator_move_equal_optional __GO_TO__]``
template<class U> optional& operator = ( optional<U> const& rhs ) ; ``[link reference_optional_operator_equal_other_optional __GO_TO__]`` template<class U> optional& operator = ( optional<U> const& rhs ) ; ``[link reference_optional_operator_equal_other_optional __GO_TO__]``
template<class U> optional& operator = ( optional<U>&& rhs ) ; ``[link reference_optional_operator_move_equal_other_optional __GO_TO__]``
template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ; ``[link reference_optional_operator_equal_factory __GO_TO__]`` template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ; ``[link reference_optional_operator_equal_factory __GO_TO__]``
template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ; ``[link reference_optional_operator_equal_factory __GO_TO__]`` template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ; ``[link reference_optional_operator_equal_factory __GO_TO__]``
@ -68,7 +80,7 @@
explicit operator bool() const ; ``[link reference_optional_operator_bool __GO_TO__]`` explicit operator bool() const ; ``[link reference_optional_operator_bool __GO_TO__]``
bool operator!() const ; ``[link reference_optional_operator_not __GO_TO__]`` bool operator!() const noexcept ; ``[link reference_optional_operator_not __GO_TO__]``
// deprecated methods // deprecated methods
@ -151,12 +163,11 @@ __SPACE__
[#reference_optional_constructor] [#reference_optional_constructor]
[: `optional<T>::optional();`] [: `optional<T>::optional() noexcept;`]
* [*Effect:] Default-Constructs an `optional`. * [*Effect:] Default-Constructs an `optional`.
* [*Postconditions:] `*this` is [_uninitialized]. * [*Postconditions:] `*this` is [_uninitialized].
* [*Throws:] Nothing. * [*Notes:] T's default constructor [_is not] called.
* Notes: T's default constructor [_is not] called.
* [*Example:] * [*Example:]
`` ``
optional<T> def ; optional<T> def ;
@ -167,11 +178,10 @@ __SPACE__
[#reference_optional_constructor_none_t] [#reference_optional_constructor_none_t]
[: `optional<T>::optional( none_t );`] [: `optional<T>::optional( none_t ) noexcept;`]
* [*Effect:] Constructs an `optional` uninitialized. * [*Effect:] Constructs an `optional` uninitialized.
* [*Postconditions:] `*this` is [_uninitialized]. * [*Postconditions:] `*this` is [_uninitialized].
* [*Throws:] Nothing.
* [*Notes:] `T`'s default constructor [_is not] called. The expression * [*Notes:] `T`'s default constructor [_is not] called. The expression
`boost::none` denotes an instance of `boost::none_t` that can be used as `boost::none` denotes an instance of `boost::none_t` that can be used as
the parameter. the parameter.
@ -188,8 +198,9 @@ __SPACE__
[: `optional<T `['(not a ref)]`>::optional( T const& v )`] [: `optional<T `['(not a ref)]`>::optional( T const& v )`]
* [*Requires:] `is_copy_constructible<T>::value` is `true`.
* [*Effect:] Directly-Constructs an `optional`. * [*Effect:] Directly-Constructs an `optional`.
* [*Postconditions:] `*this` is [_initialized] and its value is a['copy] * [*Postconditions:] `*this` is [_initialized] and its value is a ['copy]
of `v`. of `v`.
* [*Throws:] Whatever `T::T( T const& )` throws. * [*Throws:] Whatever `T::T( T const& )` throws.
* [*Notes: ] `T::T( T const& )` is called. * [*Notes: ] `T::T( T const& )` is called.
@ -220,6 +231,33 @@ assert ( *opt == v ) ;
assert (*opt == v); assert (*opt == v);
`` ``
__SPACE__
[#reference_optional_constructor_move_value]
[: `optional<T `['(not a ref)]`>::optional( T&& v )`]
* [*Requires:] `is_move_constructible<T>::value` is `true`.
* [*Effect:] Directly-Move-Constructs an `optional`.
* [*Postconditions:] `*this` is [_initialized] and its value is move-constructed from `v`.
* [*Throws:] Whatever `T::T( T&& )` throws.
* [*Notes: ] `T::T( T&& )` is called.
* [*Exception Safety:] Exceptions can only be thrown during
`T::T( T&& );` in that case, the state of `v` is determined by exception safety guarantees for `T::T(T&&)`.
* [*Example:]
``
T v1, v2;
optional<T> opt(std::move(v1));
assert ( *opt == v2 ) ;
``
__SPACE__
[: `optional<T&>::optional( T&& ref ) = delete`]
* [*Notes:] This constructor is deleted
__SPACE__ __SPACE__
[#reference_optional_constructor_bool_value] [#reference_optional_constructor_bool_value]
@ -243,6 +281,7 @@ __SPACE__
[: `optional<T `['(not a ref)]`>::optional( optional const& rhs );`] [: `optional<T `['(not a ref)]`>::optional( optional const& rhs );`]
* [*Requires:] `is_copy_constructible<T>::value` is `true`.
* [*Effect:] Copy-Constructs an `optional`. * [*Effect:] Copy-Constructs an `optional`.
* [*Postconditions:] If rhs is initialized, `*this` is initialized and * [*Postconditions:] If rhs is initialized, `*this` is initialized and
its value is a ['copy] of the value of `rhs`; else `*this` is uninitialized. its value is a ['copy] of the value of `rhs`; else `*this` is uninitialized.
@ -299,6 +338,70 @@ assert ( *init2 == 3 ) ;
__SPACE__ __SPACE__
[#reference_optional_move_constructor_optional]
[: `optional<T `['(not a ref)]`>::optional( optional&& rhs ) noexcept(`['see below]`);`]
* [*Requires:] `is_move_constructible<T>::value` is `true`.
* [*Effect:] Move-constructs an `optional`.
* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and
its value is move constructed from `rhs`; else `*this` is uninitialized.
* [*Throws:] Whatever `T::T( T&& )` throws.
* [*Notes:] If `rhs` is initialized, `T::T( T && )` is called. The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible<T>::value`.
* [*Exception Safety:] Exceptions can only be thrown during
`T::T( T&& );` in that case, `rhs` remains initialized and the value of `*rhs` is determined by exception safety of `T::T(T&&)`.
* [*Example:]
``
optional<std::unique_ptr<T>> uninit ;
assert (!uninit);
optional<std::unique_ptr<T>> uinit2 ( std::move(uninit) ) ;
assert ( uninit2 == uninit );
optional<std::unique_ptr<T>> init( std::uniqye_ptr<T>(new T(2)) );
assert ( **init == T(2) ) ;
optional<std::unique_ptr<T>> init2 ( std::move(init) ) ;
assert ( init );
assert ( *init == nullptr );
assert ( init2 );
assert ( **init2 == T(2) ) ;
``
__SPACE__
[: `optional<T&>::optional( optional && rhs );`]
* [*Effect:] Move-Constructs an `optional`.
* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and its
value is another reference to the same object referenced by `*rhs`; else
`*this` is uninitialized.
* [*Throws:] Nothing.
* [*Notes:] If `rhs` is initialized, both `*this` and `*rhs` will reefer to the
same object (they alias).
* [*Example:]
``
optional<std::unique_ptr<T>&> uninit ;
assert (!uninit);
optional<std::unique_ptr<T>&> uinit2 ( std::move(uninit) ) ;
assert ( uninit2 == uninit );
std::unique_ptr<T> v(new T(2)) ;
optional<std::unique_ptr<T>&> init(v);
assert ( *init == v ) ;
optional<std::unique_ptr<T>&> init2 ( std::move(init) ) ;
assert ( *init2 == v ) ;
*v = 3 ;
assert ( **init == 3 ) ;
assert ( **init2 == 3 ) ;
``
__SPACE__
[#reference_optional_constructor_other_optional] [#reference_optional_constructor_other_optional]
[: `template<U> explicit optional<T` ['(not a ref)]`>::optional( optional<U> const& rhs );`] [: `template<U> explicit optional<T` ['(not a ref)]`>::optional( optional<U> const& rhs );`]
@ -323,6 +426,30 @@ assert( *y == 123 ) ;
__SPACE__ __SPACE__
[#reference_optional_move_constructor_other_optional]
[: `template<U> explicit optional<T` ['(not a ref)]`>::optional( optional<U>&& rhs );`]
* [*Effect:] Move-constructs an `optional`.
* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and its
value is move constructed from `*rhs`; else `*this` is
uninitialized.
* [*Throws:] Whatever `T::T( U&& )` throws.
* [*Notes: ] `T::T( U&& )` is called if `rhs` is initialized, which requires a
valid conversion from `U` to `T`.
* [*Exception Safety:] Exceptions can only be thrown during `T::T( U&& );`
in that case, `rhs` remains initialized and the value of `*rhs` is determined by exception safety guarantee of `T::T( U&& )`.
* [*Example:]
``
optional<double> x(123.4);
assert ( *x == 123.4 ) ;
optional<int> y(std::move(x)) ;
assert( *y == 123 ) ;
``
__SPACE__
[#reference_optional_constructor_factory] [#reference_optional_constructor_factory]
[: `template<InPlaceFactory> explicit optional<T` ['(not a ref)]`>::optional( InPlaceFactory const& f );`] [: `template<InPlaceFactory> explicit optional<T` ['(not a ref)]`>::optional( InPlaceFactory const& f );`]
@ -408,6 +535,42 @@ c = 4 ;
assert ( *opt == 4 ) ; assert ( *opt == 4 ) ;
`` ``
__SPACE__
[#reference_optional_operator_move_equal_value]
[: `optional& optional<T` ['(not a ref)]`>::operator= ( T&& rhs ) ;`]
* [*Effect:] Moves the value `rhs` to an `optional`.
* [*Postconditions: ] `*this` is initialized and its value is moved from `rhs`.
* [*Throws:] Whatever `T::operator=( T&& )` or `T::T(T &&)` throws.
* [*Notes:] If `*this` was initialized, `T`'s move-assignment operator is used,
otherwise, its move-constructor is used.
* [*Exception Safety:] In the event of an exception, the initialization
state of `*this` is unchanged and its value unspecified as far as `optional`
is concerned (it is up to `T`'s `operator=()`). If `*this` is initially
uninitialized and `T`'s ['move constructor] fails, `*this` is left properly
uninitialized.
* [*Example:]
``
T x;
optional<T> def ;
optional<T> opt(x) ;
T y1, y2, yR;
def = std::move(y1) ;
assert ( *def == yR ) ;
opt = std::move(y2) ;
assert ( *opt == yR ) ;
``
__SPACE__
[: `optional<T&>& optional<T&>::operator= ( T&& rhs ) = delete;`]
* [*Notes:] This assignment operator is deleted.
__SPACE__ __SPACE__
[#reference_optional_operator_equal_optional] [#reference_optional_operator_equal_optional]
@ -471,6 +634,42 @@ assert ( *ora == 4 ) ;
__SPACE__ __SPACE__
[#reference_optional_operator_move_equal_optional]
[: `optional& optional<T` ['(not a ref)]`>::operator= ( optional&& rhs ) noexcept(`['see below]`);`]
* [*Effect:] Move-assigns another `optional` to an `optional`.
* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and
its value is moved from `*rhs`, `rhs` remains initialized; else `*this` is uninitialized.
* [*Throws:] Whatever `T::operator( T&& )` or `T::T( T && )` throws.
* [*Notes:] If both `*this` and `rhs` are initially initialized, `T`'s
['move assignment operator] is used. If `*this` is initially initialized but `rhs` is
uninitialized, `T`'s [destructor] is called. If `*this` is initially uninitialized
but `rhs` is initialized, `T`'s ['move constructor] is called. The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value`.
* [*Exception Safety:] In the event of an exception, the initialization state of
`*this` is unchanged and its value unspecified as far as optional is concerned
(it is up to `T`'s `operator=()`). If `*this` is initially uninitialized and
`T`'s ['move constructor] fails, `*this` is left properly uninitialized.
* [*Example:]
``
optional<T> opt(T(2)) ;
optional<T> def ;
opt = def ;
assert ( def ) ;
assert ( opt ) ;
assert ( *opt == T(2) ) ;
``
__SPACE__
[: `optional<T&> & optional<T&>::operator= ( optional<T&>&& rhs ) ;`]
* [*Effect:] Same as `optional<T&>::operator= ( optional<T&> const& rhs )`.
__SPACE__
[#reference_optional_operator_equal_other_optional] [#reference_optional_operator_equal_other_optional]
[: `template<U> optional& optional<T` ['(not a ref)]`>::operator= ( optional<U> const& rhs ) ;`] [: `template<U> optional& optional<T` ['(not a ref)]`>::operator= ( optional<U> const& rhs ) ;`]
@ -502,6 +701,37 @@ assert ( *opt1 == static_cast<U>(v) ) ;
__SPACE__ __SPACE__
[#reference_optional_operator_move_equal_other_optional]
[: `template<U> optional& optional<T` ['(not a ref)]`>::operator= ( optional<U>&& rhs ) ;`]
* [*Effect:] Move-assigns another convertible optional to an optional.
* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and
its value is moved from the value of `rhs`; else
`*this` is uninitialized.
* [*Throws:] Whatever `T::operator=( U&& )` or `T::T( U&& )` throws.
* [*Notes:] If both `*this` and `rhs` are initially initialized, `T`'s
[' assignment operator] (from `U&&`) is used. If `*this` is initially initialized
but `rhs` is uninitialized, `T`'s ['destructor] is called. If `*this` is
initially uninitialized but `rhs` is initialized, `T`'s ['converting constructor]
(from `U&&`) is called.
* [*Exception Safety:] In the event of an exception, the initialization state
of `*this` is unchanged and its value unspecified as far as optional is
concerned (it is up to `T`'s `operator=()`). If `*this` is initially
uninitialized and `T`'s converting constructor fails, `*this` is left properly
uninitialized.
* [*Example:]
``
T v;
optional<T> opt0(v);
optional<U> opt1;
opt1 = std::move(opt0) ;
assert ( *opt1 == static_cast<U>(v) ) ;
``
__SPACE__
[#reference_optional_operator_equal_factory] [#reference_optional_operator_equal_factory]
[: `template<InPlaceFactory> optional<T>& optional<T` ['(not a ref)]`>::operator=( InPlaceFactory const& f );`] [: `template<InPlaceFactory> optional<T>& optional<T` ['(not a ref)]`>::operator=( InPlaceFactory const& f );`]
@ -543,7 +773,7 @@ __SPACE__
[: `inline T const& get ( optional<T` ['(not a ref)]`> const& ) ;`] [: `inline T const& get ( optional<T` ['(not a ref)]`> const& ) ;`]
[: `inline T& get ( optional<T` ['(not a ref)]`> &) ;`] [: `inline T& get ( optional<T` ['(not a ref)]`> &) ;`]
* [*Requirements:] `*this` is initialized * [*Requires:] `*this` is initialized
* [*Returns:] A reference to the contained value * [*Returns:] A reference to the contained value
* [*Throws:] Nothing. * [*Throws:] Nothing.
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. * [*Notes:] The requirement is asserted via `BOOST_ASSERT()`.
@ -593,7 +823,7 @@ __SPACE__
[: `inline T const& get ( optional<T&> const& ) ;`] [: `inline T const& get ( optional<T&> const& ) ;`]
[: `inline T& get ( optional<T&> &) ;`] [: `inline T& get ( optional<T&> &) ;`]
* [*Requirements: ] `*this` is initialized * [*Requires: ] `*this` is initialized
* [*Returns:] [_The] reference contained. * [*Returns:] [_The] reference contained.
* [*Throws:] Nothing. * [*Throws:] Nothing.
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. * [*Notes:] The requirement is asserted via `BOOST_ASSERT()`.
@ -641,7 +871,7 @@ __SPACE__
[: `T const* optional<T` ['(not a ref)]`>::operator ->() const ;`] [: `T const* optional<T` ['(not a ref)]`>::operator ->() const ;`]
[: `T* optional<T` ['(not a ref)]`>::operator ->() ;`] [: `T* optional<T` ['(not a ref)]`>::operator ->() ;`]
* [*Requirements: ] `*this` is initialized. * [*Requires: ] `*this` is initialized.
* [*Returns:] A pointer to the contained value. * [*Returns:] A pointer to the contained value.
* [*Throws:] Nothing. * [*Throws:] Nothing.
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. * [*Notes:] The requirement is asserted via `BOOST_ASSERT()`.
@ -675,10 +905,9 @@ __SPACE__
[#reference_optional_operator_not] [#reference_optional_operator_not]
[: `bool optional<T>::operator!() ;`] [: `bool optional<T>::operator!() noexcept ;`]
* [*Returns:] If `*this` is uninitialized, `true`; else `false`. * [*Returns:] If `*this` is uninitialized, `true`; else `false`.
* [*Throws:] Nothing.
* [*Notes:] This operator is provided for those compilers which can't * [*Notes:] This operator is provided for those compilers which can't
use the ['unspecified-bool-type operator] in certain boolean contexts. use the ['unspecified-bool-type operator] in certain boolean contexts.
* [*Example:] * [*Example:]
@ -852,21 +1081,21 @@ __SPACE__
[#reference_swap_optional_optional] [#reference_swap_optional_optional]
[: `void swap ( optional<T>& x, optional<T>& y );`] [: `void swap ( optional<T>& x, optional<T>& y ) ;`]
* [*Effect:] If both `x` and `y` are initialized, calls `swap(*x,*y)` * [*Effect:] If both `x` and `y` are initialized, calls `swap(*x,*y)`
using `std::swap`. If only one is initialized, say `x`, calls: using `std::swap`. If only one is initialized, say `x`, calls:
`y.reset(*x); x.reset();` If none is initialized, does nothing. `y.reset(*x); x.reset();` If none is initialized, does nothing.
* [*Postconditions:] The states of `x` and `y` interchanged. * [*Postconditions:] The states of `x` and `y` interchanged.
* [*Throws:] If both are initialized, whatever `swap(T&,T&)` throws. If only * [*Throws:] If both are initialized, whatever `swap(T&,T&)` throws. If only
one is initialized, whatever `T::T ( T const& )` throws. one is initialized, whatever `T::T ( T&& )` throws.
* [*Notes:] If both are initialized, `swap(T&,T&)` is used unqualified but * [*Notes:] If both are initialized, `swap(T&,T&)` is used unqualified but
with `std::swap` introduced in scope. with `std::swap` introduced in scope.
If only one is initialized, `T::~T()` and `T::T( T const& )` is called. If only one is initialized, `T::~T()` and `T::T( T&& )` is called.
* [*Exception Safety:] If both are initialized, this operation has the * [*Exception Safety:] If both are initialized, this operation has the
exception safety guarantees of `swap(T&,T&)`. exception safety guarantees of `swap(T&,T&)`.
If only one is initialized, it has the same basic guarantee as If only one is initialized, it has the same basic guarantee as
`optional<T>::reset( T const& )`. `optional<T>::operator= ( T&& )`.
* [*Example:] * [*Example:]
`` ``
T x(12); T x(12);

View File

@ -21,6 +21,13 @@ will nonetheless reefer to the same object.
* Value-access will actually provide access to the referenced object * Value-access will actually provide access to the referenced object
rather than the reference itself. rather than the reference itself.
[heading Rvalue references]
Rvalue references and lvalue references to const have the ability in C++ to extend the life time of a temporary they bind to. Optional references do not have this capability, therefore to avoid surprising effects it is not possible to initialize an optional references from a temporary. Optional rvalue references are disabled altogether. Also, the initialization and assignment of an optional reference to const from rvalue reference is disabled.
const int& i = 1; // legal
optional<const int&> oi = 1; // illegal
[endsect] [endsect]
[section Rebinding semantics for assignment of optional references] [section Rebinding semantics for assignment of optional references]

View File

@ -21,22 +21,34 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/type.hpp> #include <boost/type.hpp>
#include <boost/type_traits/alignment_of.hpp> #include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/has_nothrow_constructor.hpp> #include <boost/type_traits/has_nothrow_constructor.hpp>
#include <boost/type_traits/type_with_alignment.hpp> #include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include <boost/type_traits/is_reference.hpp> #include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_rvalue_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp> #include <boost/mpl/not.hpp>
#include <boost/detail/reference_content.hpp> #include <boost/detail/reference_content.hpp>
#include <boost/move/utility.hpp>
#include <boost/none.hpp> #include <boost/none.hpp>
#include <boost/utility/swap.hpp>
#include <boost/utility/addressof.hpp> #include <boost/utility/addressof.hpp>
#include <boost/utility/compare_pointees.hpp> #include <boost/utility/compare_pointees.hpp>
#include <boost/utility/in_place_factory.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/utility/explicit_operator_bool.hpp> #include <boost/utility/explicit_operator_bool.hpp>
#include <boost/utility/in_place_factory.hpp>
#include <boost/utility/swap.hpp>
#include <boost/optional/optional_fwd.hpp> #include <boost/optional/optional_fwd.hpp>
@ -132,22 +144,39 @@ struct types_when_isnt_ref
{ {
typedef T const& reference_const_type ; typedef T const& reference_const_type ;
typedef T & reference_type ; typedef T & reference_type ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef T && rval_reference_type ;
static rval_reference_type move(reference_type r) { return boost::move(r); }
#endif
typedef T const* pointer_const_type ; typedef T const* pointer_const_type ;
typedef T * pointer_type ; typedef T * pointer_type ;
typedef T const& argument_type ; typedef T const& argument_type ;
} ; } ;
template<class T> template<class T>
struct types_when_is_ref struct types_when_is_ref
{ {
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ; typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
typedef raw_type& reference_const_type ; typedef raw_type& reference_const_type ;
typedef raw_type& reference_type ; typedef raw_type& reference_type ;
typedef raw_type* pointer_const_type ; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef raw_type* pointer_type ; typedef raw_type&& rval_reference_type ;
typedef raw_type& argument_type ; static reference_type move(reference_type r) { return r; }
#endif
typedef raw_type* pointer_const_type ;
typedef raw_type* pointer_type ;
typedef raw_type& argument_type ;
} ; } ;
template <class To, class From>
void prevent_binding_rvalue_ref_to_optional_lvalue_ref()
{
BOOST_STATIC_ASSERT_MSG(
!boost::is_lvalue_reference<To>::value || !boost::is_rvalue_reference<From>::value,
"binding rvalue references to optional lvalue references is disallowed");
}
struct optional_tag {} ; struct optional_tag {} ;
template<class T> template<class T>
@ -183,6 +212,9 @@ class optional_base : public optional_tag
protected: protected:
typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ; typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ;
typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ; typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ;
#endif
typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ; typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ; typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ; typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ;
@ -208,6 +240,17 @@ class optional_base : public optional_tag
construct(val); construct(val);
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// move-construct an optional<T> initialized from an rvalue-ref to 'val'.
// Can throw if T::T(T&&) does
optional_base ( rval_reference_type val )
:
m_initialized(false)
{
construct( boost::move(val) );
}
#endif
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>. // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
// Can throw if T::T(T const&) does // Can throw if T::T(T const&) does
optional_base ( bool cond, argument_type val ) optional_base ( bool cond, argument_type val )
@ -228,7 +271,29 @@ class optional_base : public optional_tag
construct(rhs.get_impl()); construct(rhs.get_impl());
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Creates a deep move of another optional<T>
// Can throw if T::T(T&&) does
optional_base ( optional_base&& rhs )
:
m_initialized(false)
{
if ( rhs.is_initialized() )
construct( boost::move(rhs.get_impl()) );
}
#endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class Expr, class PtrExpr>
explicit optional_base ( Expr&& expr, PtrExpr const* tag )
:
m_initialized(false)
{
construct(boost::forward<Expr>(expr),tag);
}
#else
// This is used for both converting and in-place constructions. // This is used for both converting and in-place constructions.
// Derived classes use the 'tag' to select the appropriate // Derived classes use the 'tag' to select the appropriate
// implementation (the correct 'construct()' overload) // implementation (the correct 'construct()' overload)
@ -240,6 +305,7 @@ class optional_base : public optional_tag
construct(expr,tag); construct(expr,tag);
} }
#endif
// No-throw (assuming T::~T() doesn't) // No-throw (assuming T::~T() doesn't)
@ -261,6 +327,24 @@ class optional_base : public optional_tag
} }
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Assigns from another optional<T> (deep-moves the rhs value)
void assign ( optional_base&& rhs )
{
if (is_initialized())
{
if ( rhs.is_initialized() )
assign_value(boost::move(rhs.get_impl()), is_reference_predicate() );
else destroy();
}
else
{
if ( rhs.is_initialized() )
construct(boost::move(rhs.get_impl()));
}
}
#endif
// Assigns from another _convertible_ optional<U> (deep-copies the rhs value) // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
template<class U> template<class U>
void assign ( optional<U> const& rhs ) void assign ( optional<U> const& rhs )
@ -278,6 +362,26 @@ class optional_base : public optional_tag
} }
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
template<class U>
void assign ( optional<U>&& rhs )
{
typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
if (is_initialized())
{
if ( rhs.is_initialized() )
assign_value(static_cast<ref_type>(rhs.get()), is_reference_predicate() );
else destroy();
}
else
{
if ( rhs.is_initialized() )
construct(static_cast<ref_type>(rhs.get()));
}
}
#endif
// Assigns from a T (deep-copies the rhs value) // Assigns from a T (deep-copies the rhs value)
void assign ( argument_type val ) void assign ( argument_type val )
{ {
@ -286,18 +390,40 @@ class optional_base : public optional_tag
else construct(val); else construct(val);
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Assigns from a T (deep-moves the rhs value)
void assign ( rval_reference_type val )
{
if (is_initialized())
assign_value( boost::move(val), is_reference_predicate() );
else construct( boost::move(val) );
}
#endif
// Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
// No-throw (assuming T::~T() doesn't) // No-throw (assuming T::~T() doesn't)
void assign ( none_t ) { destroy(); } void assign ( none_t ) { destroy(); }
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class Expr, class ExprPtr>
void assign_expr ( Expr&& expr, ExprPtr const* tag )
{
if (is_initialized())
assign_expr_to_initialized(boost::forward<Expr>(expr),tag);
else construct(boost::forward<Expr>(expr),tag);
}
#else
template<class Expr> template<class Expr>
void assign_expr ( Expr const& expr, Expr const* tag ) void assign_expr ( Expr const& expr, Expr const* tag )
{ {
if (is_initialized()) if (is_initialized())
assign_expr_to_initialized(expr,tag); assign_expr_to_initialized(expr,tag);
else construct(expr,tag); else construct(expr,tag);
} }
#endif
#endif #endif
public : public :
@ -325,7 +451,50 @@ class optional_base : public optional_tag
m_initialized = true ; m_initialized = true ;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
void construct ( rval_reference_type val )
{
new (m_storage.address()) internal_type( types::move(val) ) ;
m_initialized = true ;
}
#endif
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Constructs in-place using the given factory
template<class Expr>
void construct ( Expr&& factory, in_place_factory_base const* )
{
BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
boost_optional_detail::construct<value_type>(factory, m_storage.address());
m_initialized = true ;
}
// Constructs in-place using the given typed factory
template<class Expr>
void construct ( Expr&& factory, typed_in_place_factory_base const* )
{
BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
factory.apply(m_storage.address()) ;
m_initialized = true ;
}
template<class Expr>
void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
{
destroy();
construct(factory,tag);
}
// Constructs in-place using the given typed factory
template<class Expr>
void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
{
destroy();
construct(factory,tag);
}
#else
// Constructs in-place using the given factory // Constructs in-place using the given factory
template<class Expr> template<class Expr>
void construct ( Expr const& factory, in_place_factory_base const* ) void construct ( Expr const& factory, in_place_factory_base const* )
@ -360,7 +529,31 @@ class optional_base : public optional_tag
} }
#endif #endif
// Constructs using any expression implicitely convertible to the single argument #endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Constructs using any expression implicitly convertible to the single argument
// of a one-argument T constructor.
// Converting constructions of optional<T> from optional<U> uses this function with
// 'Expr' being of type 'U' and relying on a converting constructor of T from U.
template<class Expr>
void construct ( Expr&& expr, void const* )
{
new (m_storage.address()) internal_type(boost::forward<Expr>(expr)) ;
m_initialized = true ;
}
// Assigns using a form any expression implicitly convertible to the single argument
// of a T's assignment operator.
// Converting assignments of optional<T> from optional<U> uses this function with
// 'Expr' being of type 'U' and relying on a converting assignment of T from U.
template<class Expr>
void assign_expr_to_initialized ( Expr&& expr, void const* )
{
assign_value(boost::forward<Expr>(expr), is_reference_predicate());
}
#else
// Constructs using any expression implicitly convertible to the single argument
// of a one-argument T constructor. // of a one-argument T constructor.
// Converting constructions of optional<T> from optional<U> uses this function with // Converting constructions of optional<T> from optional<U> uses this function with
// 'Expr' being of type 'U' and relying on a converting constructor of T from U. // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
@ -371,7 +564,7 @@ class optional_base : public optional_tag
m_initialized = true ; m_initialized = true ;
} }
// Assigns using a form any expression implicitely convertible to the single argument // Assigns using a form any expression implicitly convertible to the single argument
// of a T's assignment operator. // of a T's assignment operator.
// Converting assignments of optional<T> from optional<U> uses this function with // Converting assignments of optional<T> from optional<U> uses this function with
// 'Expr' being of type 'U' and relying on a converting assignment of T from U. // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
@ -381,6 +574,8 @@ class optional_base : public optional_tag
assign_value(expr, is_reference_predicate()); assign_value(expr, is_reference_predicate());
} }
#endif
#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION #ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
// BCB5.64 (and probably lower versions) workaround. // BCB5.64 (and probably lower versions) workaround.
// The in-place factories are supported by means of catch-all constructors // The in-place factories are supported by means of catch-all constructors
@ -394,6 +589,20 @@ class optional_base : public optional_tag
// For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
// instead of choosing the wrong overload // instead of choosing the wrong overload
// //
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
template<class Expr>
void construct ( Expr&& expr, optional_tag const* )
{
if ( expr.is_initialized() )
{
// An exception can be thrown here.
// It it happens, THIS will be left uninitialized.
new (m_storage.address()) internal_type(types::move(expr.get())) ;
m_initialized = true ;
}
}
#else
// Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>) // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
template<class Expr> template<class Expr>
void construct ( Expr const& expr, optional_tag const* ) void construct ( Expr const& expr, optional_tag const* )
@ -407,9 +616,14 @@ class optional_base : public optional_tag
} }
} }
#endif #endif
#endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; } void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
void assign_value ( argument_type val, is_reference_tag ) { construct(val); } void assign_value ( argument_type val, is_reference_tag ) { construct(val); }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast<rval_reference_type>(val); }
void assign_value ( rval_reference_type val, is_reference_tag ) { construct( static_cast<rval_reference_type>(val) ); }
#endif
void destroy() void destroy()
{ {
@ -483,22 +697,32 @@ class optional : public optional_detail::optional_base<T>
typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ; typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ;
typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ; typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ;
typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ; typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ;
#endif
typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ; typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ; typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ; typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ;
// Creates an optional<T> uninitialized. // Creates an optional<T> uninitialized.
// No-throw // No-throw
optional() : base() {} optional() BOOST_NOEXCEPT : base() {}
// Creates an optional<T> uninitialized. // Creates an optional<T> uninitialized.
// No-throw // No-throw
optional( none_t none_ ) : base(none_) {} optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
// Creates an optional<T> initialized with 'val'. // Creates an optional<T> initialized with 'val'.
// Can throw if T::T(T const&) does // Can throw if T::T(T const&) does
optional ( argument_type val ) : base(val) {} optional ( argument_type val ) : base(val) {}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Creates an optional<T> initialized with 'move(val)'.
// Can throw if T::T(T &&) does
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
{optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();}
#endif
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
// Can throw if T::T(T const&) does // Can throw if T::T(T const&) does
optional ( bool cond, argument_type val ) : base(cond,val) {} optional ( bool cond, argument_type val ) : base(cond,val) {}
@ -517,39 +741,93 @@ class optional : public optional_detail::optional_base<T>
this->construct(rhs.get()); this->construct(rhs.get());
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Creates a deep move of another convertible optional<U>
// Requires a valid conversion from U to T.
// Can throw if T::T(U&&) does
template<class U>
explicit optional ( optional<U> && rhs )
:
base()
{
if ( rhs.is_initialized() )
this->construct( boost::move(rhs.get()) );
}
#endif
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
// Creates an optional<T> with an expression which can be either // Creates an optional<T> with an expression which can be either
// (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n); // (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
// (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n); // (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
// (c) Any expression implicitely convertible to the single type // (c) Any expression implicitly convertible to the single type
// of a one-argument T's constructor. // of a one-argument T's constructor.
// (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U> // (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
// even though explicit overloads are present for these. // even though explicit overloads are present for these.
// Depending on the above some T ctor is called. // Depending on the above some T ctor is called.
// Can throw is the resolved T ctor throws. // Can throw if the resolved T ctor throws.
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class Expr>
explicit optional ( Expr&& expr,
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
(boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value) ||
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value >::type* = 0
)
: base(boost::forward<Expr>(expr),boost::addressof(expr))
{optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();}
#else
template<class Expr> template<class Expr>
explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {} explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
#endif #endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES
#endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
// Creates a deep copy of another optional<T> // Creates a deep copy of another optional<T>
// Can throw if T::T(T const&) does // Can throw if T::T(T const&) does
optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {} optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Creates a deep move of another optional<T>
// Can throw if T::T(T&&) does
optional ( optional && rhs )
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
: base( boost::move(rhs) )
{}
#endif
// No-throw (assuming T::~T() doesn't) // No-throw (assuming T::~T() doesn't)
~optional() {} ~optional() {}
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
// Assigns from an expression. See corresponding constructor. // Assigns from an expression. See corresponding constructor.
// Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class Expr>
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value ||
boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value,
optional&
>::type
operator= ( Expr&& expr )
{
optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();
this->assign_expr(boost::forward<Expr>(expr),boost::addressof(expr));
return *this ;
}
#else
template<class Expr> template<class Expr>
optional& operator= ( Expr const& expr ) optional& operator= ( Expr const& expr )
{ {
this->assign_expr(expr,boost::addressof(expr)); this->assign_expr(expr,boost::addressof(expr));
return *this ; return *this ;
} }
#endif #endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES
#endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
// Assigns from another convertible optional<U> (converts && deep-copies the rhs value) // Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value)
// Requires a valid conversion from U to T. // Requires a valid conversion from U to T.
// Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
template<class U> template<class U>
@ -559,6 +837,18 @@ class optional : public optional_detail::optional_base<T>
return *this ; return *this ;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
// Requires a valid conversion from U to T.
// Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
template<class U>
optional& operator= ( optional<U> && rhs )
{
this->assign(boost::move(rhs));
return *this ;
}
#endif
// Assigns from another optional<T> (deep-copies the rhs value) // Assigns from another optional<T> (deep-copies the rhs value)
// Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
// (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw) // (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
@ -568,6 +858,16 @@ class optional : public optional_detail::optional_base<T>
return *this ; return *this ;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Assigns from another optional<T> (deep-moves the rhs value)
optional& operator= ( optional && rhs )
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
{
this->assign( static_cast<base &&>(rhs) ) ;
return *this ;
}
#endif
// Assigns from a T (deep-copies the rhs value) // Assigns from a T (deep-copies the rhs value)
// Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
optional& operator= ( argument_type val ) optional& operator= ( argument_type val )
@ -576,6 +876,15 @@ class optional : public optional_detail::optional_base<T>
return *this ; return *this ;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
// Assigns from a T (deep-moves the rhs value)
optional& operator= ( rval_reference_type val )
{
this->assign( boost::move(val) ) ;
return *this ;
}
#endif
// Assigns from a "none" // Assigns from a "none"
// Which destroys the current value, if any, leaving this UNINITIALIZED // Which destroys the current value, if any, leaving this UNINITIALIZED
// No-throw (assuming T::~T() doesn't) // No-throw (assuming T::~T() doesn't)
@ -586,10 +895,10 @@ class optional : public optional_detail::optional_base<T>
} }
void swap( optional & arg ) void swap( optional & arg )
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
{ {
// allow for Koenig lookup // allow for Koenig lookup
using boost::swap; boost::swap(*this, arg);
swap(*this, arg);
} }
@ -615,11 +924,19 @@ class optional : public optional_detail::optional_base<T>
reference_const_type operator *() const { return this->get() ; } reference_const_type operator *() const { return this->get() ; }
reference_type operator *() { return this->get() ; } reference_type operator *() { return this->get() ; }
bool operator!() const { return !this->is_initialized() ; } bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
BOOST_EXPLICIT_OPERATOR_BOOL() BOOST_EXPLICIT_OPERATOR_BOOL()
} ; } ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<class T>
class optional<T&&>
{
BOOST_STATIC_ASSERT_MSG(sizeof(T) == 0, "Optional rvalue references are illegal.");
} ;
#endif
// Returns optional<T>(v) // Returns optional<T>(v)
template<class T> template<class T>
inline inline
@ -919,6 +1236,37 @@ struct swap_selector<true>
} }
}; };
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<>
struct swap_selector<false>
{
template<class T>
static void optional_swap ( optional<T>& x, optional<T>& y )
//BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y)))
{
if(x)
{
if (y)
{
boost::swap(*x, *y);
}
else
{
y = boost::move(*x);
x = boost::none;
}
}
else
{
if (y)
{
x = boost::move(*y);
y = boost::none;
}
}
}
};
#else
template<> template<>
struct swap_selector<false> struct swap_selector<false>
{ {
@ -945,6 +1293,7 @@ struct swap_selector<false>
} }
} }
}; };
#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES
} // namespace optional_detail } // namespace optional_detail
@ -952,6 +1301,7 @@ template<class T>
struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ; struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ;
template<class T> inline void swap ( optional<T>& x, optional<T>& y ) template<class T> inline void swap ( optional<T>& x, optional<T>& y )
//BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y)))
{ {
optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y); optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
} }

View File

@ -11,15 +11,18 @@
// //
// Revisions: // Revisions:
// 10 May 2008 (added swap related forward declaration) Niels Dekker // 10 May 2008 (added swap related forward declaration) Niels Dekker
// 17 Apr 2014 (added noexcept) Andrzej Krzemienski
// //
#ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP #ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
#define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP #define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
#include <boost/config.hpp>
namespace boost { namespace boost {
template<class T> class optional ; template<class T> class optional ;
template<class T> void swap ( optional<T>& , optional<T>& ) ; template<class T> void swap ( optional<T>& , optional<T>& );
template<class T> struct optional_swap_should_use_default_constructor ; template<class T> struct optional_swap_should_use_default_constructor ;

View File

@ -21,6 +21,7 @@ import testing ;
[ run optional_test_ref.cpp ] [ run optional_test_ref.cpp ]
[ run optional_test_inplace.cpp ] [ run optional_test_inplace.cpp ]
[ run optional_test_io.cpp ] [ run optional_test_io.cpp ]
[ run optional_test_move.cpp ]
[ compile-fail optional_test_fail1.cpp ] [ compile-fail optional_test_fail1.cpp ]
[ compile-fail optional_test_fail3a.cpp ] [ compile-fail optional_test_fail3a.cpp ]
[ compile-fail optional_test_fail3b.cpp ] [ compile-fail optional_test_fail3b.cpp ]
@ -30,5 +31,11 @@ import testing ;
[ compile-fail optional_test_inplace_fail.cpp ] [ compile-fail optional_test_inplace_fail.cpp ]
[ compile-fail optional_test_inplace_fail2.cpp ] [ compile-fail optional_test_inplace_fail2.cpp ]
[ compile-fail optional_test_fail_implicit_bool_convert.cpp ] [ compile-fail optional_test_fail_implicit_bool_convert.cpp ]
[ compile-fail optional_test_fail_copying_a_moveable_type.cpp ]
[ compile-fail optional_test_fail_optional_rvalue_ref.cpp ]
[ compile-fail optional_test_ref_fail_init_from_Trefref.cpp ]
[ compile-fail optional_test_ref_fail_init_from_Urefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ]
; ;
} }

View File

@ -0,0 +1,36 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
class MoveOnly
{
public:
int val;
MoveOnly(int v) : val(v) {}
MoveOnly(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void test_copying_optional_with_noncopyable_T()
{
boost::optional<MoveOnly> opt1 ;
boost::optional<MoveOnly> opt2(opt1) ;
}

View File

@ -0,0 +1,19 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
boost::optional<int&&> oi;

414
test/optional_test_move.cpp Normal file
View File

@ -0,0 +1,414 @@
// Copyright (C) 2014 Andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
// Revisions:
//
#include<iostream>
#include<stdexcept>
#include<string>
#define BOOST_ENABLE_ASSERT_HANDLER
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
#include "boost/mpl/bool.hpp"
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
#include "boost/static_assert.hpp"
#include "boost/optional/optional.hpp"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "boost/none.hpp"
#include "boost/test/minimal.hpp"
#include "optional_test_common.cpp"
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
enum State
{
sDefaultConstructed,
sValueCopyConstructed,
sValueMoveConstructed,
sCopyConstructed,
sMoveConstructed,
sMoveAssigned,
sCopyAssigned,
sValueCopyAssigned,
sValueMoveAssigned,
sMovedFrom,
sIntConstructed
};
struct OracleVal
{
State s;
int i;
OracleVal(int i = 0) : s(sIntConstructed), i(i) {}
};
struct Oracle
{
State s;
OracleVal val;
Oracle() : s(sDefaultConstructed) {}
Oracle(const OracleVal& v) : s(sValueCopyConstructed), val(v) {}
Oracle(OracleVal&& v) : s(sValueMoveConstructed), val(std::move(v)) {v.s = sMovedFrom;}
Oracle(const Oracle& o) : s(sCopyConstructed), val(o.val) {}
Oracle(Oracle&& o) : s(sMoveConstructed), val(std::move(o.val)) {o.s = sMovedFrom;}
Oracle& operator=(const OracleVal& v) { s = sValueCopyAssigned; val = v; return *this; }
Oracle& operator=(OracleVal&& v) { s = sValueMoveAssigned; val = std::move(v); v.s = sMovedFrom; return *this; }
Oracle& operator=(const Oracle& o) { s = sCopyAssigned; val = o.val; return *this; }
Oracle& operator=(Oracle&& o) { s = sMoveAssigned; val = std::move(o.val); o.s = sMovedFrom; return *this; }
};
bool operator==( Oracle const& a, Oracle const& b ) { return a.val.i == b.val.i; }
bool operator!=( Oracle const& a, Oracle const& b ) { return a.val.i != b.val.i; }
void test_move_ctor_from_U()
{
optional<Oracle> o1 ((OracleVal()));
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed);
OracleVal v1;
optional<Oracle> o2 (v1);
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed );
BOOST_CHECK(v1.s == sIntConstructed);
optional<Oracle> o3 (boost::move(v1));
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed);
BOOST_CHECK(v1.s == sMovedFrom);
}
void test_move_ctor_form_T()
{
optional<Oracle> o1 ((Oracle()));
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sMoveConstructed);
Oracle v1;
optional<Oracle> o2 (v1);
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sCopyConstructed);
BOOST_CHECK(v1.s == sDefaultConstructed);
optional<Oracle> o3 (boost::move(v1));
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sMoveConstructed);
BOOST_CHECK(v1.s == sMovedFrom);
}
void test_move_ctor_from_optional_T()
{
optional<Oracle> o1;
optional<Oracle> o2(boost::move(o1));
BOOST_CHECK(!o1);
BOOST_CHECK(!o2);
optional<Oracle> o3((Oracle()));
optional<Oracle> o4(boost::move(o3));
BOOST_CHECK(o3);
BOOST_CHECK(o4);
BOOST_CHECK(o3->s == sMovedFrom);
BOOST_CHECK(o4->s == sMoveConstructed);
optional<Oracle> o5((optional<Oracle>()));
BOOST_CHECK(!o5);
optional<Oracle> o6((optional<Oracle>(Oracle())));
BOOST_CHECK(o6);
BOOST_CHECK(o6->s == sMoveConstructed);
optional<Oracle> o7(o6); // does copy ctor from non-const lvalue compile?
}
void test_move_assign_from_U()
{
optional<Oracle> o1 = boost::none; // test if additional ctors didn't break it
o1 = boost::none; // test if additional assignments didn't break it
o1 = OracleVal();
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sValueMoveConstructed);
o1 = OracleVal();
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sMoveAssigned);
OracleVal v1;
optional<Oracle> o2;
o2 = v1;
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sValueCopyConstructed);
BOOST_CHECK(v1.s == sIntConstructed);
o2 = v1;
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sCopyAssigned || o2->s == sMoveAssigned);
BOOST_CHECK(v1.s == sIntConstructed);
optional<Oracle> o3;
o3 = boost::move(v1);
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sValueMoveConstructed);
BOOST_CHECK(v1.s == sMovedFrom);
}
void test_move_assign_from_T()
{
optional<Oracle> o1;
o1 = Oracle();
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sMoveConstructed);
o1 = Oracle();
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sMoveAssigned);
Oracle v1;
optional<Oracle> o2;
o2 = v1;
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sCopyConstructed);
BOOST_CHECK(v1.s == sDefaultConstructed);
o2 = v1;
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sCopyAssigned);
BOOST_CHECK(v1.s == sDefaultConstructed);
optional<Oracle> o3;
o3 = boost::move(v1);
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sMoveConstructed);
BOOST_CHECK(v1.s == sMovedFrom);
}
void test_move_assign_from_optional_T()
{
optional<Oracle> o1;
optional<Oracle> o2;
o1 = optional<Oracle>();
BOOST_CHECK(!o1);
optional<Oracle> o3((Oracle()));
o1 = o3;
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sMoveConstructed);
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sCopyConstructed);
o2 = boost::move(o3);
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sMovedFrom);
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sMoveConstructed);
o2 = optional<Oracle>((Oracle()));
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sMoveAssigned);
}
class MoveOnly
{
public:
int val;
MoveOnly(int v) : val(v) {}
MoveOnly(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
friend class MoveOnlyB;
};
void test_with_move_only()
{
optional<MoveOnly> o1;
optional<MoveOnly> o2((MoveOnly(1)));
BOOST_CHECK(o2);
BOOST_CHECK(o2->val == 1);
optional<MoveOnly> o3 (boost::move(o1));
BOOST_CHECK(!o3);
optional<MoveOnly> o4 (boost::move(o2));
BOOST_CHECK(o4);
BOOST_CHECK(o4->val == 1);
BOOST_CHECK(o2);
BOOST_CHECK(o2->val == 0);
o3 = boost::move(o4);
BOOST_CHECK(o3);
BOOST_CHECK(o3->val == 1);
BOOST_CHECK(o4);
BOOST_CHECK(o4->val == 0);
}
class MoveOnlyB
{
public:
int val;
MoveOnlyB(int v) : val(v) {}
MoveOnlyB(MoveOnlyB&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnlyB&& rhs) {val = rhs.val; rhs.val = 0; }
MoveOnlyB(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnlyB(MoveOnlyB const&);
void operator=(MoveOnlyB const&);
MoveOnlyB(MoveOnly const&);
void operator=(MoveOnly const&);
};
void test_move_assign_from_optional_U()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnlyB> b1;
b1 = boost::move(a);
BOOST_CHECK(b1);
BOOST_CHECK(b1->val == 2);
BOOST_CHECK(a);
BOOST_CHECK(a->val == 0);
b1 = MoveOnly(4);
BOOST_CHECK(b1);
BOOST_CHECK(b1->val == 4);
}
void test_move_ctor_from_optional_U()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnlyB> b1(boost::move(a));
BOOST_CHECK(b1);
BOOST_CHECK(b1->val == 2);
BOOST_CHECK(a);
BOOST_CHECK(a->val == 0);
optional<MoveOnlyB> b2(( optional<MoveOnly>(( MoveOnly(4) )) ));
BOOST_CHECK(b2);
BOOST_CHECK(b2->val == 4);
}
void test_swap()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnly> b((MoveOnly(3)));
swap(a, b);
BOOST_CHECK(a->val == 3);
BOOST_CHECK(b->val == 2);
}
void test_optional_ref_to_movables()
{
MoveOnly m(3);
optional<MoveOnly&> orm = m;
orm->val = 2;
BOOST_CHECK(m.val == 2);
optional<MoveOnly&> orm2 = orm;
orm2->val = 1;
BOOST_CHECK(m.val == 1);
BOOST_CHECK(orm->val == 1);
optional<MoveOnly&> orm3 = boost::move(orm);
orm3->val = 4;
BOOST_CHECK(m.val == 4);
BOOST_CHECK(orm->val == 4);
BOOST_CHECK(orm2->val == 4);
}
// these 4 classes have different noexcept signatures in move operations
struct NothrowBoth {
NothrowBoth(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
void operator=(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
};
struct NothrowCtor {
NothrowCtor(NothrowCtor&&) BOOST_NOEXCEPT_IF(true) {};
void operator=(NothrowCtor&&) BOOST_NOEXCEPT_IF(false) {};
};
struct NothrowAssign {
NothrowAssign(NothrowAssign&&) BOOST_NOEXCEPT_IF(false) {};
void operator=(NothrowAssign&&) BOOST_NOEXCEPT_IF(true) {};
};
struct NothrowNone {
NothrowNone(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
void operator=(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
};
#ifndef BOOST_NO_NOEXCEPT
void test_noexcept() // this is a compile-time test
{
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowBoth> >::value);
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<optional<NothrowBoth> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowBoth>()));
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowCtor> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowCtor> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowCtor>()));
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowAssign> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowAssign> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowAssign>()));
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowNone> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowNone> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowNone>()));
}
#endif // !defned BOOST_NO_NOEXCEPT
#endif
int test_main( int, char* [] )
{
try
{
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
test_move_ctor_from_U();
test_move_ctor_form_T();
test_move_ctor_from_optional_T();
test_move_ctor_from_optional_U();
test_move_assign_from_U();
test_move_assign_from_T();
test_move_assign_from_optional_T();
test_move_assign_from_optional_U();
test_with_move_only();
test_optional_ref_to_movables();
test_swap();
#endif
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return 0;
}

View File

@ -0,0 +1,26 @@
// Copyright (C) 2014, andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_assign_from_Trefref()
{
boost::optional<const int&> opt;
opt = int(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@ -0,0 +1,26 @@
// Copyright (C) 2014, andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_assign_from_Urefref()
{
boost::optional<const int&> opt;
opt = long(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@ -0,0 +1,25 @@
// Copyright (C) 2014, andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_init_from_Trefref()
{
boost::optional<const int&> opt = int(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@ -0,0 +1,25 @@
// Copyright (C) 2014, andrzej Krzemienski.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_init_from_Urefref()
{
boost::optional<const int&> opt = long(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif