app-go.html 8.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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>In use - 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. <link rel="icon" href="../../../images/favicon.ico" type="image/ico"/>
  8. <body><div class="spirit-nav">
  9. <a accesskey="p" href="../../../tutorial/advanced/interop/app-map-tidylib.html"><img src="../../../images/prev.png" alt="Prev"></a>
  10. <a accesskey="u" href="../../../tutorial/advanced/interop.html"><img src="../../../images/up.png" alt="Up"></a>
  11. <a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../../../tutorial/advanced/interop/conclusion.html"><img src="../../../images/next.png" alt="Next"></a></div><div id="content">
  12. <div class="titlepage"><div><div><h1 style="clear: both">In use</h1></div></div></div>
  13. <p>This is how you might now write application code using these three libraries:</p>
  14. <div class="code-snippet"><div class="highlight"><pre class="chroma"><code class="language-c++" data-lang="c++"><span class="k">namespace</span> <span class="n">app</span>
  15. <span class="p">{</span>
  16. <span class="c1">// A markup function to indicate when we are ValueOrError converting
  17. </span><span class="c1"></span> <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span><span class="err"> </span><span class="nc">T</span><span class="o">&gt;</span> <span class="kr">inline</span> <span class="n">outcome</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;</span> <span class="n">ext</span><span class="p">(</span><span class="n">T</span> <span class="o">&amp;&amp;</span><span class="n">v</span><span class="p">)</span>
  18. <span class="p">{</span> <span class="c1">//
  19. </span><span class="c1"></span> <span class="k">return</span> <span class="n">outcome</span><span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">::</span><span class="n">value_type</span><span class="o">&gt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">v</span><span class="p">));</span>
  20. <span class="p">}</span>
  21. <span class="n">outcome</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">go</span><span class="p">()</span> <span class="c1">// NOT noexcept, this can throw STL exceptions e.g. bad_alloc
  22. </span><span class="c1"></span> <span class="p">{</span>
  23. <span class="c1">// Note that explicit construction is required when converting between differing types
  24. </span><span class="c1"></span> <span class="c1">// of outcome and result. This makes it explicit what you intend to do as conversion
  25. </span><span class="c1"></span> <span class="c1">// may be a lot more expensive than moves.
  26. </span><span class="c1"></span>
  27. <span class="c1">// Try to GET this URL. If an unsuccessful HTTP status is returned, serialise a string
  28. </span><span class="c1"></span> <span class="c1">// containing a description of the HTTP status code and the URL which failed, storing
  29. </span><span class="c1"></span> <span class="c1">// that into a httplib_error exception type which is stored as an exception ptr. The
  30. </span><span class="c1"></span> <span class="c1">// TRY operation below will return that exception ptr to be rethrown in the caller.
  31. </span><span class="c1"></span> <span class="c1">// Otherwise the fetched data is returned in a std::string data.
  32. </span><span class="c1"></span> <span class="n">BOOST_OUTCOME_TRY</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">ext</span><span class="p">(</span><span class="n">httplib</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="s">&#34;http://www.nedproductions.biz/&#34;</span><span class="p">)));</span>
  33. <span class="n">string_view</span> <span class="nf">data_view</span><span class="p">(</span><span class="n">data</span><span class="p">);</span>
  34. <span class="c1">// HTML tidy the fetched data. If the C library fails due to an error corresponding to
  35. </span><span class="c1"></span> <span class="c1">// a standard library exception type, throw that. Otherwise, synthesise an exception
  36. </span><span class="c1"></span> <span class="c1">// ptr of type tidylib_error which stores the error code returned in an error code with
  37. </span><span class="c1"></span> <span class="c1">// generic category (i.e. errno domain).
  38. </span><span class="c1"></span> <span class="c1">// TRY operation below will return that exception ptr to be rethrown in the caller.
  39. </span><span class="c1"></span> <span class="c1">// Otherwise the tidied data is returned into holdmem, with the string view updated to
  40. </span><span class="c1"></span> <span class="c1">// point at the tidied data.
  41. </span><span class="c1"></span> <span class="n">BOOST_OUTCOME_TRY</span><span class="p">(</span><span class="n">holdmem</span><span class="p">,</span> <span class="n">ext</span><span class="p">(</span><span class="n">tidy_html</span><span class="p">(</span><span class="n">data_view</span><span class="p">)));</span>
  42. <span class="c1">// Write the tidied data to some file. If the write fails, synthesise a filesystem_error
  43. </span><span class="c1"></span> <span class="c1">// exception ptr exactly as if one called filelib::write_file(data_view).value().
  44. </span><span class="c1"></span> <span class="n">BOOST_OUTCOME_TRY</span><span class="p">(</span><span class="n">written</span><span class="p">,</span> <span class="n">ext</span><span class="p">(</span><span class="n">filelib</span><span class="o">::</span><span class="n">write_file</span><span class="p">(</span><span class="n">data_view</span><span class="p">)));</span>
  45. <span class="k">return</span> <span class="nf">success</span><span class="p">();</span>
  46. <span class="p">}</span>
  47. <span class="p">}</span> <span class="c1">// namespace app
  48. </span><span class="c1"></span></code></pre></div><a href="https://github.com/boostorg/outcome/tree/master/doc/src/snippets/finale.cpp#L370" class="code-snippet-url" target="_blank">View this code on Github</a></div>
  49. <p>The curiosity will be surely the <code>ext()</code> markup function, which needs
  50. explaining. It was felt
  51. important during Outcome&rsquo;s design that <code>ValueOrError</code> conversions never
  52. be implicit, as they almost always represent a transition across an
  53. ABI or semantic boundary. They are also usually non-trivial to implement
  54. and compile, and it was felt important that the programmer ought to
  55. always mark the semantic boundary transition at the point of every use,
  56. as considerable amounts of code may execute.</p>
  57. <p>How the end user chooses to mark up their code is up to them, however
  58. above we use a simple <code>ext()</code> function to mark up that the function
  59. being called is <em>external</em> to the application. This ticks our box of
  60. requiring the documentation, at the point of use, of every transition
  61. in failure handling boundaries.</p>
  62. <p>Note that we are able to use <code>TRY</code> as normal throughout this function.
  63. Everything &ldquo;just works&rdquo;.</p>
  64. <p>And most especially note that we never, <strong>at any stage</strong>, needed to modify
  65. the source code of <code>httplib</code>, <code>tidylib</code> nor <code>filelib</code>, nor inject
  66. custom things into their namespaces. This entire worked example was
  67. achieved solely by <code>app</code> based customisation points, and via <code>convert</code>.</p>
  68. </div><p><small>Last revised: February 11, 2019 at 13:38:04 UTC</small></p>
  69. <hr>
  70. <div class="spirit-nav">
  71. <a accesskey="p" href="../../../tutorial/advanced/interop/app-map-tidylib.html"><img src="../../../images/prev.png" alt="Prev"></a>
  72. <a accesskey="u" href="../../../tutorial/advanced/interop.html"><img src="../../../images/up.png" alt="Up"></a>
  73. <a accesskey="h" href="../../../index.html"><img src="../../../images/home.png" alt="Home"></a><a accesskey="n" href="../../../tutorial/advanced/interop/conclusion.html"><img src="../../../images/next.png" alt="Next"></a></div></body>
  74. </html>