<!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=windows-1252">

<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>
ISO/IEC JTC1 SC22 WG21 N4233 - 2014-10-10
</p>

<p>
Lawrence Crowl, Lawrence@Crowl.org
<br>
Chris Mysen, mysen@google.com
</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>
</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/2013/n3533.html">
N3533 C++ Concurrent Queues</a>,
has separate return value and output parameter for its pop operations.
<p>

<blockquote>
<pre>
<code>Value queue::value_pop();
queue_op_status queue::try_pop(<var>Value</var>&);
queue_op_status queue::nonblocking_pop(<var>Value</var>&);</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>try_pop</code> and <code>nonblocking_pop</code> operations
 will require an <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::value_pop();
<var>something</var>&lt;queue_op_status, <var>Value</var>&gt; queue::try_pop();
<var>something</var>&lt;queue_op_status, <var>Value</var>&gt; queue::nonblocking_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>.
</p>

<p>
However, the need is almost direclty 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 status's 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>.
</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.
At present, we see no need for copying, but we could be convinced otherwise.
</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 the status is cheap and copyable,
which enables more efficient return-by-value.
</p>

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

<p>
They may be queried for wither 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 Status,
with the status value passed to the constructor the constructor,
is thrown.
This design enables moving out of the class.
</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>



<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.try_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.try_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 status's that have values
</p>

<blockquote>
<pre>
<code>if ( auto sv = q.try_pop() )
  do_something_with(*sv);
else
  do_something_else_with(sv.status());</code>
</pre>
</blockquote>

</body></html>
