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 © 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 < 1.70</a></span></dt> 51 <dt><span class="section"><a href="./recipes/asio-integration-1-70.html">ASIO/Networking TS: Boost >= 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<T, E></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’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<T></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’s destructor if it was not moved from. If your compiler’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<T, E></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<T, E></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’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 &&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> => 144<code>_TRY(auto &&\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<T></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’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"><</span><span class="n">string</span><span class="o">></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"><</span><span class="n">string</span><span class="o">></span> <span class="n">rslt</span> <span class="o">=</span> <span class="n">data_from_file</span><span class="p">(</span><span class="s">"config.cfg"</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">"config.cfg"</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<T></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"><</span><span class="kt">int</span><span class="o">></span> <span class="n">process</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span><span class="o">&</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"><</span><span class="kt">int</span><span class="o">></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<T></code> object contains an error information, the enclosing function is immediately returned with <code>result<U></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<T></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<T></code> or <code>boost_result<T></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 +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