• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
3<title>Home - Boost.Outcome documentation</title>
4<link rel="stylesheet" href="./css/boost.css" type="text/css">
5<meta name="generator" content="Hugo 0.52 with Boostdoc theme">
6<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
7
8<link rel="icon" href="./images/favicon.ico" type="image/ico"/>
9<body><div class="spirit-nav">
10
11    <a accesskey="h" href="./index.html"><img src="./images/home.png" alt="Home"></a><a accesskey="n" href="./requirements.html"><img src="./images/next.png" alt="Next"></a></div><div id="content">
12
13
14<h1 id="outcome-2-1-library">Outcome 2.1 library</h1>
15
16<div>
17  <div class="author">
18    <h3 class="author"><span class="firstname">Niall</span> <span class="surname">Douglas</span></h3>
19  </div>
20</div>
21<div><p class="copyright">Copyright &#169; 2014-2020 Niall Douglas <a href="./credits.html">and others</a></p></div>
22<div><div class="legalnotice">
23<a name="outcome.legal"></a><p>
24        Distributed under the Boost Software License, Version 1.0. (See accompanying
25        file LICENSE_1_0.txt or copy at <a href="./LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
26      </p>
27</div></div>
28<div class="toc">
29<p><b>Table of Contents</b></p>
30<dl class="toc">
31  <dt><span class="section"><a href="./requirements.html">Prerequisites</a></span></dt>
32  <dt><span class="section"><a href="./build.html">Build and install</a></span></dt>
33  <dt><span class="section"><a href="./motivation.html">Motivation</a></span></dt>
34        <dd><dl>
35  <dt><span class="section"><a href="./motivation/exceptions.html">Exceptions</a></span></dt>
36  <dt><span class="section"><a href="./motivation/errno.html">errno</a></span></dt>
37  <dt><span class="section"><a href="./motivation/error_codes.html">Error codes</a></span></dt>
38  <dt><span class="section"><a href="./motivation/std_error_code.html">std::error_code</a></span></dt>
39  <dt><span class="section"><a href="./motivation/plug_error_code.html">Plugging a library into std::error_code`</a></span></dt>
40  <dt><span class="section"><a href="./motivation/plug_error_code2.html">Plugging a library into boost::system::error_code</a></span></dt>
41  <dt><span class="section"><a href="./motivation/narrow_contract.html">Narrow contracts</a></span></dt>
42        </dl></dd>
43  <dt><span class="section"><a href="./tutorial.html">Tutorial</a></span></dt>
44        <dd><dl>
45  <dt><span class="section"><a href="./tutorial/essential.html">Essential</a></span></dt>
46  <dt><span class="section"><a href="./tutorial/advanced.html">Advanced</a></span></dt>
47        </dl></dd>
48  <dt><span class="section"><a href="./recipes.html">Recipes</a></span></dt>
49        <dd><dl>
50  <dt><span class="section"><a href="./recipes/asio-integration.html">ASIO/Networking TS : Boost &lt; 1.70</a></span></dt>
51  <dt><span class="section"><a href="./recipes/asio-integration-1-70.html">ASIO/Networking TS: Boost &gt;= 1.70</a></span></dt>
52  <dt><span class="section"><a href="./recipes/foreign-try.html">Extending <code>BOOST_OUTCOME_TRY</code></a></span></dt>
53        </dl></dd>
54  <dt><span class="section"><a href="./experimental.html">Experimental</a></span></dt>
55        <dd><dl>
56  <dt><span class="section"><a href="./experimental/advantages.html">The main advantages</a></span></dt>
57  <dt><span class="section"><a href="./experimental/map.html">Approximate map between error code designs</a></span></dt>
58  <dt><span class="section"><a href="./experimental/differences.html">Major differences</a></span></dt>
59  <dt><span class="section"><a href="./experimental/status_result.html"><code>status_result</code> and <code>status_outcome</code></a></span></dt>
60  <dt><span class="section"><a href="./experimental/worked-example.html">Worked example: Custom domain</a></span></dt>
61  <dt><span class="section"><a href="./experimental/outcome.html">Tying it all together</a></span></dt>
62  <dt><span class="section"><a href="./experimental/c-api.html">Using Outcome from C code</a></span></dt>
63        </dl></dd>
64  <dt><span class="section"><a href="./reference.html">API reference</a></span></dt>
65        <dd><dl>
66  <dt><span class="section"><a href="./reference/macros.html">Macros</a></span></dt>
67  <dt><span class="section"><a href="./reference/concepts.html">Concepts</a></span></dt>
68  <dt><span class="section"><a href="./reference/converters.html">Converters</a></span></dt>
69  <dt><span class="section"><a href="./reference/traits.html">Traits</a></span></dt>
70  <dt><span class="section"><a href="./reference/policies.html">Policies</a></span></dt>
71  <dt><span class="section"><a href="./reference/types.html">Types</a></span></dt>
72  <dt><span class="section"><a href="./reference/aliases.html">Aliases</a></span></dt>
73  <dt><span class="section"><a href="./reference/functions.html">Functions</a></span></dt>
74        </dl></dd>
75  <dt><span class="section"><a href="./faq.html">Frequently asked questions</a></span></dt>
76  <dt><span class="section"><a href="./videos.html">Videos</a></span></dt>
77  <dt><span class="section"><a href="./changelog.html">Changelog</a></span></dt>
78  <dt><span class="section"><a href="./history.html">History</a></span></dt>
79
80
81</dl>
82</div>
83<h2 class="title">Introduction</h2>
84
85<p>Outcome is a set of tools for reporting and handling function failures in contexts where <em>directly</em> using C++ exception handling is unsuitable. Such contexts include:</p>
86
87<ul>
88<li><p>there are programs, or parts thereof, that are compiled with exceptions disabled;</p></li>
89
90<li><p>there are parts of program that have a lot of branches depending on types of failures,
91where if-statements are cleaner than try-catch blocks;</p></li>
92
93<li><p>there is a hard requirement that the failure path of execution should not cost more than the successful path of execution;</p></li>
94
95<li><p>there are situations, like in the <a href="http://www.boost.org/doc/libs/release/libs/filesystem/doc/index.htm"><code>filesystem</code></a> library, where whether the failure should be handled remotely
96(using a C++ exception throw), or locally cannot be made inside the function and needs to be decided by the caller,
97and in the latter case throwing a C++ exception is not desirable for the aforementioned reasons;</p></li>
98
99<li><p>there are parts of the program/framework that themselves implement exception handling and prefer
100to not use exceptions to propagate failure reports across threads, tasks, fibers, etc;</p></li>
101
102<li><p>one needs to propagate exceptions through layers that do not implement exception throw safety;</p></li>
103
104<li><p>there is an external requirement (such as a company-wide policy) that failure handling paths are explicitly indicated in the code.</p></li>
105
106<li><p>where interoperation with C code, without having to resort to C++ exception wrapper shims, is important.</p></li>
107</ul>
108
109<p>Outcome addresses failure handling through returning a special type from functions, which is able to store either a successfully computed value (or <code>void</code>), or the information about failure. Outcome also comes with a set of idioms for dealing with such types.</p>
110
111<p>Particular care has been taken to ensure that Outcome has the lowest possible impact on build times,
112thus making it suitable for use in the global headers of really large codebases. Storage layout is
113guaranteed and is C-compatible for <code>result&lt;T, E&gt;</code><sup class="footnote-ref" id="fnref:1"><a href="#fn:1">1</a></sup>, thus making Outcome based code long term ABI-stable.</p>
114
115<div class="notices note" style="background: url('images/note.png') top left no-repeat padding-box padding-box;">
116<div class="notices heading">note</div>
117<div class="notices message"><p>Ben Craig&rsquo;s work on <a href="https://wg21.link/P1886">P1886 <em>Error speed benchmarking</em></a> has led to
118a <a href="https://github.com/ned14/outcome/tree/better_optimisation"><code>better_optimisation</code></a> branch intended
119to be merged end of 2020 as Outcome v2.2.0, after twelve months of testing. This branch has a number
120of major and breaking changes to Outcome v2:</p>
121
122<ol>
123<li><p>A new trait <code>is_move_bitcopying&lt;T&gt;</code> is added, which opts types into a library-based emulation of
124<a href="https://wg21.link/P1029">P1029 <em>move = bitcopies</em></a>. <a href="https://wg21.link/P1028">Experimental <code>std::error</code></a> is opted in by default.
125If this trait is true for your <code>T</code> or <code>E</code> type, Outcome will track moved-from status for your type,
126and will only call your type&rsquo;s destructor if it was not moved from. If your compiler&rsquo;s optimiser is
127sufficiently able to fold code, this improves codegen quality for Experimental Outcome very considerably,
128approaching the same gains as P1029 types would have. Note that the empirical performance difference
129will likely be nil, but the codegen does look much more elegant.</p></li>
130
131<li><p>If for <code>basic_result&lt;T, E&gt;</code> both <code>T</code> and <code>E</code> are trivially copyable, union-based rather than
132struct-based storage will be used. This significantly improves performance in synthetic benchmarks
133which do nothing in deep call stacks of function calls except create and return <code>result&lt;T, E&gt;</code>, and
134makes Outcome return competitive results to alternative error handling choices, improving comparative
135optics. It is not expected that the performance difference will be detectable empirically in real
136world code. It is expected that the build time impact of union storage won&rsquo;t be noticeable, as
137union storage for trivially copyable types is much easier than for non-TC types.</p></li>
138
139<li><p>The compile time requirement for <code>E</code> types to have a default constructor is removed.</p></li>
140
141<li><p><code>BOOST_OUTCOME_TRY(var, expr)</code> no longer always declares <code>var</code> as <code>auto &amp;&amp;var</code>, but simply uses it
142as is. This allows <code>TRY</code> to initialise or assign. You can use the macro <code>OUTCOME21_TRY</code> if you
143want the pre-Outcome v2.2 behaviour. You may find the regular expression <code>_TRY\(([^(]*?),(.*?)\);</code> =&gt;
144<code>_TRY(auto &amp;&amp;\1,\2);</code> of use to you when upgrading code.</p></li>
145</ol>
146</div>
147</div>
148
149
150<h2 id="sample-usage">Sample usage</h2>
151
152<p>The main workhorse in the Outcome library is <code>result&lt;T&gt;</code>: it represents either a successfully computed value of type <code>T</code>, or a <code>std::error_code</code>/<code>boost::system::error_code</code><sup class="footnote-ref" id="fnref:2"><a href="#fn:2">2</a></sup> representing the reason for failure. You use it in the function&rsquo;s return type:</p>
153
154<div class="code-snippet"><div class="highlight"><pre class="chroma"><code class="language-c++" data-lang="c++"><span class="n">outcome</span><span class="o">::</span><span class="n">result</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">data_from_file</span><span class="p">(</span><span class="n">string_view</span> <span class="n">path</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
155</code></pre></div><a href="https://github.com/boostorg/outcome/tree/master/doc/src/snippets/intro_example.cpp#L49" class="code-snippet-url" target="_blank">View this code on Github</a></div>
156
157
158<p>It is possible to inspect the state manually:</p>
159
160<div class="code-snippet"><div class="highlight"><pre class="chroma"><code class="language-c++" data-lang="c++"><span class="k">if</span> <span class="p">(</span><span class="n">outcome</span><span class="o">::</span><span class="n">result</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">rslt</span> <span class="o">=</span> <span class="n">data_from_file</span><span class="p">(</span><span class="s">&#34;config.cfg&#34;</span><span class="p">))</span>
161  <span class="n">use_string</span><span class="p">(</span><span class="n">rslt</span><span class="p">.</span><span class="n">value</span><span class="p">());</span>                   <span class="c1">// returns string
162</span><span class="c1"></span><span class="k">else</span>
163  <span class="k">throw</span> <span class="n">LibError</span><span class="p">{</span><span class="n">rslt</span><span class="p">.</span><span class="n">error</span><span class="p">(),</span> <span class="s">&#34;config.cfg&#34;</span><span class="p">};</span> <span class="c1">// returns error_code
164</span><span class="c1"></span></code></pre></div><a href="https://github.com/boostorg/outcome/tree/master/doc/src/snippets/intro_example.cpp#L54" class="code-snippet-url" target="_blank">View this code on Github</a></div>
165
166
167<p>Or, if this function is called in another function that also returns <code>result&lt;T&gt;</code>, you can use a dedicated control statement:</p>
168
169<div class="code-snippet"><div class="highlight"><pre class="chroma"><code class="language-c++" data-lang="c++"><span class="n">outcome</span><span class="o">::</span><span class="n">result</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">process</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span><span class="o">&amp;</span> <span class="n">content</span><span class="p">)</span> <span class="k">noexcept</span><span class="p">;</span>
170
171<span class="n">outcome</span><span class="o">::</span><span class="n">result</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">int_from_file</span><span class="p">(</span><span class="n">string_view</span> <span class="n">path</span><span class="p">)</span> <span class="k">noexcept</span>
172<span class="p">{</span>
173  <span class="n">BOOST_OUTCOME_TRY</span><span class="p">(</span><span class="n">str</span><span class="p">,</span> <span class="n">data_from_file</span><span class="p">(</span><span class="n">path</span><span class="p">));</span>
174  <span class="c1">// if control gets here data_from_file() has succeeded
175</span><span class="c1"></span>  <span class="k">return</span> <span class="nf">process</span><span class="p">(</span><span class="n">str</span><span class="p">);</span>  <span class="c1">// decltype(str) == string
176</span><span class="c1"></span><span class="p">}</span>
177</code></pre></div><a href="https://github.com/boostorg/outcome/tree/master/doc/src/snippets/intro_example.cpp#L62" class="code-snippet-url" target="_blank">View this code on Github</a></div>
178
179
180<p><code>BOOST_OUTCOME_TRY</code> is a control statement. If the returned <code>result&lt;T&gt;</code> object contains an error information, the enclosing function is immediately returned with <code>result&lt;U&gt;</code> containing the same failure information; otherwise an automatic object of type <code>T</code>
181is available in scope.</p>
182
183<div class="notices note" style="background: url('images/note.png') top left no-repeat padding-box padding-box;">
184<div class="notices heading">note</div>
185<div class="notices message"><p>This library joined <a href="https://www.boost.org/doc/libs/develop/libs/outcome/doc/html/index.html">the Boost C++ libraries</a> in the 1.70 release (Spring 2019). <a href="https://github.com/boostorg/outcome">It can be grafted into much older Boost releases if desired</a>.</p>
186</div>
187</div>
188
189<div class="footnotes">
190
191<hr />
192
193<ol>
194<li id="fn:1">If you choose a C-compatible <code>T</code> and <code>E</code> type.
195 <a class="footnote-return" href="#fnref:1"><sup>[return]</sup></a></li>
196<li id="fn:2"><code>result&lt;T&gt;</code> defaults to <code>std::error_code</code> for Standalone Outcome, and to <code>boost::system::error_code</code> for Boost.Outcome. You can mandate a choice using <code>std_result&lt;T&gt;</code> or <code>boost_result&lt;T&gt;</code>.
197 <a class="footnote-return" href="#fnref:2"><sup>[return]</sup></a></li>
198</ol>
199</div>
200
201
202        </div><p><small>Last revised: July 03, 2020 at 14:21:54 &#43;0100</small></p>
203<hr>
204<div class="spirit-nav">
205<a accesskey="p" href="./history.html"><img src="./images/prev.png" alt="Prev"></a>
206
207    <a accesskey="h" href="./index.html"><img src="./images/home.png" alt="Home"></a><a accesskey="n" href="./requirements.html"><img src="./images/next.png" alt="Next"></a></div></body>
208</html>
209