174 lines
13 KiB
HTML
174 lines
13 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<title>Home - Boost.Outcome documentation</title>
|
|
<link rel="stylesheet" href="./css/boost.css" type="text/css">
|
|
<meta name="generator" content="Hugo 0.52 with Boostdoc theme">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
|
|
|
<link rel="icon" href="./images/favicon.ico" type="image/ico"/>
|
|
<body><div class="spirit-nav">
|
|
|
|
<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">
|
|
|
|
|
|
<h1 id="outcome-2-1-library">Outcome 2.1 library</h1>
|
|
|
|
<div>
|
|
<div class="author">
|
|
<h3 class="author"><span class="firstname">Niall</span> <span class="surname">Douglas</span></h3>
|
|
</div>
|
|
</div>
|
|
<div><p class="copyright">Copyright © 2014-2019 Niall Douglas <a href="./credits.html">and others</a></p></div>
|
|
<div><div class="legalnotice">
|
|
<a name="outcome.legal"></a><p>
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
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>)
|
|
</p>
|
|
</div></div>
|
|
<div class="toc">
|
|
<p><b>Table of Contents</b></p>
|
|
<dl class="toc">
|
|
<dt><span class="section"><a href="./requirements.html">Prerequisites</a></span></dt>
|
|
<dt><span class="section"><a href="./build.html">Build and install</a></span></dt>
|
|
<dt><span class="section"><a href="./motivation.html">Motivation</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="./motivation/exceptions.html">Exceptions</a></span></dt>
|
|
<dt><span class="section"><a href="./motivation/errno.html">errno</a></span></dt>
|
|
<dt><span class="section"><a href="./motivation/error_codes.html">Error codes</a></span></dt>
|
|
<dt><span class="section"><a href="./motivation/std_error_code.html">std::error_code</a></span></dt>
|
|
<dt><span class="section"><a href="./motivation/plug_error_code.html">Plugging a library into std::error_code`</a></span></dt>
|
|
<dt><span class="section"><a href="./motivation/plug_error_code2.html">Plugging a library into boost::system::error_code</a></span></dt>
|
|
<dt><span class="section"><a href="./motivation/narrow_contract.html">Narrow contracts</a></span></dt>
|
|
</dl></dd>
|
|
<dt><span class="section"><a href="./tutorial.html">Tutorial</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="./tutorial/essential.html">Essential</a></span></dt>
|
|
<dt><span class="section"><a href="./tutorial/advanced.html">Advanced</a></span></dt>
|
|
</dl></dd>
|
|
<dt><span class="section"><a href="./recipes.html">Recipes</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="./recipes/asio-integration.html">ASIO/Networking TS : Boost < 1.70</a></span></dt>
|
|
<dt><span class="section"><a href="./recipes/asio-integration-1-70.html">ASIO/Networking TS: Boost >= 1.70</a></span></dt>
|
|
<dt><span class="section"><a href="./recipes/foreign-try.html">Extending <code>BOOST_OUTCOME_TRY</code></a></span></dt>
|
|
</dl></dd>
|
|
<dt><span class="section"><a href="./experimental.html">Experimental</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="./experimental/advantages.html">The main advantages</a></span></dt>
|
|
<dt><span class="section"><a href="./experimental/map.html">Approximate map between error code designs</a></span></dt>
|
|
<dt><span class="section"><a href="./experimental/differences.html">Major differences</a></span></dt>
|
|
<dt><span class="section"><a href="./experimental/status_result.html"><code>status_result</code> and <code>status_outcome</code></a></span></dt>
|
|
<dt><span class="section"><a href="./experimental/worked-example.html">Worked example: Custom domain</a></span></dt>
|
|
<dt><span class="section"><a href="./experimental/outcome.html">Tying it all together</a></span></dt>
|
|
<dt><span class="section"><a href="./experimental/c-api.html">Using Outcome from C code</a></span></dt>
|
|
</dl></dd>
|
|
<dt><span class="section"><a href="./reference.html">API reference</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="./reference/macros.html">Macros</a></span></dt>
|
|
<dt><span class="section"><a href="./reference/concepts.html">Concepts</a></span></dt>
|
|
<dt><span class="section"><a href="./reference/converters.html">Converters</a></span></dt>
|
|
<dt><span class="section"><a href="./reference/traits.html">Traits</a></span></dt>
|
|
<dt><span class="section"><a href="./reference/policies.html">Policies</a></span></dt>
|
|
<dt><span class="section"><a href="./reference/types.html">Types</a></span></dt>
|
|
<dt><span class="section"><a href="./reference/aliases.html">Aliases</a></span></dt>
|
|
<dt><span class="section"><a href="./reference/functions.html">Functions</a></span></dt>
|
|
</dl></dd>
|
|
<dt><span class="section"><a href="./faq.html">Frequently asked questions</a></span></dt>
|
|
<dt><span class="section"><a href="./videos.html">Videos</a></span></dt>
|
|
<dt><span class="section"><a href="./changelog.html">Changelog</a></span></dt>
|
|
<dt><span class="section"><a href="./history.html">History</a></span></dt>
|
|
|
|
|
|
</dl>
|
|
</div>
|
|
<h2 class="title">Introduction</h2>
|
|
|
|
<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>
|
|
|
|
<ul>
|
|
<li><p>there are programs, or parts thereof, that are compiled with exceptions disabled;</p></li>
|
|
|
|
<li><p>there are parts of program that have a lot of branches depending on types of failures,
|
|
where if-statements are cleaner than try-catch blocks;</p></li>
|
|
|
|
<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>
|
|
|
|
<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
|
|
(using a C++ exception throw), or locally cannot be made inside the function and needs to be decided by the caller,
|
|
and in the latter case throwing a C++ exception is not desirable for the aforementioned reasons;</p></li>
|
|
|
|
<li><p>there are parts of the program/framework that themselves implement exception handling and prefer
|
|
to not use exceptions to propagate failure reports across threads, tasks, fibers, etc;</p></li>
|
|
|
|
<li><p>one needs to propagate exceptions through layers that do not implement exception throw safety;</p></li>
|
|
|
|
<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>
|
|
|
|
<li><p>where interoperation with C code, without having to resort to C++ exception wrapper shims, is important.</p></li>
|
|
</ul>
|
|
|
|
<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>
|
|
|
|
<p>Particular care has been taken to ensure that Outcome has the lowest possible impact on build times,
|
|
thus making it suitable for use in the global headers of really large codebases. Storage layout is
|
|
guaranteed 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>
|
|
|
|
<h2 id="sample-usage">Sample usage</h2>
|
|
|
|
<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>
|
|
|
|
<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>
|
|
</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>
|
|
|
|
|
|
<p>It is possible to inspect the state manually:</p>
|
|
|
|
<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>
|
|
<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
|
|
</span><span class="c1"></span><span class="k">else</span>
|
|
<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
|
|
</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>
|
|
|
|
|
|
<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>
|
|
|
|
<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>
|
|
|
|
<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>
|
|
<span class="p">{</span>
|
|
<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>
|
|
<span class="c1">// if control gets here data_from_file() has succeeded
|
|
</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
|
|
</span><span class="c1"></span><span class="p">}</span>
|
|
</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>
|
|
|
|
|
|
<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>
|
|
is available in scope.</p>
|
|
|
|
<div class="notices note" style="background: url('images/note.png') top left no-repeat padding-box padding-box;">
|
|
<div class="notices heading">note</div>
|
|
<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>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="footnotes">
|
|
|
|
<hr />
|
|
|
|
<ol>
|
|
<li id="fn:1">If you choose a C-compatible <code>T</code> and <code>E</code> type.
|
|
<a class="footnote-return" href="#fnref:1"><sup>[return]</sup></a></li>
|
|
<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>.
|
|
<a class="footnote-return" href="#fnref:2"><sup>[return]</sup></a></li>
|
|
</ol>
|
|
</div>
|
|
|
|
|
|
</div><p><small>Last revised: March 19, 2019 at 22:57:48 +0100</small></p>
|
|
<hr>
|
|
<div class="spirit-nav">
|
|
<a accesskey="p" href="./history.html"><img src="./images/prev.png" alt="Prev"></a>
|
|
|
|
<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>
|
|
</html>
|