<!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">

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; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }

</style>

<title>A Class for Status and Optional Value</title>
</head>

<body>
<h1>A Class for Status and Optional Value</h1>

<p>
Committee: ISO/IEC JTC1 SC22 WG21 EWG Evolution<br>
Document Number: P0262r1<br>
Title: A Class for Status and Optional Value<br>
Date: 2016-10-15<br>
Authors: Lawrence Crowl, Chris Mysen<br>
Reply To: Lawrence Crowl, Lawrence@Crowl.org<br>
Audience: EWG Evolution
</p>


<h2>Abstract</h2>

<p>
We propose a control helper, <code>status_value</code>,
that enables functions to return both status and value from a function,
which in turn enables the caller to decide when exeptions are appropriate,
rather than the callee making that choice.
</p>


<h2>Contents</h2>

<p>
<a href="#Introduction">Introduction</a><br>
<a href="#Discussion">Discussion</a><br>
<a href="#Solution">Solution</a><br>
<a href="#Examples">Examples</a><br>
<a href="#Wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value">?.? Status and Value Objects [status_value]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.general">?.?.1 General [status_value.general]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.syn">?.?.2 Header <code>&lt;status_value&gt;</code> synopsis [status_value.syn]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.class">?.?.3 Class template <code>status_value</code> [status_value.class]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.ctor">?.?.3.1 Constructors [status_value.ctor]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.dtor">?.?.3.2 Destructor [status_value.dtor]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.status">?.?.3.3 Status observers [status_value.status]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.state">?.?.3.4 State observers [status_value.state]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.value">?.?.3.4 Value observers [status_value.value]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#status_value.bad">?.?.4 Class template <code>bad_status_value_access</code> [status_value.bad]</a><br>
<a href="#Revision">Revision History</a><br>
</p>


<h2><a name="Introduction">Introduction</a></h2>

<p>
The current proposal for concurrent queues,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0260r0.html">
P0260r0 C++ Concurrent Queues</a>,
has two separate waiting pop operations,
one with a return value
one with an output reference parameter.
These functions provide essentially the same semantics,
but differ how they signal disappointment.
See
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0157r0.html">P0157r0
Handling Disappointment in C++</a>.
</p>

<blockquote>
<pre>
<code>Value queue::value_pop();
queue_op_status queue::wait_pop(<var>Value</var>&amp;);</code>
</pre>
</blockquote>

<p>
This design has two consequences.
</p>

<ul>
<li><p>
A bad status for <code>value_pop</code> will result in an exception.
</p></li>

<li><p>
Use of the <code>wait_pop</code> operation
requires a <code><var>Value</var></code>
that is essentially default constructible.
</p></li>
</ul>

<p>
Chandler Carruth suggested
having a return value that comprised both status and value.
</p>

<blockquote>
<pre>
<code><var>something</var>&lt;queue_op_status, <var>Value</var>&gt; queue::pop();</code>
</pre>
</blockquote>

<p>
The essential point of the design
is that <code><var>something</var></code> may or may not contain a value,
and that
accessing a non-existent value results in an exception.
</p>

<p>
This design would
normalize the form of the functions,
move exception generation to accessing a non-existent value, and
enable use of types with no default constructor as elements.
</p>

<p>
This paper proposes a mechanism to provide this combined status and value.
While such a proposal could be folded into the queue proposal alone,
the true value of such a mechanism
would be its widespread use throughout the library,
particularly in concurrent data structures
where it is not technically possible
to provide separate access functions for status and value.
Therefore, we should either commit to or abandon such a mechanism.
</p>


<h2><a name="Discussion">Discussion</a></h2>

<p>
The value is clearly related to the class template <code>optional</code>,
as defined by 
<a href="http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2013/n3793.html">
N3793 A proposal to add a utility class to represent optional objects
(Revision 5)</a>.
The problem could be solved
with a tuple of the status and an <code>optional</code>.
That approach would require more verbose code at each use,
which we prefer to avoid.
</p>

<p>
However, the need is almost directly met by
the class template <code>expected</code>,
as defined by 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4109.pdf">
N4109 A proposal to add a utility class to represent expected monad
- Revision 1</a>.
</p>

<p>
In our view, the weakness in the <code>expected</code> proposal
is that you get either a value or an error, but not both.
In the queue proposal,
operations return a status, not an error.
The distinction is that
a queue's inability to deliver a value
is often not an error,
but simply a normal part of interacting with concurrent objects.
For example, <code>try_pop</code>
can return <code>queue_op_status::empty</code>,
which clearly does not indicate an error.
</p>

<p>
The distinction has a design effect
when more than one status may be associated with a value.
For example,
a concurrent queue could provide
both a status indicating success with low contention
and a status indicating success with high contention.
In both cases,
the value alone provides less information.
</p>

<p>
So, we prefer a design in which a status is always provided,
but the value is optional.
Users of the design will need to define which statuses have values.
</p>



<h2><a name="Solution">Solution</a></h2>

<p>
The design is a simpler version of that which appears in 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4109.pdf">
N4109 A proposal to add a utility class to represent expected monad
- Revision 1</a>.
The interface follows the lead of <code>std::optional</code>
in detailed design as reflected in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4604.pdf">
N4604 C++17 CD Ballot Document</a>.
However, there are several definitions in <code>optional</code>
that do not appear in this proposal.
The primary reason is that we propose a control helper,
not a data structure.
Operations related to persistence and deferred values are not needed.
</p>

<p>
The working name for the proposed class is <code>status_value</code>.
</p>

<blockquote>
<pre>
<code>template&lt;typename Status, typename Value&gt; class status_value;</code>
</pre>
</blockquote>

<p>
Construction of a <code>status_value</code>
can be done with or without a value.
</p>

<blockquote>
<pre>
<code>status_value::status_value(Status s);
status_value::status_value(Status s, Value&amp;&amp; v);
status_value::status_value(Status s, const Value&amp; v);</code>
</pre>
</blockquote>

<p>
Construction of <code>status_value</code> must include a status.
</p>

<blockquote>
<pre>
<code>status_value::status_value() = delete;</code>
</pre>
</blockquote>

<p>
A <code>status_value</code> may be moved.
A copy operation would make the type unusable
for non-copyable contained objects,
so we do not provide a copy operation.
</p>

<blockquote>
<pre>
<code>status_value::status_value(status_value&amp;&amp; sv);</code>
</pre>
</blockquote>

<p>
They may be queried for status.
The design assumes that inlining will remove the cost of returning a reference
for cheap copyable types.
</p>

<blockquote>
<pre>
<code>const Status&amp; status_value::status() const noexcept;</code>
</pre>
</blockquote>

<p>
They may be queried for whether or not they have a value.
</p>

<blockquote>
<pre>
<code>bool status_value::has_value() const;
status_value::operator bool() const;</code>
</pre>
</blockquote>

<p>
They may provide access to their value.
If they have no value,
an exception of type <code>bad_status_value_access&lt;Status&gt;</code>,
with the status value passed to the constructor,
is thrown.
</p>

<blockquote>
<pre>
<code>const Value&amp; status_value::value() const;
Value&amp; status_value::value();
const Value&amp; status_value::operator *() const;
Value&amp; status_value::operator *();</code>
</pre>
</blockquote>

<p>
This design enables moving out of the class
by calling <code>std::move</code> on the result of the non-const functions.
</p>


<h2><a name="Examples">Examples</a></h2>

<p>
The outlined solution changes typical code
for the proposed concurrent queue
from
</p>

<blockquote>
<pre>
<code>Value e = q.value_pop();</code>
</pre>
</blockquote>

<p>
into
</p>

<blockquote>
<pre>
<code>Value e = q.value_pop().value();</code>
</pre>
</blockquote>


<p>
and from
</p>

<blockquote>
<pre>
<code>Value e;
queue_op_status s = q.wait_pop(e);
if ( s == queue_op_status::success )
   do_something_with(e);
else
   do_something_else_with(s);</code>
</pre>
</blockquote>

<p>
into
</p>

<blockquote>
<pre>
<code>auto sv = q.wait_pop();
if ( sv.status() == queue_op_status::success )
  do_something_with(sv.value());
else
  do_something_else_with(sv.status());</code>
</pre>
</blockquote>

<p>
or for handling all statuses that have values
</p>

<blockquote>
<pre>
<code>if ( auto sv = q.wait_pop() )
  // Via the implicit conversion to bool, a value is known to be present.
  do_something_with(*sv);
else
  // Via the implicit conversion to bool, a value is known to be absent.
  do_something_else_with(sv.status());</code>
</pre>
</blockquote>

<p>
With both sets of changes,
the handling of disappointment is decided by the caller,
not by the set of operations provided by the queue.
</p>


<h2><a name="Wording">Wording</a></h2>

<p>
The proposed wording is as follows.
</p>


<h3><a name="status_value">?.? Status and Value Objects [status_value]</a></h3>

<p>
Add a new section.
</p>


<h3><a name="status_value.general">?.?.1 General [status_value.general]</a></h3>

<p>
Add a new section.
</p>

<blockquote class="stdins">

<p>
This subclause describes class template <code>status_value</code>
that represents a return status together with an optional object.
The class template <code>status_value</code> is a control helper
that enables deferring to the caller
a decision about whether or not an exception is thrown.
</p>

</blockquote>


<h3><a name="status_value.syn">?.?.2 Header <code>&lt;status_value&gt;</code> synopsis [status_value.syn]</a></h3>

<blockquote class="stdins">

<pre><code>
namespace std {

// ?.?.3 class template status_value
template &lt;typename Status, typename Value&gt;
class status_value;

// ?.?.4 class template bad_status_value_access
template &lt;typename Status&gt;
class bad_status_value_access;

} // namespace std
</code></pre>

<p>
A program that necessitates
the instantiation of template <code>status_value</code>
for a reference type is ill-formed.
</p>

</blockquote>

<h3><a name="status_value.class">?.?.3 Class template <code>status_value</code> [status_value.class]</a></h3>

<blockquote class="stdins">

<pre><code>
template &lt;typename Status, typename Value&gt;
class status_value
{
  // ?.?.3.1 constructors
  status_value() = delete;
  status_value(Status s);
  status_value(Status s, const Value&amp; v);
  status_value(Status s, Value&amp;&amp; v);
  status_value(status_value&amp;&amp; sv) noexcept(see below);

  // ?.?.3.2 destructor
  ~status_value();

  // assignment
  status_value&amp; operator=(const status_value&amp;) = delete;

  // ?.?.3.3 status observers
  const Status&amp; status() const noexcept;

  // ?.?.3.4 state observers
  bool has_value() const noexcept;
  explicit operator bool() const noexcept;

  // ?.?.3.5 value observers
  const Value&amp;  value() const &amp;;
        Value&amp;  value()       &amp;;
        Value&amp;&amp; value()       &amp;&amp;;
  const Value&amp;&amp; value() const &amp;&amp;;
  const Value*  operator-&gt;() const;
        Value*  operator-&gt;();
  const Value&amp;  operator*() const &amp;;
        Value&amp;  operator*()       &amp;;
  const Value&amp;&amp; operator*() const &amp;&amp;;
        Value&amp;&amp; operator*()       &amp;&amp;;
};
</code></pre>

<p>
Any instance of <code>status_value&lt;Status, Value&gt;</code>
at any given time either contains a value or does not contain a value.
When instance of <code>status_value&lt;Status, Value&gt;</code>
contains a value, it means that an object of type <code>Value</code>,
referred to as the <code>status_value</code> object's contained value,
is allocated within the storage of the <code>status_value</code> object.
Implementations are not permitted to use additional storage,
such as dynamic memory, to allocate its contained value.
The contained value shall be allocated
in a region of the <code>status_value</code> storage
suitably aligned for the type <code>Value</code>.
When an object of type <code>status_value</code>
is contextually converted to bool,
the conversion returns true if the object contains a value;
otherwise the conversion returns false.
<p>

<p>
<code>Status</code> shall be an object type
and shall be copy constructible and destructible.
</p>

<p>
<code>Value</code> shall be an object type
and shall be move constructible and destructible.
</p>


<h3><a name="status_value.ctor">?.?.3.1 Constructors [status_value.ctor]</a></h3>

<p class="function">
<code>status_value(Status s);</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Constructs a <code>status_value</code>
with the <code>Status</code> <code>s</code>
and with no <code>Value</code>.
</p></dd>
<dt>Postcondition:</dt>
<dd><p>
<code>this->has_value()</code> is false.
</p></dd>
<dt>Throws:</dt>
<dd><p>
Any exception thrown by the selected constructor of <code>Status</code>.
</p></dd>
</dl>

<p class="function">
<code>status_value(Status s, const Value&amp; v);</code><br>
<code>status_value(Status s, Value&amp;&amp; v);</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Constructs a <code>status_value</code>
with the <code>Status</code> <code>s</code>
and with <code>Value</code> <code>v</code>.
</p></dd>
<dt>Postcondition:</dt>
<dd><p>
<code>this->has_value()</code> is true.
</p></dd>
<dt>Throws:</dt>
<dd><p>
Any exception thrown by the selected constructor of <code>Status</code>.
Any exception thrown by the selected constructor of <code>Value</code>.
</p></dd>
</dl>

<p class="function">
<code>status_value(status_value&amp;&amp; sv) noexcept(see below);</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Constructs a <code>status_value</code>
with a copy of <code>sv.status()</code>
and a move of <code>sv.value()</code>, if any.
</p></dd>
<dt>Postcondition:</dt>
<dd><p>
<code>this-&gt;has_value()</code>
is that of <code>sv-&gt;has_value()</code> before construction.
<code>sv-&gt;has_value()</code> is false.
</p></dd>
<dt>Throws:</dt>
<dd><p>
Any exception thrown by the selected constructor of <code>Status</code>.
Any exception thrown by the selected constructor of <code>Value</code>.
</p></dd>
<dt>Remarks:</dt>
<dd><p>
The expression inside <code>noexcept</code> is equivalent to
<code>is_nothrow_copy_constructible_v&lt;Status&gt; &amp;&amp;
is_nothrow_move_constructible_v&lt;Value&gt;</code>.
</p></dd>
</dl>


<h3><a name="status_value.dtor">?.?.3.2 Destructor [status_value.dtor]</a></h3>

<p class="function">
<code>~status_value();</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Destroys the object.
</p></dd>
</dl>


<h3><a name="status_value.status">?.?.3.3 Status observers [status_value.status]</a></h3>

<p class="function">
<code>const Status&amp; status() const noexcept;</code>
</p>

<dl class="attribute">
<dt>Returns:</dt>
<dd><p>
A reference to the status object.
</p></dd>
</dl>


<h3><a name="status_value.state">?.?.3.4 State observers [status_value.state]</a></h3>

<p class="function">
<code>constexpr bool has_value() const noexcept;<br>
constexpr explicit operator bool() const noexcept;</code>
</p>

<dl class="attribute">
<dt>Returns:</dt>
<dd><p>
True iff <code>*this</code> has a value.
</p></dd>
</dl>

<p class="function">
<code>constexpr bool has_value() const noexcept;<br>
constexpr explicit operator bool() const noexcept;</code>
</p>

<dl class="attribute">
<dt>Returns:</dt>
<dd><p>
True iff <code>*this</code> has a value.
</p></dd>
</dl>

</blockquote>


<h3><a name="status_value.value">?.?.3.4 Value observers [status_value.value]</a></h3>

<blockquote class="stdins">

<p class="function">
<code>const Value&amp;  value() const &amp;;<br>
      Value&amp;  value()       &amp;;<br>
      Value&amp;&amp; value()       &amp;&amp;;<br>
const Value&amp;&amp; value() const &amp;&amp;;<br>
const Value*  operator-&gt;() const;<br>
      Value*  operator-&gt;();<br>
const Value&amp;  operator*() const &amp;;<br>
      Value&amp;  operator*()       &amp;;<br>
const Value&amp;&amp; operator*() const &amp;&amp;;<br>
      Value&amp;&amp; operator*()       &amp;&amp;;</code>
</p>

<dl class="attribute">
<dt>Returns:</dt>
<dd><p>
A reference or pointer to the contained value.
</p></dd>
<dt>Throws:</dt>
<dd><p>
When <code>!this-&gt;has_value()</code>,
a <code>bad_status_value_access&lt;Status&gt;</code>
constructed with the <code>Status</code>
passed to the constructor of <code>status_value</code>.
</p></dd>
</dl>

</blockquote>


<h3><a name="status_value.bad">?.?.4 Class template <code>bad_status_value_access</code> [status_value.bad]</a></h3>

<blockquote class="stdins">

<pre><code>
template &lt;typename Status&gt;
class bad_status_value_access : public logic_error
{
  // constructors
  bad_status_value_access() = delete;
  bad_status_value_access(Status s);

  // destructor
  ~bad_status_value_access();

  // status observers
  const Status&amp; status() const noexcept;

};
</code></pre>

<p>
The class <code>bad_status_value_access</code>
defines the type of objects thrown as exceptions
to report the situation where an attempt is made
to access the value of a status_value object
that does not contain a value.
</p>

<p class="function">
<code>bad_status_value_access(Status s);</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Constructs a <code>bad_status_value_access</code>
with the <code>Status</code> <code>s</code>.
</p></dd>
<dt>Postcondition:</dt>
<dd><p>
<code>what()</code> returns and implementation-defined NTBS.
</p></dd>
<dt>Throws:</dt>
<dd><p>
Any exception thrown by the selected constructor of <code>Status</code>.
</p></dd>
</dl>

<p class="function">
<code>~bad_status_value_access();</code>
</p>

<dl class="attribute">
<dt>Effects:</dt>
<dd><p>
Destroys the object.
</p></dd>
</dl>


<p class="function">
<code>const Status&amp; status() const noexcept;</code>
</p>

<dl class="attribute">
<dt>Returns:</dt>
<dd><p>
A reference to the status object.
</p></dd>
</dl>

</blockquote>


<h2><a name="Revision">Revision History</a></h2>

<p>
This paper revises
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0262r0.html">
P0262r0</a> as follows.
</p>

<ul>

<li><p>
Add proposed wording.
</p></li>

<li><p>
Change signatures to be more in line with <code>optional</code>.
</p></li>

<li><p>
Explicitly delete the assignment operator.
</p></li>

<li><p>
Add additional value observers.
</p></li>

<li><p>
Add <code>noexcept</code> qualifiers where applicable.
</p></li>

<li><p>
Change the exception object type from <code>Status</code>
to <code>std::bad_status_value_access&lt;Status&gt;</code>.
</p></li>

</ul>

<p>
P0262r0 revised
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4233.html">
N4233</a> as follows.
</p>

<ul>

<li><p>
Add a reference to
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0157r0.html">P0157r0
Handling Disappointment in C++</a>.
</p></li>

<li><p>
Add a discussion of a tuple of status and optional.
</p></li>

<li><p>
Explicitly avoid copying for <code>status_value</code> objects.
</p></li>

<li><p>
Make the <code>status</code> member function return a reference,
which enables efficient access to non-trivial status objects.
</p></li>

<li><p>
Clarify the mechanism for moving out of a <code>status_value</code>.
</p></li>

<li><p>
Change the running example
to <code>value_pop</code> versus <code>wait_pop</code>,
which is the essential example of different handling of disappointment.
</p></li>

<li><p>
Add clarification of the example using implicit conversion to bool
in a variable declaration in a condition.
</p></li>

</ul>

</body></html>
