<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">

<style type="text/css">
pre {margin-left:20pt; }
pre > i {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }


</style>

<title>Rvalue reference overloads for optional</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"> </script>
<script type="text/javascript">$(function() {
    var next_id = 0
    function find_id(node) {
        // Look down the first children of 'node' until we find one
        // with an id. If we don't find one, give 'node' an id and
        // return that.
        var cur = node[0];
        while (cur) {
            if (cur.id) return curid;
            if (cur.tagName == 'A' && cur.name)
                return cur.name;
            cur = cur.firstChild;
        };
        // No id.
        node.attr('id', 'gensection-' + next_id++);
        return node.attr('id');
    };

    // Put a table of contents in the #toc nav.

    // This is a list of <ol> elements, where toc[N] is the list for
    // the current sequence of <h(N+2)> tags. When a header of an
    // existing level is encountered, all higher levels are popped,
    // and an <li> is appended to the level
    var toc = [$("<ol/>")];
    $(':header').not('h1').each(function() {
        var header = $(this);
        // For each <hN> tag, add a link to the toc at the appropriate
        // level.  When toc is one element too short, start a new list
        var levels = {H2: 0, H3: 1, H4: 2, H5: 3, H6: 4};
        var level = levels[this.tagName];
        if (typeof level == 'undefined') {
            throw 'Unexpected tag: ' + this.tagName;
        }
        // Truncate to the new level.
        toc.splice(level + 1, toc.length);
        if (toc.length < level) {
            // Omit TOC entries for skipped header levels.
            return;
        }
        if (toc.length == level) {
            // Add a <ol> to the previous level's last <li> and push
            // it into the array.
            var ol = $('<ol/>')
            toc[toc.length - 1].children().last().append(ol);
            toc.push(ol);
        }
        var header_text = header.text();
        toc[toc.length - 1].append(
            $('<li/>').append($('<a href="#' + find_id(header) + '"/>')
                              .text(header_text)));
    });
    $('#toc').append(toc[0]);
})
</script>
</head>

<body>


<table>
<tr><th align='right'>Doc. no.:</th><td>WG21/N3982</td></tr>
<tr><th align='right'>Date:</th><td>2014-04-03</td></tr>
<tr><th valign='top' align='right'>Author:</th><td>Andrzej Krzemie&#x144;ski</td></tr>
<tr><th valign='top' align='right'>Contact:</th><td><a href='mailto:akrzemi1@gmail.com'>akrzemi1@gmail.com</a></td></tr>
<tr><th align='right'>Addresses:</th><td>fundamentals-ts</td></tr>
</table>

<h1><a name='title'>Rvalue reference overloads for optional</a></h1>


<p>This document proposes an addition of missing rvalue reference overloads for <code>optional</code> observer functions.</p>

<h2><a name='toc'>Table of contents</a></h2>

<p id='toc'></p>


<h2>Motivation</h2>

<p>Consider the following usage of <code>optional</code>. A converting function that converts from type <code>T</code> to some other type <code>U</code>:</p>

<pre>template &lt;typename U, typename T&gt;
optional&lt;U&gt; convert(const T&amp; v);</pre>

<p>Such a conversion may fail because certain values of type <code>T</code> cannot be represented by any value of type <code>U</code>. For instance converting a <code>string</code> to <code>int</code> may fail. One user can consider such failure an exceptional condition that qualifies for a throw. Other user may just want to use a default value instead. Some other user may want to perform some fallback action, or skip some part of the code. Finally, a different user can just be sure that the conversion will not fail (e.g. when converting an <code>int</code> to a <code>string</code>), and may want to skip a time-consuming check. <code>optional</code> can satisfy all these expectations:</p> 

<pre>int i;	

auto oi = convert&lt;int&gt;(str);   
if (oi) i = *oi;                    <em>// (1) check and skip logic</em>
i = convert&lt;int&gt;(str).value_or(-1); <em>// (2) use default</em>
i = convert&lt;int&gt;(str).value();      <em>// (3) throw if empty</em>
i = *convert&lt;int&gt;("1");             <em>// (4) unchecked</em></pre> 

<p>Now, suppose that, rather than to type <code>int</code>, we are converting to a type that is <code>MoveConstructible</code> but not <code>CopyConstructible</code>. Case (1), with manual check, does not work (unless we put an explicit <code>move</code>). But that is understandable: we want to perform two reads from the optional object: one to check if it contains the value, the other to read the value. For that we need a named object; it cannot be a temporary, so no implicit moving is possible. Case (2) will work fine. This is because function <code>value_or</code> has two overloads: for <code>*this</code> being an lvalue reference to <code>const</code> and rvalue reference. Cases (3) and (4) will not work although they could have. <code>optional</code> is just missing the rvalue reference overloads for these functions. This is what this proposal intends to fix: add rvalue reference overloads for member functions <code>value</code> and <code>operator*</code> (not for <code>operator-&gt;</code>, because it appears not to be implementable). I consider it a bug fix rather than a new feature, primarily because such an overload already exists and has been approved for function <code>value_or</code>. This is why I propose to fix it still in the first version of Fundamentals TS.</p>

<h2>Implementability</h2>

The proposed changes are not implementable in C++11. This is because in C++11 <code>constexpr</code> member functions automatically become <code>const</code>, and one cannot implement a member function that is both <code>constexpr</code> and has an rvalue reference qualifier. C++14 fixed it though, and a reference implementation of the proposed fix to optional in C++14 (tested in Clang 3.4) can be accessed at <a href="https://github.com/akrzemi1/Optional">https://github.com/akrzemi1/Optional</a>. For consistency, this proposal makes all the observer functions <code>constexpr</code>.


<h2><a name='wording'>Proposed wording</a></h2>

<p>The insertions and deletions in this section describe the changes to Fundamentals TS, assuming N3966 has been incorporated.</p>

<p>In optional synopsis [optional.synop], change the declaration of observers as follows:</p>

<blockquote class="std"> 
<pre>
    // <em><a href="#optional.object.observe">5.4.5</a>, observers</em>
    constexpr T const* operator -&gt;() const;
    <ins>constexpr</ins> T* operator -&gt;();
    constexpr T const&amp; operator *() const<ins>&amp;</ins>;
    <ins>constexpr</ins> T&amp; operator *() <ins>&amp;</ins>;
    <ins>constexpr T&amp;&amp; operator *() &amp;&amp;;</ins>
    constexpr explicit operator bool() const noexcept;
    constexpr T const&amp; value() const<ins>&amp;</ins>;
    <ins>constexpr</ins> T&amp; value() <ins>&amp;</ins>;
    <ins>constexpr T&amp;&amp; value() &amp;&amp;;</ins>
    template &lt;class U&gt; constexpr T value_or(U&amp;&amp;) const&amp;;
    template &lt;class U&gt; <ins>constexpr</ins> T value_or(U&amp;&amp;) &amp;&amp;;
</pre>
</blockquote>

Change  [optional.object.observe] as follows:

<blockquote class="std"> 
<h5><a name="optional.object.observe">5.4.5 Observers  <span style="float:right">[optional.object.observe]</span></a></h5>


  <p class="function">
  <code>constexpr T const* operator-&gt;() const;<br><ins>constexpr</ins> T* operator-&gt;();</code>
  </p>
  
  <dl class="attribute">
    <dt>Requires:</dt> <dd><p><code>bool(*this)</code>.</p></dd>
    <dt>Returns:</dt> <dd><p><code><var>val</var></code>.</p></dd>
    <dt>Throws:</dt> <dd><p>Nothing.</p></dd>
    <dt>Remarks:</dt> <dd><p>Unless <code>T</code> is a user-defined type with overloaded unary <code>operator&amp;</code>, <del>the first function</del><ins>these functions</ins> shall be <del>a </del><code>constexpr</code> function<ins>s</ins>.</p></dd>
  </dl>
  
  
  <p class="function">
  <code>constexpr T const&amp; operator*() const<ins>&amp;</ins>;<br><ins>constexpr</ins> T&amp; operator*() <ins>&amp;</ins>;</code>
  </p>
  
  <dl class="attribute">
    <dt>Requires:</dt> <dd><p><code>bool(*this)</code><ins>.</ins></p></dd>
    <dt>Returns:</dt> <dd><p><code>*<var>val</var></code>.</p></dd>
    <dt>Throws:</dt> <dd><p>Nothing.</p></dd>
    <dt>Remarks:</dt> <dd><p><del>The first function</del><ins>These functions</ins> shall be <del>a </del><code>constexpr</code> function<ins>s</ins>.</p></dd>
  </dl>
  
  <p class="function">
  <ins><code>constexpr T&amp;&amp; operator*() &amp;&amp;</code></ins>
  </p>
  
  <dl class="attribute">
    <dt><ins>Requires:</ins></dt> <dd><p><ins><code>bool(*this)</code>.</ins></p></dd>
    <dt><ins>Returns:</ins></dt> <dd><p><ins><code>std::move(*<var>val</var>)</code>.</ins></p></dd>
    <dt><ins>Throws:</ins></dt> <dd><p><ins>Nothing.</ins></p></dd>
    <dt><ins>Remarks:</ins></dt> <dd><p><ins>This function shall be a <code>constexpr</code> function.</ins></p></dd>
  </dl>
  
  <p class="function">
  <code>constexpr explicit operator bool() noexcept;</code>
  </p>
  
  <dl class="attribute">
    <dt>Returns:</dt> <dd><p><code>true</code> if and only if <code>*this</code> contains a value.</p></dd>
    <dt>Remarks:</dt> <dd><p>This function shall be a <code>constexpr</code> function.</p></dd>
  </dl>
  
  
  <p class="function">
  <code>constexpr T const&amp; value() const<ins>&amp;</ins>;<br><ins>constexpr</ins>  T&amp; value() <ins>&amp;</ins>;</code>
  </p>
  
  <dl class="attribute">
    <dt>Returns:</dt> <dd><p><code><var>*val</var></code>, if <code>bool(*this)</code>.</p></dd>
    <dt>Throws:</dt> <dd><p><code>bad_optional_access</code> if <code>!*this</code>.</p></dd>
    <dt>Remarks:</dt> <dd><p><del>The first function</del><ins>These functions</ins> shall be <del>a </del><code>constexpr</code> function<ins>s</ins>.</p></dd>
  </dl>
  
  
  <p class="function">
  <ins><code>constexpr T &amp;&amp; value() &amp;&amp;;</code></ins>
  </p>
  
  <dl class="attribute">
    <dt><ins>Returns:</ins></dt> <dd><p><ins><code>std::move(<var>*val</var>)</code>, if <code>bool(*this)</code>.</ins></p></dd>
    <dt><ins>Throws:</ins></dt> <dd><p><ins><code>bad_optional_access</code> if <code>!*this</code>.</ins></p></dd>
    <dt><ins>Remarks:</ins></dt> <dd><p><ins>This function shall be a <code>constexpr</code> function.</ins></p></dd>
  </dl>
  

  <p class="function">
  <code>template &lt;class U&gt; constexpr T value_or(U&amp;&amp; <var>v</var>) const&amp;;</code>
  </p>
  
  <dl class="attribute">
    <dt>Requires:</dt> <dd><p><code>is_copy_constructible&lt;T&gt;::value</code> is <code>true</code> and <code>is_convertible&lt;U&amp;&amp;, T&gt;::value</code> is <code>true</code>.</p></dd>
    <dt>Returns:</dt> <dd><p><code>bool(*this) ? **this : static_cast&lt;T&gt;(std::forward&lt;U&gt;(<var>v</var>))</code>.</p></dd>
    <dt>Throws:</dt> <dd><p>Any exception thrown by the selected constructor of <code>T</code>.</p></dd>
    <dt>Exception Safety:</dt> <dd><p>If <code>bool(*this)</code> and exception is thrown during the call to <code>T</code>'s constructor, the value of <code>bool(*this)</code> and <code><var>v</var></code> remains unchanged and the state of <code><var>*val</var></code> is determined by the exception safety guarantee of the selected constructor of <code>T</code>. Otherwise, when an exception is thrown during the call to <code>T</code>'s constructor, the value of <code><var>*this</var></code> remains unchanged and the state of <code><var>v</var></code> is determined by the exception safety guarantee of the selected constructor of <code>T</code>.</p></dd>
    <dt>Remarks:</dt> <dd><p>If any of the constructors of <code>T</code> which could be selected is a <code>constexpr</code> constructor, this function shall be a <code>constexpr</code> function.</p></dd>
  </dl>
  
  
  <p class="function">
  <code>template &lt;class U&gt; <ins>constexpr</ins> T value_or(U&amp;&amp; <var>v</var>) &amp;&amp;;</code>
  </p>
  
  <dl class="attribute">
    <dt>Requires:</dt> <dd><p><code>is_move_constructible&lt;T&gt;::value</code> is <code>true</code> and <code>is_convertible&lt;U&amp;&amp;, T&gt;::value</code> is <code>true</code>.</p></dd>
    <dt>Returns:</dt> <dd><p><code>bool(*this) ? std::move(**this) : static_cast&lt;T&gt;(std::forward&lt;U&gt;(<var>v</var>))</code>.</p></dd>
    <dt>Throws:</dt> <dd><p>Any exception thrown by the selected constructor of <code>T</code>.</p></dd>
    <dt>Exception Safety:</dt> <dd><p>If <code>bool(*this)</code> and exception is thrown during the call to <code>T</code>'s constructor, the value of <code>bool(*this)</code> and <code><var>v</var></code> remains unchanged and the state of <code><var>*val</var></code> is determined by the exception safety guarantee of the <code>T</code>'s constructor. Otherwise, when an exception is thrown during the call to <code>T</code>'s constructor, the value of <code><var>*this</var></code> remains unchanged and the state of <code><var>v</var></code> is determined by the exception safety guarantee of the selected constructor of <code>T</code>.</p></dd>
	<dt><ins>Remarks:</ins></dt> <dd><p><ins>If any of the constructors of <code>T</code> which could be selected is a <code>constexpr</code> constructor, this function shall be a <code>constexpr</code> function.</ins></p></dd>
  </dl>
</blockquote>


<h2><a name='acknowledgements'>Acknowledgements</a></h2>

<p>Daniel Kr&uuml;gler and Tomasz Kami&#324;ski reviewed the proposal and suggested fixes.</p>

  

</body>
</html>
