1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>User Interface Signature</title> 5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../index.html" title="Chapter 1. Boost.Convert 2.0"> 8<link rel="up" href="../design_notes.html" title="Design Notes"> 9<link rel="prev" href="converter_signature.html" title="Converter Signature"> 10<link rel="next" href="../supporting_tools.html" title="Supporting Tools"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> 15<td align="center"><a href="../../../../../../index.html">Home</a></td> 16<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 19<td align="center"><a href="../../../../../../more/index.htm">More</a></td> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<a accesskey="p" href="converter_signature.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../design_notes.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../supporting_tools.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<a name="boost_convert.design_notes.user_interface_signature"></a><a class="link" href="user_interface_signature.html" title="User Interface Signature">User 28 Interface Signature</a> 29</h3></div></div></div> 30<p> 31 The first attempt to accommodate the User Requirements might result in the 32 following fairly conventional interface: 33 </p> 34<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">></span> <span class="identifier">Out</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#1</span> 35<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">></span> <span class="identifier">Out</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">fallback</span><span class="special">);</span> <span class="comment">//#2</span> 36<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">></span> <span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">Out</span><span class="special">&</span> <span class="identifier">result_out</span><span class="special">,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#3</span> 37<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">></span> <span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">Out</span><span class="special">&</span> <span class="identifier">result_out</span><span class="special">,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">fallback</span><span class="special">);</span> <span class="comment">//#4</span> 38</pre> 39<p> 40 with the following behavior: 41 </p> 42<div class="orderedlist"><ol class="orderedlist" type="1"> 43<li class="listitem"> 44 returns the result or throws on failure (<span class="emphasis"><em>R3a</em></span>, <span class="emphasis"><em>R4</em></span>); 45 </li> 46<li class="listitem"> 47 does not throw, returns the result or the provided fallback (<span class="emphasis"><em>R3b</em></span>, 48 <span class="emphasis"><em>R5</em></span>, <span class="emphasis"><em>R5c</em></span> but not <span class="emphasis"><em>R5a</em></span>); 49 </li> 50<li class="listitem"> 51 does not throw, writes the result to <code class="computeroutput"><span class="identifier">result_out</span></code> 52 (when successful), returns indication of success or failure (<span class="emphasis"><em>R3b</em></span>, 53 <span class="emphasis"><em>R5</em></span>, <span class="emphasis"><em>R5a</em></span> but not <span class="emphasis"><em>R5c</em></span>); 54 </li> 55<li class="listitem"> 56 does not throw, writes the result to <code class="computeroutput"><span class="identifier">result_out</span></code> 57 (when successful) or the provided fallback, returns indication of success 58 or failure (<span class="emphasis"><em>R3b</em></span>, <span class="emphasis"><em>R5</em></span>, <span class="emphasis"><em>R5c</em></span> 59 and <span class="emphasis"><em>R5a</em></span>). 60 </li> 61</ol></div> 62<p> 63 The #3 and #4 signatures are special as they, in fact, return two things 64 -- the actual result (written into the <code class="computeroutput"><span class="identifier">result_out</span></code>) 65 and the indication of success or failure (returned by the functions). Given 66 that a reference to <code class="computeroutput"><span class="identifier">result_out</span></code> 67 is passed in, the actual <code class="computeroutput"><span class="identifier">result_out</span></code> 68 instance is constructed (storage allocated and initialized) outside the function 69 calls. 70 </p> 71<p> 72 Similar to the scenario described in the <a class="link" href="converter_signature.html" title="Converter Signature">Converter 73 Signature</a> section that results in an additional and unnecessary overhead. 74 Indeed, if the conversion operation succeeds, then the initialization value 75 is overridden (with the actual result), if it fails, then the value is either 76 overridden still (with the fallback) or is meaningless. 77 </p> 78<p> 79 To avoid the overhead we might again (as in the <a class="link" href="converter_signature.html" title="Converter Signature">Converter 80 Signature</a> section) deploy <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code> 81 and to change the signatures to 82 </p> 83<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">>&,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#3</span> 84<span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">>&,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#4</span> 85</pre> 86<p> 87 Now, when we look at #3, we can see that the indication of success or failure 88 is duplicated. Namely, it is returned from the function and is encapsulated 89 in <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">></span></code>. 90 Consequently, #3 can be further simplified to 91 </p> 92<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">>&,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#3</span> 93</pre> 94<p> 95 or expressed more idiomatically (in C++) as: 96 </p> 97<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">></span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#3</span> 98</pre> 99<p> 100 So far, we have arrived to the following set 101 </p> 102<pre class="programlisting"><span class="identifier">Out</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#1</span> 103<span class="identifier">Out</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#2</span> 104<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">></span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#3</span> 105<span class="keyword">bool</span> <span class="identifier">convert</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">>&,</span> <span class="identifier">In</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&);</span> <span class="comment">//#4</span> 106</pre> 107<p> 108 which as a whole looks quite ugly and, in fact, does not even compile as 109 #1 clashes with #3. The good thing though is that <span class="emphasis"><em>functionally</em></span> 110 #1 and #2 are not needed anymore as they are duplicates of the following 111 #3 deployments: 112 </p> 113<pre class="programlisting"><span class="identifier">Out</span> <span class="identifier">out1</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// #3 with #1 behavior</span> 114<span class="identifier">Out</span> <span class="identifier">out2</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback</span><span class="special">);</span> <span class="comment">// #3 with #2 behavior</span> 115</pre> 116<p> 117 Again, we are not discussing aesthetic aspects of the interface (or syntactic 118 sugar some might say, which might be very subjective). Instead, we are focusing 119 on the <span class="emphasis"><em>functional completeness</em></span> and so far we manage 120 to maintain the same <span class="emphasis"><em>functional completeness</em></span> with <span class="emphasis"><em>less</em></span>. 121 </p> 122<p> 123 Turns out, with a bit of effort, we can get away without the most complex 124 one -- #4 -- as well: 125 </p> 126<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">></span> <span class="identifier">out</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">);</span> 127<span class="keyword">bool</span> <span class="identifier">out_success</span> <span class="special">=</span> <span class="identifier">out</span> <span class="special">?</span> <span class="keyword">true</span> <span class="special">:</span> <span class="keyword">false</span><span class="special">;</span> 128<span class="identifier">Out</span> <span class="identifier">out_value</span> <span class="special">=</span> <span class="identifier">out</span><span class="special">.</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback</span><span class="special">);</span> 129</pre> 130<p> 131 So, ultimately we arrive to one and only 132 </p> 133<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">></span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&);</span> 134</pre> 135<p> 136 The important qualities of the API are that it is <span class="emphasis"><em>functionally-complete</em></span> 137 and the <span class="emphasis"><em>most efficient way</em></span> to deploy the chosen converter 138 signature (see the <a class="link" href="converter_signature.html" title="Converter Signature">Converter 139 Signature</a> section). Namely, the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">()</span></code> interface is routinely optimized out (elided) 140 when deployed as 141 </p> 142<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Out</span><span class="special">></span> <span class="identifier">out</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">);</span> 143</pre> 144<p> 145 The API has several deployment-related advantages. First, it says exactly 146 what it does. Given a conversion request is only a <span class="emphasis"><em>request</em></span>, 147 the API returns <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code> essentially saying "I'll 148 try but I might fail. Proceed as you find appropriate.". Honest and 149 simple. I prefer it to "I'll try. I might fail but you do not want to 150 know about it." or "I'll try. If I fail, you die." or variations 151 along these lines. :-) 152 </p> 153<p> 154 On a more serious note though the interface allows for batched conveyor-style 155 conversions. Namely, attempting to convert several values, in sequence, storing 156 the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code> results and, then, analyzing/validating 157 them (without losing the information if each individual conversion was successful 158 or not) in some semi-automated way. 159 </p> 160<p> 161 Again, that API does not have to be the only API <span class="emphasis"><em>Boost.Convert</em></span> 162 provides. However, that API is the only <span class="emphasis"><em>essential</em></span> API. 163 Other APIs are relatively easily derived from it. For example, 164 </p> 165<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Out</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">In</span><span class="special">></span> 166<span class="identifier">Out</span> 167<span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">in</span><span class="special">,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">fallback</span><span class="special">)</span> <span class="comment">//#2</span> 168<span class="special">{</span> 169 <span class="keyword">return</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">in</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback</span><span class="special">);</span> 170<span class="special">}</span> 171</pre> 172<p> 173 Given that it is extremely difficult (if not impossible) to come up with 174 a library API that could please everyone, we might as well settle on the 175 <span class="emphasis"><em>essential</em></span> API and let the users build their own APIs 176 (as in the example above) to satisfy their aesthetic preferences. 177 </p> 178<p> 179 Still, it needs to be acknowledged that <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code> 180 is a fairly new concept and some people are reluctant using it or find its 181 deployment unreasonably complicating. Consequently, <span class="emphasis"><em>Boost.Convert</em></span> 182 provides an alternative (more conventional) interface: 183 </p> 184<pre class="programlisting"><span class="identifier">Out</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Converter</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Out</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">fallback_value</span><span class="special">);</span> 185<span class="identifier">Out</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Converter</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Functor</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">fallback_functor</span><span class="special">);</span> 186<span class="identifier">Out</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">In</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">Converter</span> <span class="keyword">const</span><span class="special">&,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">throw_on_failure</span><span class="special">);</span> 187</pre> 188</div> 189<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 190<td align="left"></td> 191<td align="right"><div class="copyright-footer">Copyright © 2009-2016 Vladimir Batov<p> 192 Distributed under the Boost Software License, Version 1.0. See copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>. 193 </p> 194</div></td> 195</tr></table> 196<hr> 197<div class="spirit-nav"> 198<a accesskey="p" href="converter_signature.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../design_notes.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../supporting_tools.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 199</div> 200</body> 201</html> 202