Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/optional/doc/optional.html @ 33

Last change on this file since 33 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 71.2 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//SoftQuad Software//DTD HoTMetaL PRO 5.0::19981217::extensions to HTML 4.0//EN" "hmpro5.dtd">
2
3<HTML>
4
5<HEAD>
6<meta http-equiv="Content-Language" content="en-us">
7<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
8<meta name="ProgId" content="FrontPage.Editor.Document">
9<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
10<LINK REL="stylesheet" TYPE="text/css" HREF="../../../boost.css">
11<TITLE>Header </TITLE>
12</HEAD>
13
14<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080">
15<H2><IMG SRC="../../../boost.png" WIDTH="276" HEIGHT="86">Header &lt;<A
16HREF="../../../boost/optional/optional.hpp">boost/optional/optional.hpp</A>&gt; </H2>
17
18<H2>Contents</H2>
19<DL CLASS="page-index">
20  <DT><A HREF="#mot">Motivation</A></DT>
21  <DT><A HREF="#dev">Development</A></DT>
22  <DT><A HREF="#synopsis">Synopsis</A></DT>
23  <DT><A HREF="#semantics">Semantics</A></DT>
24  <DT><A HREF="#examples">Examples</A></DT>
25  <DT><A HREF="#ref">Optional references</A></DT>
26  <DT><A HREF="#refassign">Rebinding semantics for assignment of optional references</A></DT>
27  <DT><A HREF="#none">none_t and none</A></DT>
28  <DT><A HREF="#inplace">In-Place Factories</A></DT>
29  <DT><A HREF="#bool">A note about optional&lt;bool&gt;</A></DT>
30  <DT><A HREF="#exsafety">Exception Safety Guarantees</A></DT>
31  <DT><A HREF="#requirements">Type requirements</A></DT>
32  <DT><A HREF="#impl">Implementation Notes</A></DT>
33  <DT><A HREF="#porta">Dependencies and Portability</A></DT>
34  <DT><A HREF="#credits">Acknowledgment</A></DT>
35</DL>
36
37<HR>
38
39<H2><A NAME="mot"></A>Motivation</H2>
40
41<P>Consider these functions which should return a value but which might not have
42  a value to return:</P>
43<pre>(A) double sqrt(double n );
44(B) char get_async_input();
45(C) point polygon::get_any_point_effectively_inside();</pre>
46<P>There are different approaches to the issue of not having a value to return.</P>
47<P>A typical approach is to consider the existence of a valid return value as
48  a postcondition, so that if the function cannot compute the value to return,
49  it has either undefined behavior (and can use assert in a debug build)
50  or uses a runtime check and throws an exception if the postcondition is violated.
51  This is a reasonable choice for example, for function (A), because the
52  lack of a proper return value is directly related to an invalid parameter (out
53  of domain argument), so it is appropriate to require the callee to supply only
54  parameters in a valid domain for execution to continue normally.</P>
55<P>However, function (B), because of its asynchronous nature, does not fail just
56  because it can't find a value to return; so it is incorrect to consider
57  such a situation an error and assert or throw an exception. This function must
58  return, and somehow, must tell the callee that it is not returning a meaningful
59  value.</P>
60<P>A similar situation occurs with function (C): it is conceptually an error to
61  ask a <i>null-area</i> polygon to return a point inside itself, but in many
62  applications, it is just impractical for performance reasons to treat this as
63  an error (because detecting that the polygon has no area might be too expensive
64  to be required to be tested previously), and either an arbitrary point (typically
65  at infinity) is returned, or some efficient way to tell the callee that there
66  is no such point is used.</P>
67<P>There are various mechanisms to let functions communicate that the returned
68  value is not valid. One such mechanism, which is quite common since it has zero
69  or negligible overhead, is to use a special value which is reserved to communicate
70  this. Classical examples of such special values are EOF, string::npos, points
71  at infinity, etc...</P>
72<P>When those values exist, i.e. the return type can hold all meaningful values
73  <i>plus</i> the <i>signal</i> value, this mechanism is quite appropriate and
74  well known. Unfortunately, there are cases when such values do not exist. In
75  these cases, the usual alternative is either to use a wider type, such as 'int'
76  in place of 'char'; or a compound type, such as std::pair&lt;point,bool&gt;.
77</P>
78<P>Returning a std::pair&lt;T,bool&gt;, thus attaching a boolean flag to the result
79  which indicates if the result is meaningful, has the advantage that can be turned
80  into a consistent idiom since the first element of the pair can be whatever
81  the function would conceptually return. For example, the last two functions
82  could have the following interface:</P>
83<pre>std::pair&lt;char,bool&gt; get_async_input();
84std::pair&lt;point,bool&gt; polygon::get_any_point_effectively_inside();</pre>
85<p>These functions use a consistent interface for dealing with possibly inexistent
86  results:</p>
87<pre>std::pair&lt;point,bool&gt; p = poly.get_any_point_effectively_inside();
88if ( p.second )
89  flood_fill(p.first);
90</pre>
91
92<P>However, not only is this quite a burden syntactically, it is also error
93  prone since the user can easily use the function result (first element of the
94  pair) without ever checking if it has a valid value.</P>
95<P>Clearly, we need a better idiom.</P>
96
97<H2><A NAME="dev"></A>Development</H2>
98
99<h3><u>The models:</u></h3>
100<P>In C++, we can <i>declare</i> an object (a variable) of type T, and we can give this variable
101  an <i>initial value</i> (through an <i>initializer</i>. (c.f. 8.5)).<br>
102  When a declaration includes a non-empty initializer (an initial value is given), it is said that
103  the object has been <i><b>initialized</b></i>.<br>
104  If the declaration uses an empty initializer (no initial value is given),
105  and neither default nor value initialization applies, it is said that the object is
106  <i><b>uninitialized</b></i>. Its actual value exist but has an
107  <i>indeterminate initial value</i> (c.f. 8.5.9).<br>
108  <code>optional&lt;T&gt;</code> intends to formalize the notion of initialization
109(or lack of it)
110  allowing a program to test whether an object has been initialized and stating that access to
111  the value of an uninitialized object is undefined behavior. That is,
112  when a variable is declared as optional&lt;T&gt; and no initial value is given,
113  the variable is <i>formally</i> uninitialized. A formally uninitialized optional object has conceptually
114  no value at all and this situation can be tested at runtime. It is formally <i>
115undefined behavior</i>
116  to try to access the value of an uninitialized optional. An uninitialized optional can be <i>assigned</i> a      value, in which case its initialization state changes to initialized. Furthermore, given the formal
117  treatment of initialization states in optional objects, it is even possible to reset an optional to <i>uninitialized</i>.</P>
118<P>In C++ there is no formal notion of uninitialized objects, which
119  means that objects always have an initial value even if indeterminate.<br>
120  As discussed on the previous section, this has a drawback because you need additional
121  information to tell if an object has been effectively initialized.<br>
122  One of the typical ways in which this has been historically
123  dealt with is via a special value: EOF,npos,-1, etc... This is equivalent to adding
124  the special value to the set of possible values of a given type. This super set of
125  T plus some <i>nil_t</i>&mdash;were nil_t is some stateless POD-can be modeled in modern
126  languages as a <b>discriminated union</b> of <code>T</code> and <code>nil_t</code>.
127  Discriminated unions are often called <i>variants</i>. A variant has a <i>current type</i>,
128  which in our case is either <code>T</code> or <code>nil_t</code>.<br>
129  Using the <a href="../../../doc/html/variant.html">Boost.Variant</a> library, this model can be implemented
130  in terms of <code>boost::variant&lt;T,nil_t&gt;</code>.<br>
131  There is precedent for a discriminated union as a model for an optional value: the
132  <a href="http://www.haskell.org/"><u>Haskell</u></a> <b>Maybe</b> built-in type constructor.
133Thus, a discriminated union <code>T+nil_t</code> serves as a conceptual foundation.</p>
134<p>A <code>variant&lt;T,nil_t&gt;</code> follows naturally from the traditional idiom of extending
135the range of possible values adding an additional sentinel value with the special meaning of <i>Nothing. </i>
136However, this additional <i>Nothing</i> value is largely irrelevant for our purpose
137 since our goal is to formalize the notion of uninitialized objects and, while a special extended value <i>can</i> be used to convey that meaning, it is not strictly
138necessary in order to do so.</p>
139<p>The observation made in the last paragraph about the irrelevant nature of the additional <code>nil_t</code> with respect to
140<u>purpose</u> of optional&lt;T&gt; suggests
141an alternative model: a <i>container</i> that either has a value of T or nothing.
142</p>
143<p>As of this writing I don't know of any precedent for a variable-size fixed-capacity (of 1)
144stack-based container model for optional values, yet I believe this is the consequence of
145the lack of practical implementations of such a container rather than an inherent shortcoming
146of the container model.</p>
147<p>In any event, both the discriminated-union or the single-element container models serve as a conceptual
148ground for a class representing optional&mdash;i.e. possibly uninitialized&mdash;objects.<br>
149For instance, these models show the <i>exact</i> semantics required for a wrapper of optional values:</p>
150<p>Discriminated-union:</p>
151<blockquote>
152<li><b>deep-copy</b> semantics:  copies of the variant implies copies of the value.</li>
153<li><b>deep-relational</b> semantics: comparisons between variants matches both current types and values</li>
154<li>If the variant's current type is T, it is modeling an <i>initialized</i> optional.</li>
155<li>If the variant's current type is not T, it is modeling an <i>uninitialized</i> optional.</li>
156<li>Testing if the variant's current type is T models testing if the optional is initialized</li>
157<li>Trying to extract a T from a variant when its current type is not T, models the undefined
158behavior
159of trying to access the value of an uninitialized optional</li>
160</blockquote>
161<p>Single-element container:</p>
162<blockquote>
163<li><b>deep-copy</b> semantics:  copies of the container implies copies of the value.</li>
164<li><b>deep-relational</b> semantics: comparisons between containers compare container size and if match, contained value</li>
165<li>If the container is not empty (contains an object of type T), it is modeling an <i>initialized</i> optional.</li>
166<li>If the container is empty, it is modeling an <i>uninitialized</i> optional.</li>
167<li>Testing if the container is empty models testing if the optional is initialized</li>
168<li>Trying to extract a T from an empty container models the undefined behavior
169of trying to access the value of an uninitialized optional</li>
170</blockquote>
171
172<h3><u>The semantics:</u></h3>
173<p>Objects of type <code>optional&lt;T&gt;</code> are intended to be used in places where objects of type T would
174but which might be uninitialized. Hence, <code>optional&lt;T&gt;</code>'s purpose is to formalize the
175additional possibly uninitialized state.<br>
176From the perspective of this role, <code>optional&lt;T&gt;</code> can have the same operational semantics of T
177plus the additional semantics corresponding to this special state.<br>
178As such, <code>optional&lt;T&gt;</code> could be thought of as a <i>supertype</i> of T. Of course,
179we can't do that in C++, so we need to compose the desired semantics using a different mechanism.<br>
180Doing it the other way around, that is, making <code>optional&lt;T&gt;</code> a <i>subtype</i> of T is not only
181conceptually wrong but also impractical: it is not allowed to derive from a non-class type, such as a
182built-in type.</p>
183
184<p>We can draw from the purpose of optional&lt;T&gt; the required basic semantics:</p>
185
186<blockquote>
187<p><b>Default Construction:</b> To introduce a formally uninitialized wrapped
188object.</p>
189
190<p><b>Direct Value Construction via copy:</b> To introduce a formally
191initialized wrapped object whose value is obtained as a copy of some object.</p>
192
193<p><b>Deep Copy Construction:</b> To obtain a new yet equivalent wrapped
194object.</p>
195
196<p><b>Direct Value Assignment (upon initialized):</b> To assign a value to the wrapped object.</p>
197
198<p><b>Direct Value Assignment (upon uninitialized):</b> To initialize the wrapped object
199with a value obtained
200as a copy of some object.</p>
201
202<p><b>Assignment (upon initialized):</b> To assign to the wrapped object the value
203of another wrapped object.</p>
204
205<p><b>Assignment (upon uninitialized):</b> To initialize the wrapped object
206with value of another wrapped object.</p>
207
208<p><b>Deep Relational Operations (when supported by the type T):</b> To compare
209wrapped object values taking into account the presence of uninitialized
210states.</p>
211
212<p><b>Value access:</b> To unwrap the wrapped object.</p>
213
214<p><b>Initialization state query:</b> To determine if the object is formally
215initialized or not.</p>
216
217<p><b>Swap:</b> To exchange wrapped objects. (with whatever exception safety
218guarantees are provided by T's swap).</p>
219
220<p><b>De-initialization:</b> To release the wrapped object (if any) and leave
221the wrapper in the uninitialized state.</p>
222
223</blockquote>
224
225<p>Additional operations are useful, such as converting constructors and
226converting assignments, in-place construction and assignment, and safe value
227access via a pointer to the wrapped object or null.</p>
228<h3><u>The Interface:</u></h3>
229<p>Since the purpose of optional is to allow us to use objects with a formal
230uninitialized additional state, the interface could try to follow the interface
231of the underlying T type as much as possible. In order to choose the proper
232degree of adoption of the native T interface, the following must be noted: <br>
233Even if all the operations supported by an instance of type T are defined for
234the entire range of values for such a type, an optional&lt;T&gt; extends such a set of
235values with a new value for which most (otherwise valid) operations are not
236defined in terms of T.<br>
237Furthermore, since optional&lt;T&gt; itself is merely a T wrapper (modeling a T
238supertype), any attempt to define such operations upon uninitialized optionals
239will be totally artificial w.r.t. T.<br>
240This library chooses an interface which follows from T's interface only for
241those operations which are well defined (w.r.t the type T) even if any of the
242operands are uninitialized. These operations include: construction,
243copy-construction, assignment, swap and relational operations.<br>
244For the value access operations, which are undefined (w.r.t the type T) when the
245operand is uninitialized, a different interface is chosen (which will be
246explained next).<br>
247Also, the presence of the possibly uninitialized state requires additional
248operations not provided by T itself which are supported by a special interface.</p>
249<h3>Lexically-hinted Value Access in the presence of possibly untitialized
250optional objects: The operators * and -&gt;</h3>
251<p>A relevant feature of a pointer is that it can have a <b>null
252  pointer value</b>. This is a <i>special</i> value which is used to indicate that the
253  pointer is not referring to any object at all. In other words, null pointer
254  values convey the notion of inexistent objects.</P>
255<P>This meaning of the null pointer value allowed pointers to became a <i>de facto</i> standard
256  for handling optional objects because all you have to do to refer to a value which you
257  don't really have is to use a null pointer value of the appropriate type.
258  Pointers have been used for decades&mdash;from the days of C APIs to modern C++ libraries&mdash;to
259  <i>refer</i> to optional (that is, possibly inexistent) objects; particularly
260  as optional arguments to a function, but also quite often as optional data members.</P>
261<P>The possible presence of a null pointer value makes the operations that access the
262  pointee's value possibly undefined, therefore, expressions which use dereference
263  and access operators, such as: <code>( *p = 2 )</code> and <code>( p-&gt;foo())</code>,
264  implicitly convey the notion of optionality, and this information is tied to
265  the <i>syntax</i> of the expressions. That is, the presence of operators * and -&gt; tell by
266  themselves&mdash;without any additional context&mdash;that the expression will be undefined unless
267  the implied pointee actually exist.</P>
268<P>Such a <i>de facto</i> idiom for referring to optional objects can be formalized in the form of a
269concept: the <a href="../../utility/OptionalPointee.html">OptionalPointee</a> concept.<br>
270This concept captures the syntactic usage of operators *, -> and conversion to bool to convey
271the notion of optionality.</P>
272<P>However, pointers are good to <u>refer</u> to optional objects, but not particularly good
273to handle the optional objects in all other respects, such as initializing or moving/copying
274them. The problem resides in the shallow-copy of pointer semantics: if you need to
275  effectively move or copy the object, pointers alone are not enough. The problem
276  is that copies of pointers do not imply copies of pointees. For example, as
277  was discussed in the motivation, pointers alone cannot be used to return optional
278  objects from a function because the object must move outside from the function and
279  into the caller's context.<br>
280  A solution to the shallow-copy problem that is often used is to resort to dynamic
281  allocation and use a smart pointer to automatically handle the details of this.
282  For example, if a function is to optionally return an object X, it can use shared_ptr&lt;X&gt;
283  as the return value. However, this requires dynamic allocation of X. If X is
284  a built-in or small POD, this technique is very poor in terms of required resources.
285  Optional objects are essentially values so it is very convenient to be able to use automatic
286  storage and deep-copy semantics to manipulate optional values just as we do with ordinary
287  values. Pointers do not have this semantics, so are inappropriate for the initialization and
288  transport of optional values, yet are quite convenient for handling the access to the
289  possible undefined value because of the idiomatic aid present in the OptionalPointee
290  concept incarnated by pointers.
291</p>
292<h4>Optional&lt;T&gt; as a model of OptionalPointee</h4>
293<P>For value access operations optional&lt;&gt; uses operators * and -&gt; to lexically
294warn about the possibly uninitialized state appealing to the familiar pointer
295semantics w.r.t. to null pointers.<br>
296<u><b>However, it is particularly important to note that optional<> objects are not pointers. optional&lt;&gt;
297is not, and does not model, a pointer</b></u><b>.</b>
298<P>For instance, optional&lt;&gt; does not have shallow-copy so does not alias: two different optionals
299  never refer to the <i>same</i> value unless T itself is a reference (but may have <i>equivalent</i> values).<br>
300  The difference between an optional&lt;T&gt; and a pointer must be kept in mind, particularly
301  because the semantics of relational operators are different: since optional&lt;T&gt;
302  is a value-wrapper, relational operators are deep: they compare optional values;
303  but relational operators for pointers are shallow:  they do not compare pointee values.<br>
304  As a result, you might be able to replace optional&lt;T&gt; by T* on some situations but
305  not always. Specifically, on generic code written for both, you cannot use relational
306  operators directly, and must use the template functions
307  <a href="../../utility/OptionalPointee.html#equal">equal_pointees()</a> and
308  <a href="../../utility/OptionalPointee.html#less">less_pointees()</a> instead.
309<HR>
310
311<H2><A NAME="synopsis">Synopsis</A></H2>
312
313<PRE>namespace boost {
314
315template&lt;class T>
316class optional
317{
318  public :
319
320    <i><u>(If T is of reference type, the parameters and results by reference are by value)</u></i>
321
322    optional () ;
323
324    optional ( none_t ) ;
325
326    optional ( T const&amp; v ) ;
327
328    optional ( bool condition, T const&amp; v ) ;  <u><i>[new in 1.34]</u></i>
329   
330    optional ( optional const&amp; rhs ) ;
331
332    template&lt;class U&gt; explicit optional ( optional&lt;U&gt; const&amp; rhs ) ;
333
334    template&lt;class InPlaceFactory&gt; explicit optional ( InPlaceFactory const&amp; f ) ;
335
336    template&lt;class TypedInPlaceFactory&gt; explicit optional ( TypedInPlaceFactory const&amp; f ) ;
337
338    optional&amp; operator = ( none_t ) ;
339
340    optional&amp; operator = ( T const&amp; v ) ;
341
342    optional&amp; operator = ( optional const&amp; rhs ) ;
343
344    template&lt;class U&gt; optional&amp; operator = ( optional&lt;U&gt; const&amp rhs ) ;
345
346    template&lt;class InPlaceFactory&gt; optional&amp; operator = ( InPlaceFactory const&amp f ) ;
347
348    template&lt;class TypedInPlaceFactory&gt; optional&amp; operator = ( TypedInPlaceFactory const&amp f ) ;
349
350    T const& get() const ;
351    T&       get() ;
352
353    T const&amp; get_value_or( T const&amp; default ) const ;  <u><i>[new in 1.34]</u></i>
354   
355    T const* operator -&gt;() const ;
356    T*       operator -&gt;() ;
357
358    T const&amp; operator *() const ;
359    T&amp;       operator *() ;
360
361    T const* get_ptr() const ;
362    T*       get_ptr() ;
363
364    operator <i>unspecified-bool-type</i>() const ;
365
366    bool operator!() const ;
367
368    <i><u>deprecated methods</u></i>
369
370    void reset() ; (deprecated)
371    void reset ( T const&amp; ) ; (deprecated)
372    bool is_initialized() const ; (deprecated)
373
374} ;
375
376template&lt;class T&gt; inline bool operator == ( optional&lt;T&gt; const& x, optional&lt;T&gt; const& y ) ;
377
378template&lt;class T&gt; inline bool operator != ( optional&lt;T&gt; const& x, optional&lt;T&gt; const& y ) ;
379
380template&lt;class T&gt; inline bool operator <  ( optional&lt;T&gt; const& x, optional&lt;T&gt; const& y ) ;
381
382template&lt;class T&gt; inline bool operator >  ( optional&lt;T&gt; const& x, optional&lt;T&gt; const& y ) ;
383
384template&lt;class T&gt; inline bool operator <= ( optional&lt;T&gt; const& x, optional&lt;T&gt; const& y ) ;
385
386template&lt;class T&gt; inline bool operator >= ( optional&lt;T&gt; const& x, optional&lt;T&gt; const& y ) ;
387
388template&lt;class T&gt; inline bool operator == ( optional&lt;T&gt; const& x, T const& n ) ; <u><i>[new in 1.34]</u></i>
389
390template&lt;class T&gt; inline bool operator != ( optional&lt;T&gt; const& x, T const& n ) ; <u><i>[new in 1.34]</u></i>
391
392template&lt;class T&gt; inline bool operator <  ( optional&lt;T&gt; const& x, T const& n ) ; <u><i>[new in 1.34]</u></i>
393
394template&lt;class T&gt; inline bool operator >  ( optional&lt;T&gt; const& x, T const& n ) ; <u><i>[new in 1.34]</u></i>
395
396template&lt;class T&gt; inline bool operator <= ( optional&lt;T&gt; const& x, T const& n ) ; <u><i>[new in 1.34]</u></i>
397
398template&lt;class T&gt; inline bool operator >= ( optional&lt;T&gt; const& x, T const& n ) ; <u><i>[new in 1.34]</u></i>
399
400template&lt;class T&gt; inline bool operator == ( T const& n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
401
402template&lt;class T&gt; inline bool operator != ( T const& n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
403
404template&lt;class T&gt; inline bool operator <  ( T const& n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
405
406template&lt;class T&gt; inline bool operator >  ( T const& n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
407
408template&lt;class T&gt; inline bool operator <= ( T const& n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
409
410template&lt;class T&gt; inline bool operator >= ( T const& n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
411
412template&lt;class T&gt; inline bool operator == ( optional&lt;T&gt; const& x, none_t n ) ; <u><i>[new in 1.34]</u></i>
413
414template&lt;class T&gt; inline bool operator != ( optional&lt;T&gt; const& x, none_t n ) ; <u><i>[new in 1.34]</u></i>
415
416template&lt;class T&gt; inline bool operator <  ( optional&lt;T&gt; const& x, none_t n ) ; <u><i>[new in 1.34]</u></i>
417
418template&lt;class T&gt; inline bool operator >  ( optional&lt;T&gt; const& x, none_t n ) ; <u><i>[new in 1.34]</u></i>
419
420template&lt;class T&gt; inline bool operator <= ( optional&lt;T&gt; const& x, none_t n ) ; <u><i>[new in 1.34]</u></i>
421
422template&lt;class T&gt; inline bool operator >= ( optional&lt;T&gt; const& x, none_t n ) ; <u><i>[new in 1.34]</u></i>
423
424template&lt;class T&gt; inline bool operator == ( none_t n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
425
426template&lt;class T&gt; inline bool operator != ( none_t n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
427
428template&lt;class T&gt; inline bool operator <  ( none_t n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
429
430template&lt;class T&gt; inline bool operator >  ( none_t n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
431
432template&lt;class T&gt; inline bool operator <= ( none_t n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
433
434template&lt;class T&gt; inline bool operator >= ( none_t n, optional&lt;T&gt; const& y ) ; <u><i>[new in 1.34]</u></i>
435
436template&lt;class T&gt; inline optional&lt;T&gt; make_optional ( T const& v ) ;  <u><i>[new in 1.34]</u></i>
437
438template&lt;class T&gt; inline optional&lt;T&gt; make_optional ( bool condition, T const& v ) ;  <u><i>[new in 1.34]</u></i>
439
440template&lt;class T&gt; inline T const&amp; get_optional_value_or ( optional&lt;T&gt; const& opt, T const& default ) ;  <u><i>[new in 1.34]</u></i>
441
442template&lt;class T&gt; inline T const& get ( optional&lt;T&gt; const& opt ) ;
443
444template&lt;class T&gt; inline T& get ( optional&lt;T&gt; & opt ) ;
445
446template&lt;class T&gt; inline T const* get ( optional&lt;T&gt; const* opt ) ;
447
448template&lt;class T&gt; inline T* get ( optional&lt;T&gt;* opt ) ;
449
450template&lt;class T&gt; inline T const* get_pointer ( optional&lt;T&gt; const& opt ) ;
451
452template&lt;class T&gt; inline T* get_pointer ( optional&lt;T&gt; & opt ) ;
453
454template&lt;class T&gt; inline void swap( optional&lt;T&gt;& x, optional&lt;T&gt;&amp; y ) ;
455
456} // namespace boost
457</PRE>
458
459<HR>
460
461<h2><A NAME="semantics">Detailed Semantics</a></h2>
462
463<p><b><u>NOTES: </u></b></p>
464
465<p><b>Because T might be of reference type, in the sequel, those entries whose
466semantic depends on T being of reference type or not will be distinguished using
467the following convention:<br>
468If the entry reads: optional&lt;T (not a ref)&gt;, the description corresponds only to
469the case where T is not of reference type.<br>
470If the entry reads: optional&lt;T&amp;&gt;, the description corresponds only to the case
471where T is of reference type. <br>
472If the entry reads: optional&lt;T&gt;, the description is the same for both cases.</b></p>
473
474<p><i>The following section contains various assert() which are used only to
475show the postconditions as sample code. It is not implied that the type T must
476support each particular expression but that if the expression is supported, the
477implied condition holds.</i></p>
478
479<hr>
480
481<pre>optional&lt;T&gt;::optional();</pre>
482<blockquote>
483<p><b>Effect:</b> Default-Constructs an <b>optional</b>.</p>
484<p><b>Postconditions:</b> <b>*this</b> is <u>uninitialized</u>.</p>
485<p><b>Throws:</b> Nothing.</p>
486<p><b>Notes:</b> T's default constructor <u><i>is not</i></u> called.</p>
487<p><b>Example:</b></p>
488  <blockquote>
489    <pre>optional&lt;T&gt; def ;
490assert ( !def ) ;</pre>
491</blockquote>
492</blockquote>
493
494<HR>
495
496<pre>optional&lt;T&gt;::optional( none_t );</pre>
497<blockquote>
498<p><b>Effect:</b> Constructs an <b>optional</b> uninitialized.</p>
499<p><b>Postconditions:</b> <b>*this</b> is <u>uninitialized</u>.</p>
500<p><b>Throws:</b> Nothing.</p>
501<p><b>Notes:</b></p>
502<blockquote>
503<p>T's default constructor <u><i>is not</i></u> called.<br>
504The
505expression <code>boost::none</code> denotes an instance of <code>boost::none_t</code> that can be
506used as the parameter.</p>
507</blockquote>
508<p><b>Example:</b></p>
509  <blockquote>
510<pre>
511#include &lt;boost/none.hpp&gt;
512optional&lt;int&gt; n(boost::none) ;
513assert ( !n ) ;
514</pre>
515</blockquote>
516</blockquote>
517
518<HR>
519
520<pre>optional&lt;T <i>(not a ref)</i>&gt;::optional( T const&amp; v )</pre>
521<blockquote>
522<p><b>Effect:</b> Directly-Constructs an <b>optional</b>.</p>
523<p><b>Postconditions:</b> <b>*this</b> is <u>initialized</u> and its value is a <i>copy</i> of 'v'.</p>
524<p><b>Throws:</b> Whatever T::T( T const&amp; ) throws.</p>
525<p><b>Notes: </b> T::T( T const&amp; ) is called.</p>
526<p><b>Exception Safety:</b> Exceptions can only be thrown during T::T( T const&amp; );
527in that case, this constructor has no effect.
528</p>
529<p><b>Example:</b></p>
530<blockquote>
531<pre>
532T v;
533optional&lt;T&gt; opt(v);
534assert ( *opt == v ) ;
535</pre>
536</blockquote>
537</blockquote>
538
539<HR>
540
541<pre>optional&lt;T&amp;&gt;::optional( T&amp; ref )</pre>
542<blockquote>
543<p><b>Effect:</b> Directly-Constructs an <b>optional</b>.</p>
544<p><b>Postconditions:</b> <b>*this</b> is <u>initialized</u> and its value is an
545instance of an internal type wrapping the reference 'ref'.</p>
546<p><b>Throws:</b> Nothing.</p>
547<p><b>Example:</b></p>
548<blockquote>
549<pre>
550T v;
551T&amp; vref = v ;
552optional&lt;T&amp;&gt; opt(vref);
553assert ( *opt == v ) ;
554++ v ; // mutate referee
555assert (*opt == v);
556</pre>
557</blockquote>
558</blockquote>
559
560<HR>
561
562<pre>optional&lt;T <i>(not a ref)</i>&gt;::optional( bool condition, T const&amp; v ) ;
563optional&lt;T&amp;&gt;           ::optional( bool condition, T&amp;       v ) ;
564</pre>
565
566<blockquote>
567<p>If <i>condition</i> is <code>true</code>, same as:</p>
568<pre>optional&lt;T <i>(not a ref)</i>&gt;::optional( T const&amp; v )
569optional&lt;T&amp;&gt;           ::optional( T&amp;       v )
570</pre>
571<p>otherwise, same as:</p>
572<pre>
573optional&lt;T <i>(not a ref)</i>&gt;::optional()
574optional&lt;T&amp;&gt;           ::optional()
575</pre>
576</blockquote>
577
578<HR>
579
580<pre>optional&lt;T <i>(not a ref)</i>&gt;::optional( optional const&amp; rhs );</pre>
581<blockquote>
582<p><b>Effect:</b> Copy-Constructs an <b>optional</b>.</p>
583<p><b>Postconditions:</b> If <b>rhs</b> is initialized, <b>*this</b> is initialized
584and its value is a <i>copy</i> of the value of <b>rhs</b>; else <b>*this</b>
585is uninitialized.</p>
586<p><b>Throws:</b> Whatever T::T( T const& ) throws.</p>
587<p><b>Notes:</b> If <b>rhs</b> is initialized, T::T(T const&amp; ) is called.</p>
588<p><b>Exception Safety:</b> Exceptions can only be thrown during T::T( T const& );
589in that case, this constructor has no effect.
590</p>
591<p><b>Example:</b></p>
592<blockquote>
593<pre>
594optional&lt;T&gt; uninit ;
595assert (!uninit);
596
597optional&lt;T&gt; uinit2 ( uninit ) ;
598assert ( uninit2 == uninit );
599
600optional&lt;T&gt; init( T(2) );
601assert ( *init == T(2) ) ;
602
603optional&lt;T&gt; init2 ( init ) ;
604assert ( init2 == init ) ;
605</pre>
606
607</blockquote>
608</blockquote>
609
610<HR>
611
612<pre>optional&lt;T&amp;&gt;::optional( optional const&amp; rhs );</pre>
613<blockquote>
614<p><b>Effect:</b> Copy-Constructs an <b>optional</b>.</p>
615<p><b>Postconditions:</b> If <b>rhs</b> is initialized, <b>*this</b> is initialized
616and its value is another reference to the same object referenced by <b>*rhs</b>; else <b>*this</b>
617is uninitialized.</p>
618<p><b>Throws:</b> Nothing.</p>
619<p><b>Notes:</b> If <b>rhs</b> is initialized, both <b>*this</b> and <b>*rhs</b> will
620reefer to the same object<b> </b>(they alias).</p>
621<p><b>Example:</b></p>
622<blockquote>
623<pre>
624optional&lt;T&amp;&gt; uninit ;
625assert (!uninit);
626
627optional&lt;T&amp;&gt; uinit2 ( uninit ) ;
628assert ( uninit2 == uninit );
629
630T v = 2 ; T&amp; ref = v ;
631optional&lt;T&gt; init(ref);
632assert ( *init == v ) ;
633
634optional&lt;T&gt; init2 ( init ) ;
635assert ( *init2 == v ) ;
636
637v = 3 ;
638
639assert ( *init  == 3 ) ;
640assert ( *init2 == 3 ) ;
641
642
643</pre>
644
645</blockquote>
646</blockquote>
647
648<HR>
649
650<pre>template&lt;U&gt; explicit optional&lt;T <i>(not a ref)</i>&gt;::optional( optional&lt;U&gt; const&amp; rhs );</pre>
651<blockquote>
652<p><b>Effect:</b> Copy-Constructs an <b>optional</b>.</p>
653<p><b>Postconditions:</b> If <b>rhs</b> is initialized, <b>*this</b> is initialized
654    and its value is a <i>copy</i> of the value of <b>rhs</b> <i>converted</i>
655    to type T; else <b>*this</b> is uninitialized.
656</p>
657<p><b>Throws:</b> Whatever T::T( U const& ) throws.</p>
658<p><b>Notes:</b> T::T( U const& ) is called if <b>rhs</b> is initialized, which requires
659a valid conversion from U to T.
660</p>
661<p><b>Exception Safety:</b> Exceptions can only be thrown during T::T( U const& );
662in that case, this constructor has no effect.
663</p>
664<p><b>Example:</b></p>
665<blockquote>
666
667<pre>
668optional&lt;double&gt; x(123.4);
669assert ( *x == 123.4 ) ;
670
671optional&lt;int&gt; y(x) ;
672assert( *y == 123 ) ;
673</pre>
674</blockquote>
675</blockquote>
676
677<HR>
678
679<pre>template&lt;<i>InPlaceFactory</i>&gt; explicit optional&lt;T <i>(not a ref)</i>&gt;::optional( <i>InPlaceFactory</i> const&amp; f );</pre>
680
681<pre>template&lt;<i>TypedInPlaceFactory</i>&gt; explicit optional&lt;T <i>(not a ref)</i>&gt;::optional( <i>TypedInPlaceFactory</i> const&amp; f );</pre>
682<blockquote>
683<p><b>Effect:</b> Constructs an <b>optional</b> with a value of T obtained from
684the factory.</p>
685<p><b>Postconditions:</b>&nbsp; <b>*this</b> is <u>initialized</u> and its value is
686<i>directly given</i> from the factory 'f' (i.e., the value<u> is not copied</u>).</p>
687<p><b>Throws:</b> Whatever the T constructor called by the factory throws.</p>
688<p><b>Notes:</b> See <A HREF="#inplace">In-Place Factories</A></p>
689<p><b>Exception Safety:</b> Exceptions can only be thrown during the call to the
690T constructor used by the factory;
691in that case, this constructor has no effect.
692</p>
693<p><b>Example:</b></p>
694<blockquote>
695
696<pre>
697class C { C ( char, double, std::string ) ; } ;
698
699C v('A',123.4,&quot;hello&quot;);
700
701optional&lt;C&gt; x( in_place   ('A', 123.4, &quot;hello&quot;) ); // InPlaceFactory used
702optional&lt;C&gt; y( in_place&lt;C&gt;('A', 123.4, &quot;hello&quot;) ); // TypedInPlaceFactory used
703
704assert ( *x == v ) ;
705assert ( *y == v ) ;
706
707</pre>
708</blockquote>
709</blockquote>
710
711<HR>
712
713<pre>optional&amp; optional&lt;T</i>&gt;::operator= ( none_t n ) ;</pre>
714<blockquote>
715<p><b>Effect:</b> Same as opeator=(optional const&amp; rhs), when rhs is default-constructed (uninitialized).</p>
716<p><b>Postconditions:</b> <b>*this</b> is uninitialized</p>
717<p><b>Example:</b></p>
718<blockquote>
719<pre>
720#include &lt;boost/none.hpp&gt;
721
722optional&lt;int&gt; def ;
723optional&lt;int&gt; opt(123) ;
724
725opt = boost::none ;
726
727assert ( opt == def ) ;
728</pre>
729</blockquote>
730</blockquote>
731
732<HR>
733
734<pre>optional&amp; optional&lt;T <i>(not a ref)</i>&gt;::operator= ( T const&amp; rhs ) ;</pre>
735<blockquote>
736<p><b>Effect:</b> Assigns the value 'rhs' to an <b>optional</b>.</p>
737<p><b>Postconditions:</b> <b>*this</b> is initialized
738and its value is a <i>copy</i> of <b>rhs.</b></p>
739<p><b>Throws:</b> Whatever T::operator=( T const& ) or T::T(T const&amp;) throws.</p>
740<p><b>Notes:</b> If <b>*this</b> was initialized, T's assignment operator is
741used, otherwise, its copy-constructor is used.</p>
742<p><b>Exception Safety:</b> In the event of an exception, the initialization
743state of <b>*this</b> is unchanged and its value unspecified as far as optional
744is concerned (it is up to T's operator=()) [If <b>*this</b> is initially
745uninitialized and T's <i>copy constructor</i> fails, <b>*this</b> is left
746properly uninitialized]</p>
747<p><b>Example:</b></p>
748<blockquote>
749<pre>
750T x;
751optional&lt;T&gt; def ;
752optional&lt;T&gt; opt(x) ;
753
754T y;
755def = y ;
756assert ( *def == y ) ;
757opt = y ;
758assert ( *opt == y ) ;</pre>
759</blockquote>
760</blockquote>
761
762<HR>
763
764<pre>optional&lt;T&amp;&gt;&amp; optional&lt;T&amp;&gt;::operator= ( T&amp; const&amp; rhs ) ;</pre>
765<blockquote>
766<p><b>Effect:</b> (Re)binds thee wrapped reference.</p>
767<p><b>Postconditions:</b> <b>*this</b> is initialized
768and it references the same object referenced by <b>rhs.</b></p>
769<p><b>Notes:</b> If <b>*this</b> was initialized, is is <i>rebound</i> to the
770new object. See <A HREF="#refassign">here</a> for details on this behavior.</p>
771<p><b>Example:</b></p>
772<blockquote>
773<pre>
774int a = 1 ;
775int b = 2 ;
776T&amp; ra = a ;
777T&amp; rb = b ;
778optional&lt;int&amp;&gt; def ;
779optional&lt;int&amp;&gt; opt(ra) ;
780
781def = rb ; // binds 'def' to 'b' through 'rb'
782assert ( *def == b ) ;
783*def = a ; // changes the value of 'b' to a copy of the value of 'a'
784assert ( b == a ) ;
785int c = 3;
786int&amp; rc = c ;
787opt = rc ; // REBINDS to 'c' through 'rc'
788c = 4 ;
789assert ( *opt == 4 ) ;
790</pre>
791</blockquote>
792</blockquote>
793
794<HR>
795
796<pre>optional&amp; optional&lt;T <i>(not a ref)</i>&gt;::operator= ( optional const&amp; rhs ) ;</pre>
797<blockquote>
798<p><b>Effect:</b> Assigns another <b>optional</b> to an <b>optional</b>.</p>
799<p><b>Postconditions:</b> If <b>rhs</b> is initialized, <b>*this</b> is initialized
800and its value is a <i>copy</i> of the value of <b>rhs</b>; else <b>*this</b>
801is uninitialized.
802</p>
803<p><b>Throws:</b> Whatever T::operator( T const&amp;) or&nbsp; T::T( T const& ) throws.</p>
804<p><b>Notes:</b> If both<b> *this</b> and <b>rhs</b> are initially initialized,
805T's <i>assignment</i> <i>operator</i> is used. If <b>*this</b> is initially initialized but <b>
806rhs</b> is uninitialized, T's <i>destructor</i> is called. If <b>*this</b> is initially
807uninitialized but rhs is initialized, T's <i>copy constructor</i> is called.
808</p>
809<p><b>Exception Safety:</b> In the event of an exception, the initialization
810state of <b>*this</b> is unchanged and its value unspecified as far as optional
811is concerned (it is up to T's operator=()) [If <b>*this</b> is initially
812uninitialized and T's <i>copy constructor</i> fails, <b>*this</b> is left
813properly uninitialized]</p>
814<p><b>Example:</b></p>
815<blockquote>
816    <pre>T v;
817optional&lt;T&gt; opt(v);
818optional&lt;T&gt; def ;
819
820opt = def ;
821assert ( !def ) ;
822// previous value (copy of 'v') destroyed from within 'opt'.
823
824</pre>
825</blockquote>
826</blockquote>
827
828<HR>
829
830<pre>optional&lt;T&amp;&gt; &amp; optional&lt;T&amp;&gt;::operator= ( optional&lt;T&amp;&gt; const&amp; rhs ) ;</pre>
831<blockquote>
832<p><b>Effect:</b> (Re)binds thee wrapped reference.</p>
833<p><b>Postconditions:</b> If <b>*rhs</b> is initialized, *<b>this</b> is initialized
834and it references the same object referenced by <b>*rhs</b>; otherwise, <b>*this</b> 
835is uninitialized (and references no object).</p>
836<p><b>Notes:</b> If <b>*this</b> was initialized and so is <b>*rhs</b>, <b>this</b> 
837is is <i>rebound</i> to the new object. See <A HREF="#refassign">here</a> for details on this
838behavior.</p>
839<p><b>Example:</b></p>
840<blockquote>
841    <pre>int a = 1 ;
842int b = 2 ;
843T&amp; ra = a ;
844T&amp; rb = b ;
845optional&lt;int&amp;&gt; def ;
846optional&lt;int&amp;&gt; ora(ra) ;
847optional&lt;int&amp;&gt; orb(rb) ;
848
849def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb'
850assert ( *def == b ) ;
851*def = ora ; // changes the value of 'b' to a copy of the value of 'a'
852assert ( b == a ) ;
853int c = 3;
854int&amp; rc = c ;
855optional&lt;int&amp;&gt; orc(rc) ;
856ora = orc ; // REBINDS ora to 'c' through 'rc'
857c = 4 ;
858assert ( *ora == 4 ) ;
859</pre>
860</blockquote>
861</blockquote>
862
863<HR>
864
865<pre>template&lt;U&gt; optional&amp; optional&lt;T <i>(not a ref)</i>&gt;::operator= ( optional&lt;U&gt; const&amp; rhs ) ;</pre>
866<blockquote>
867<p><b>Effect:</b> Assigns another <i>convertible</i> <b>optional</b> to an <b>optional</b>.</p>
868<p><b>Postconditions:</b> If <b>rhs</b> is initialized, <b>*this</b> is initialized
869and its value is a <i>copy</i> of the value of <b>rhs</b> <i>converted</i>
870to type T; else <b>*this</b> is uninitialized.
871</p>
872<p><b>Throws:</b> Whatever T::operator=( U const&amp; ) or T::T( U const& ) throws.</p>
873<p><b>Notes:</b> If both<b> *this</b> and <b>rhs</b> are initially initialized,
874T's <i>assignment</i> <i>operator</i> (from U) is used. If <b>*this</b> is initially initialized but <b>
875rhs</b> is uninitialized, T's <i>destructor</i> is called. If <b>*this</b> is initially
876uninitialized but rhs is initialized, T's <i>converting constructor</i> (from U) is called.
877</p>
878<p><b>Exception Safety:</b> In the event of an exception, the initialization
879state of <b>*this</b> is unchanged and its value unspecified as far as optional
880is concerned (it is up to T's operator=()) [If <b>*this</b> is initially
881uninitialized and T's <i>converting constructor</i> fails, <b>*this</b> is left
882properly uninitialized]</p>
883<p><b>Example:</b></p>
884<blockquote>
885    <pre>T v;
886optional&lt;T&gt; opt0(v);
887optional&lt;U&gt; opt1;
888
889opt1 = opt0 ;
890assert ( *opt1 == static_cast&lt;U&gt;(v) ) ;
891</pre>
892</blockquote>
893</blockquote>
894
895<HR>
896<pre>void optional&lt;T <i>(not a ref)</i>&gt;::reset( T const&amp v ) ;</pre>
897<blockquote>
898<p><b>Deprecated:</b> same as operator= ( T const&amp; v) ;</p>
899</blockquote>
900
901<HR>
902<pre>void optional&lt;T&gt;::reset() ;</pre>
903<blockquote>
904<p><b>Deprecated: </b>Same as operator=( none_t n);</p>
905</blockquote>
906
907<HR>
908
909<pre>T const&amp; optional&lt;T <i>(not a ref)</i>&gt;::operator*() const ;
910T&amp;       optional&lt;T<i> (not a ref)</i>&gt;::operator*();</pre>
911
912<pre>T const&amp; optional&lt;T <i>(not a ref)</i>&gt;::get() const ;
913T&amp;       optional&lt;T <i>(not a ref)</i>&gt;::get() ;
914
915inline T const&amp; get ( optional&lt;T<i> (not a ref)</i>&gt; const&amp; ) ;
916inline T&amp;       get ( optional&lt;T <i>(not a ref)</i>&gt; &amp;) ;
917</pre>
918<blockquote>
919<p><b>Requirements: *this</b> is initialized</p>
920<p><b>Returns:</b> A reference to the contained value</p>
921<p><b>Throws:</b> Nothing.</p>
922<p><b>Notes:</b> The requirement is asserted via BOOST_ASSERT().</p>
923<p><b>Example:</b></p>
924<blockquote>
925    <pre>T v ;
926optional&lt;T&gt; opt ( v );
927T const&amp; u = *opt;
928assert ( u == v ) ;
929T w ;
930*opt = w ;
931assert ( *opt == w ) ;
932</pre>
933  </blockquote>
934    <pre></pre>
935</blockquote>
936
937<HR>
938
939
940<pre>T const&amp; optional&lt;T&amp;&gt;::operator*() const ;
941T      &amp; optional&lt;T<i>&amp;</i>&gt;::operator*();</pre>
942
943<pre>T const&amp; optional&lt;T&amp;&gt;::get() const ;
944T&amp;       optional&lt;T&amp;&gt;::get() ;
945
946inline T const&amp; get ( optional&lt;T<i>&amp;</i>&gt; const&amp; ) ;
947inline T&amp;       get ( optional&lt;T&amp;&gt; &amp;) ;
948</pre>
949<blockquote>
950<p><b>Requirements: *this</b> is initialized</p>
951<p><b>Returns:</b> <u>The</u> reference contained.</p>
952<p><b>Throws:</b> Nothing.</p>
953<p><b>Notes:</b> The requirement is asserted via BOOST_ASSERT().</p>
954<p><b>Example:</b></p>
955<blockquote>
956    <pre>T v ;
957T&amp; vref = v ;
958optional&lt;T&amp;&gt; opt ( vref );
959T const&amp; vref2 = *opt;
960assert ( vref2 == v ) ;
961++ v ;
962assert ( *opt == v ) ;</pre>
963  </blockquote>
964</blockquote>
965
966<HR>
967
968<pre>T const&amp; optional&lt;T&gt;::get_value_or( T const&amp; default) const ;
969T&amp;       optional&lt;T&gt;::get_value_or( T&amp;       default ) ;
970
971inline T const&amp; get_optional_value_or ( optional&lt;T&gt; const&amp; o, T const&amp; default ) ;
972inline T&amp;       get_optional_value_or ( optional&lt;T&gt;&amp;       o, T&amp;       default ) ;
973</pre>
974<blockquote>
975<p><b>Returns:</b> A reference to the contained value (which can be itself a reference), if any, or <code>default</code></p>
976<p><b>Throws:</b> Nothing.</p>
977<p><b>Example:</b></p>
978<blockquote>
979    <pre>T v, z ;
980optional&lt;T&gt; def;
981T const&amp; y = def.get_value_or(z);
982assert ( y == z ) ;
983
984optional&lt;T&gt; opt ( v );
985T const&amp; u = get_optional_value_or(opt,z);
986assert ( u == v ) ;
987assert ( u != z ) ;
988</pre>
989  </blockquote>
990    <pre></pre>
991</blockquote>
992
993<HR>
994
995<pre>T const* optional&lt;T&gt;::get_ptr() const ;
996T*       optional&lt;T&gt;::get_ptr() ;
997
998inline T const* get_pointer ( optional&lt;T&gt; const&amp; ) ;
999inline T*       get_pointer ( optional&lt;T&gt; &amp;) ;
1000</pre>
1001<blockquote>
1002<p><b>Returns:</b> If <b>*this</b> is initialized, a pointer to the contained
1003value; else 0 (<i>null</i>).
1004</p>
1005<p><b>Throws:</b> Nothing.</p>
1006<p><b>Notes:</b> If T is a reference type, the pointer is to the referenced object</p>
1007<p><b>Notes:</b> The contained value is permanently stored within *this, so
1008you should not hold nor delete this pointer.
1009</p>
1010<p><b>Example:</b></p>
1011<blockquote>
1012    <pre>int v=123;
1013optional&lt;int&gt; opt(v);
1014optional&lt;int&gt; const copt(v);
1015int* p = opt.get_ptr() ;
1016int const* cp = copt.get_ptr();
1017assert ( p == get_pointer(opt) );
1018assert ( cp == get_pointer(copt) ) ;
1019
1020int& rv = v ;
1021optional&lt;int&amp;&gt; optr(rv);
1022
1023*(optr.get_ptr()) = 456 ;
1024
1025assert ( v == 456 );
1026
1027
1028</pre>
1029</blockquote>
1030</blockquote>
1031
1032
1033<HR>
1034
1035
1036<pre>T const* optional&lt;T&gt;::operator -&gt;() const ;
1037T*       optional&lt;T&gt;::operator -&gt;()       ;
1038</pre>
1039<blockquote>
1040<p><b>Requirements: *this</b> is initialized.</p>
1041<p><b>Returns:</b> A pointer to the contained value.</p>
1042<p><b>Throws:</b> Nothing.</p>
1043<p><b>Notes:</b> If T is a reference type, the pointer is to the referenced object</p>
1044<p><b>Notes:</b> The requirement is asserted via BOOST_ASSERT().</p>
1045<p><b>Example:</b></p>
1046<blockquote>
1047<pre>struct X { int mdata ; } ;
1048X x ;
1049optional&lt;X&gt; opt (x);
1050opt-&gt;mdata = 2 ;
1051
1052X& rx = x ;
1053
1054optional&lt;X&amp;&gt; optr (rx);
1055optr-&gt;mdata = 4 ;
1056
1057assert ( x.mdata = 4 )
1058
1059</pre>
1060</blockquote>
1061</blockquote>
1062
1063
1064<HR>
1065
1066
1067<pre>optional&lt;T&gt;::operator <i>unspecified-bool-type</i>() const ;</pre>
1068<blockquote>
1069<p><b>Returns:</b> An unspecified value which if used on a boolean context is equivalent to (get() != 0)</p>
1070<p><b>Throws:</b> Nothing.</p>
1071<blockquote>
1072    <pre>optional&lt;T&gt; def ;
1073assert ( def == 0 );
1074optional&lt;T&gt; opt ( v ) ;
1075assert ( opt );
1076assert ( opt != 0 );
1077</pre>
1078</blockquote>
1079</blockquote>
1080
1081<HR>
1082
1083
1084<pre> bool optional&lt;T&gt;::operator!() ;</pre>
1085<blockquote>
1086<p><b>Returns:</b> If <b>*this</b> is uninitialized, <code>true</code>; else <code>false.</code></p>
1087<p><b>Throws:</b> Nothing.</p>
1088<p><b>Notes:</b> This operator is provided for those compilers which can't use
1089the <i>unspecified-bool-type</i> operator in certain boolean contexts.
1090</p>
1091<p><b>Example:</b></p>
1092<blockquote>
1093    <pre>optional&lt;T&gt; opt ;
1094assert ( !opt );
1095*opt = some_T ;
1096
1097// Notice the &quot;double-bang&quot; idiom here.
1098assert ( !!opt ) ;
1099</pre>
1100</blockquote>
1101</blockquote>
1102
1103
1104<HR>
1105
1106
1107<pre>bool optional&lt;T&gt;::is_initialized() const ;</pre>
1108<blockquote>
1109<p><b>Returns:</b> <i>true</i> is the <b>optional</b> is initialized, <i>false</i>
1110otherwise.</p>
1111<p><b>Throws:</b> Nothing.</p>
1112<blockquote>
1113    <pre>optional&lt;T&gt; def ;
1114assert ( !def.is_initialized() );
1115optional&lt;T&gt; opt ( v ) ;
1116assert ( opt.is_initialized() );</pre>
1117</blockquote>
1118</blockquote>
1119
1120<HR>
1121
1122<pre>optional&lt;T <i>(not a ref)</i>&gt; make_optional( T const&amp; v )</pre>
1123<blockquote>
1124<p><b>Returns:</b> optional&lt;T&gt;(v) for the <i>deduced</i> type <code>T</code> of <code>v</code>.</p>
1125<p><b>Example:</b></p>
1126<blockquote>
1127<pre>template&lt;class T&gt; void foo ( optional&lt;T&gt; const& opt ) ;
1128
1129foo ( make_optional(1+1) ) ; // Creates an optional&lt;int&gt;
1130</blockquote>
1131</blockquote>
1132<HR>
1133
1134<pre>optional&lt;T <i>(not a ref)</i>&gt; make_optional( bool condition, T const&amp; v )</pre>
1135<blockquote>
1136<p><b>Returns:</b> optional&lt;T&gt;(condition,v) for the <i>deduced</i> type <code>T</code> of <code>v</code>.</p>
1137<p><b>Example:</b></p>
1138<blockquote>
1139<pre>optional&lt;double&gt; calculate_foo()
1140{
1141  double val = compute_foo();
1142  return make_optional(is_not_nan_and_finite(val),val);
1143}
1144
1145optional&lt;double&gt; v = calculate_foo();
1146if ( !v )
1147  error("foo wasn't computed");
1148</blockquote>
1149</blockquote>
1150
1151<HR>
1152
1153
1154<pre>bool operator == ( optional&lt;T&gt; const&amp x, optional&lt;T&gt const&amp y );</pre>
1155<blockquote>
1156<p><b>Returns:</b> If both <b>x</b> and <b>y</b> are initialied, <code>(*x == *y)</code>.
1157If only x or y is initialized, <code>false</code>. If both are uninitialized, <code>true</code>. </p>
1158<p><b>Throws:</b> Nothing.</p>
1159<p><b>Notes:</b> Pointers have shallow relational operators while <b>optional</b> has
1160deep relational operators. Do not use operator == directly in generic code
1161which expect to be given either an optional&lt;T&gt; or a pointer;
1162use <a href="../../utility/OptionalPointee.html#equal">equal_pointees()</a> instead </p>
1163<p><b>Example:</b></p>
1164<blockquote>
1165    <pre>T x(12);
1166T y(12);
1167T z(21);
1168optional&lt;T&gt; def0 ;
1169optional&lt;T&gt; def1 ;
1170optional&lt;T&gt; optX(x);
1171optional&lt;T&gt; optY(y);
1172optional&lt;T&gt; optZ(z);
1173
1174// Identity always hold
1175assert ( def0 == def0 );
1176assert ( optX == optX );
1177
1178// Both uninitialized compare equal
1179assert ( def0 == def1 );
1180
1181// Only one initialized compare unequal.
1182assert ( def0 != optX );
1183
1184// Both initialized compare as (*lhs == *rhs)
1185assert ( optX == optY ) ;
1186assert ( optX != optZ ) ;
1187</pre>
1188</blockquote>
1189</blockquote>
1190
1191<HR>
1192
1193
1194<pre>bool operator &lt; ( optional&lt;T&gt; const&amp x, optional&lt;T&gt const&amp y );</pre>
1195<blockquote>
1196<p><b>Returns:</b> If <b>y</b> is not initialized, <code>false</code>.
1197If <b>y</b> is initialized and <b>x</b> is not initialized, <code>true</code>.
1198If both <b>x</b> and <b>y</b> are initialized, <code>(*x &lt; *y)</code>. </p>
1199<p><b>Throws:</b> Nothing.</p>
1200<p><b>Notes:</b> Pointers have shallow relational operators while <b>optional</b> has
1201deep relational operators. Do not use operator &lt; directly in generic code
1202which expect to be given either an optional&lt;T&gt; or a pointer;
1203use <a href="../../utility/OptionalPointee.html#less">less_pointees()</a> instead </p>
1204<p><b>Example:</b></p>
1205<blockquote>
1206    <pre>T x(12);
1207T y(34);
1208optional&lt;T&gt; def ;
1209optional&lt;T&gt; optX(x);
1210optional&lt;T&gt; optY(y);
1211
1212// Identity always hold
1213assert ( !(def &lt; def) );
1214assert ( optX == optX );
1215
1216// Both uninitialized compare equal
1217assert ( def0 == def1 );
1218
1219// Only one initialized compare unequal.
1220assert ( def0 != optX );
1221
1222// Both initialized compare as (*lhs == *rhs)
1223assert ( optX == optY ) ;
1224assert ( optX != optZ ) ;
1225</pre>
1226</blockquote>
1227</blockquote>
1228
1229<HR>
1230<pre>bool operator != ( optional&lt;T&gt; const&amp x, optional&lt;T&gt const&amp y );
1231</pre>
1232<blockquote>
1233  <p><b>Returns:</b> !( x == y );</p>
1234  <p><b>Throws:</b> Nothing.</p>
1235</blockquote>
1236
1237<HR>
1238<pre>bool operator &gt; ( optional&lt;T&gt; const&amp x, optional&lt;T&gt const&amp y );
1239</pre>
1240<blockquote>
1241  <p><b>Returns:</b> ( y &lt; x );</p>
1242  <p><b>Throws:</b> Nothing.</p>
1243</blockquote>
1244
1245<HR>
1246<pre>bool operator &lt;= ( optional&lt;T&gt; const&amp x, optional&lt;T&gt const&amp y );
1247</pre>
1248<blockquote>
1249  <p><b>Returns:</b> !( y&lt;x );</p>
1250  <p><b>Throws:</b> Nothing.</p>
1251</blockquote>
1252
1253<HR>
1254<pre>bool operator &gt;= ( optional&lt;T&gt; const&amp x, optional&lt;T&gt const&amp y );
1255</pre>
1256<blockquote>
1257  <p><b>Returns:</b> !( x&lt;y );</p>
1258  <p><b>Throws:</b> Nothing.</p>
1259</blockquote>
1260
1261<HR>
1262<pre>
1263bool operator == ( optional&lt;T&gt; const&amp; x, T const&amp; n );
1264bool operator != ( optional&lt;T&gt; const&amp; x, T const&amp; n );
1265bool operator &lt;  ( optional&lt;T&gt; const&amp; x, T const&amp; n );
1266bool operator &gt;  ( optional&lt;T&gt; const&amp; x, T const&amp; n );
1267bool operator &lt;= ( optional&lt;T&gt; const&amp; x, T const&amp; n );
1268bool operator &gt;= ( optional&lt;T&gt; const&amp; x, T const&amp; n );
1269bool operator == ( T const&amp; n, optional&lt;T&gt; const&amp; y );
1270bool operator != ( T const&amp; n, optional&lt;T&gt; const&amp; y );
1271bool operator &lt;  ( T const&amp; n, optional&lt;T&gt; const&amp; y );
1272bool operator &gt;  ( T const&amp; n, optional&lt;T&gt; const&amp; y );
1273bool operator &lt;= ( T const&amp; n, optional&lt;T&gt; const&amp; y );
1274bool operator &gt;= ( T const&amp; n, optional&lt;T&gt; const&amp; y );
1275</pre>
1276<blockquote>
1277  <p><b>Returns:</b> The result obtained by replacing the argument 'n' by optional&lt;T&gt;(n).</p>
1278</blockquote>
1279
1280<HR>
1281<pre>
1282bool operator == ( optional&lt;T&gt; const&amp; x, none_t n );
1283bool operator != ( optional&lt;T&gt; const&amp; x, none_t n );
1284bool operator &lt;  ( optional&lt;T&gt; const&amp; x, none_t n );
1285bool operator &gt;  ( optional&lt;T&gt; const&amp; x, none_t n );
1286bool operator &lt;= ( optional&lt;T&gt; const&amp; x, none_t n );
1287bool operator &gt;= ( optional&lt;T&gt; const&amp; x, none_t n );
1288bool operator == ( none_t n, optional&lt;T&gt; const&amp; y );
1289bool operator != ( none_t n, optional&lt;T&gt; const&amp; y );
1290bool operator &lt;  ( none_t n, optional&lt;T&gt; const&amp; y );
1291bool operator &gt;  ( none_t n, optional&lt;T&gt; const&amp; y );
1292bool operator &lt;= ( none_t n, optional&lt;T&gt; const&amp; y );
1293bool operator &gt;= ( none_t n, optional&lt;T&gt; const&amp; y );
1294</pre>
1295<blockquote>
1296  <p><b>Returns:</b> The result obtained by replacing the argument 'n' by optional&lt;T&gt;().</p>
1297</blockquote>
1298<HR>
1299
1300<pre>void swap ( optional&lt;T&gt;&amp x, optional&lt;T&gt&amp y );</pre>
1301
1302<blockquote>
1303<p><b>Effect:</b> If both <b>x</b> and <b>y</b> are initialized, calls <code>swap(*x,*y)</code> using std::swap.<br>
1304If only one is initialized, say x, calls: <code>y = *x; x = boost:none;</code><br>
1305If none is initialized, does nothing. </p>
1306<p><b>Postconditions:</b> The states of x and y interchanged.</p>
1307<p><b>Throws:</b> If both are initialized, whatever swap(T&amp;,T&amp;) throws.
1308If only one is initialized, whatever T::T ( T const&amp; ) throws. </p>
1309<p><b>Notes:</b> If both are initialized, swap(T&amp;,T&amp;) is used <i>unqualified</i> but with std::swap introduced in scope.<br>
1310If only one is initialized, T::~T() and T::T( T const& ) is called. </p>
1311<p><b>Exception Safety:</b> If both are initialized, this operation has the exception
1312safety guarantees of swap(T&,T&).<br>
1313If only one is initialized, it has the same <b>basic</b> guarantee as optional&lt;T&gt;::operator=( T const& ). </p>
1314<p><b>Example:</b></p>
1315<blockquote>
1316      <pre>T x(12);
1317T y(21);
1318optional&lt;T&gt; def0 ;
1319optional&lt;T&gt; def1 ;
1320optional&lt;T&gt; optX(x);
1321optional&lt;T&gt; optY(y);
1322
1323boost::swap(def0,def1); // no-op
1324
1325boost::swap(def0,optX);
1326assert ( *def0 == x );
1327assert ( !optX );
1328
1329boost::swap(def0,optX); // Get back to original values
1330
1331boost::swap(optX,optY);
1332assert ( *optX == y );
1333assert ( *optY == x );
1334
1335</pre>
1336</blockquote>
1337</blockquote>
1338<HR>
1339
1340<H2><A NAME="examples">Examples</A></H2>
1341
1342<h3>Optional return values</h3>
1343<PRE>optional&lt;char&gt; get_async_input()
1344{
1345&nbsp; if ( !queue.empty() )
1346&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return optional&lt;char&gt;(queue.top());
1347&nbsp; else return optional&lt;char&gt;(); // uninitialized
1348}
1349
1350void receive_async_message()
1351{
1352&nbsp; optional&lt;char&gt; rcv ;
1353&nbsp; // The safe boolean conversion from 'rcv' is used here.
1354&nbsp; while ( (rcv = get_async_input()) &amp;&amp; !timeout() )
1355&nbsp;&nbsp;&nbsp; output(*rcv);
1356}
1357</pre>
1358
1359<h3>Optional local variables</h3>
1360<pre>optional&lt;string&gt; name ;
1361if ( database.open() )
1362{
1363&nbsp; name = database.lookup(employer_name) ;
1364}
1365else
1366{
1367&nbsp; if ( can_ask_user )
1368&nbsp;&nbsp;&nbsp; name = user.ask(employer_name) ;
1369}
1370
1371if ( name )
1372&nbsp;&nbsp;&nbsp;&nbsp; print(*name);
1373else print(&quot;employer's name not found!&quot;);
1374</pre>
1375
1376<h3>Optional data members</h3>
1377<pre>class figure
1378{
1379&nbsp; public:
1380
1381&nbsp;&nbsp;&nbsp; figure()
1382&nbsp;&nbsp;&nbsp; {
1383&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // data member 'm_clipping_rect' is uninitialized at this point.
1384&nbsp;&nbsp;&nbsp; }
1385
1386&nbsp;&nbsp;&nbsp; void clip_in_rect ( rect const&amp; rect )
1387&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
1388&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ....
1389&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_clipping_rect = rect ; // initialized here.
1390&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
1391
1392&nbsp;&nbsp;&nbsp; void draw ( canvas& cvs )
1393&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
1394&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( m_clipping_rect )
1395&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do_clipping(*m_clipping_rect);
1396
1397&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cvs.drawXXX(..);
1398&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
1399
1400&nbsp;&nbsp;&nbsp; // this can return NULL.
1401&nbsp;&nbsp;&nbsp; rect const* get_clipping_rect() { return get_pointer(m_clipping_rect); }
1402
1403&nbsp; private :
1404
1405&nbsp;&nbsp;&nbsp; optional&lt;rect&gt; m_clipping_rect ;
1406
1407};
1408</pre>
1409<h3>Bypassing expensive unnecessary default construction</h3>
1410<pre>class ExpensiveCtor { ... } ;
1411class Fred
1412{
1413&nbsp; Fred() : mLargeVector(10000) {}
1414
1415&nbsp; std::vector< optional&lt;ExpensiveCtor&gt; > mLargeVector ;
1416} ;
1417</pre>
1418
1419<HR>
1420
1421<H2><A NAME="ref">Optional references</A></H2>
1422<p>This library allows the template parameter T to be of reference type: T&amp;, and
1423to some extent, T const&amp;.</p>
1424
1425<p>However, since references are not real objects some restrictions apply and
1426some operations are not available in this case:</p>
1427
1428<ul>
1429  <li>Converting constructors</li>
1430  <li>Converting assignment</li>
1431  <li>InPlace construction</li>
1432  <li>InPlace assignment</li>
1433</ul>
1434<p>Also, even though optional&lt;T&amp;&gt; treats it wrapped pseudo-object much as a real
1435value, a true real reference is stored, thus aliasing can ocurr: </p>
1436
1437<ul>
1438  <li>Copies of optional&lt;T&amp;&gt; copies the reference, but all copied references
1439  will nonetheless reefer to the same object.</li>
1440  <li>Value-access provides access to the referenced object rather
1441  than the reference itself.</li>
1442  <li>Pointer-access provides a pointer to the referenced object rather
1443  than a pointer to the reference itself.</li>
1444</ul>
1445
1446<HR>
1447<h2><A NAME="refassign">Rebinding semantics for assignment of optional
1448references</a></h2>
1449<p>If you assign to an <i>uninitialized</i> optional&lt;T&amp;&gt; the effect is to bind (for the first time) to the object.
1450Clearly, there is no other choice.</p>
1451<pre>int x = 1 ;
1452int&amp; rx = x ;
1453optional&lt;int&amp;&gt; ora ;
1454optional&lt;int&amp;&gt; orb(rx) ;
1455ora = orb ; // now 'ora'&nbsp;is bound to 'x' through 'rx'
1456*ora = 2 ; // Changes value of 'x' through 'ora'
1457assert(x==2);
1458</pre>
1459<p>If you assign to a bare C++ reference, the assignment is forwarded to the
1460referenced object; it's value changes but the reference is never rebound.</p>
1461<pre>int a = 1 ;
1462int&amp; ra = a ;
1463int b = 2 ;
1464int&amp; rb = b ;
1465ra = rb ; // Changes the VALUE of 'a' to that of 'b'
1466assert(a==b);
1467b = 3 ;
1468assert(ra!=b); // 'ra' is not rebound to 'b'
1469</pre>
1470<p>Now, if you assign to an <i>initialized</i> optional&lt;T&amp;&gt;, the effect is to <b>rebind</b> to the new object instead of assigning the referee. This is unlike
1471bare C++ references.</p>
1472<pre>int a = 1 ;
1473int b = 2 ;
1474int&amp; ra = a ;
1475int&amp; rb = b ;
1476optional&lt;int&amp;&gt; ora(ra) ;
1477optional&lt;int&amp;&gt; orb(rb) ;
1478ora = orb ; // 'ora'&nbsp;is <b>rebound</b> to 'b'
1479*ora = 3 ; // Changes value of 'b' (not 'a')
1480assert(a==1);
1481assert(b==3);
1482</pre>
1483<h3>Rationale:</h3>
1484<p>Rebinding semantics for the assignment of <i>initialized</i> optional
1485references has been chosen to provide<b><i> </i>consistency among initialization
1486states<i> </i></b>even at the expense of lack of consistency with the semantics of bare
1487C++ references.<br>
1488It is true that optional&lt;U&gt; strives to behave as much as possible as U does
1489whenever it is initialized; but in the case when U is T&amp;, doing so would result
1490in inconsistent behavior w.r.t to the lvalue initialization state.</p>
1491<p>Consider the following code :</p>
1492<pre>
1493int x = 1 ;
1494int& rx = x ;
1495void foo ( optional&lt;int&amp;&gt; & outer )
1496{
1497  optional&lt;int&amp;&gt; b(rx);
1498  outer = b ;
1499}
1500</pre>
1501<p>What should the assignment to 'outer' do?<br>
1502If 'outer' is <i>uninitialized</i>, the answer is clear: it should bind to 'x' (so we now have
1503a second reference to 'x').<br>
1504But what if 'outer' is already <i>initialized?</i><br>
1505The assignment could change the value of the
1506referenced object (whatever that is), but doing that would be inconsistent with the uninitialized case
1507and then you wouldn't be able to reason at compile time about all the references to x since
1508the appearance of a new reference to it would depend on wheter the lvalue ('outer')
1509is initialized or not.</p>
1510<p>Arguably, if rebinding the reference to another object is wrong for your code, then is
1511likely that binding it for the fist time via assignment instead of intialization is also wrong.
1512In that case, you can always just assign the value to the referenced object directly via
1513the access operator <code>*opt=value</code>.</p>
1514<p>If rebinding is wrong but first-time binding
1515isn't (via assignment), you can always work around the rebinding semantics using a discriminator:</p>
1516<pre>
1517if ( !opt )
1518      opt = value ; // first-time binding
1519else *opt = value ; // assign to referee without rebinding
1520</pre>
1521
1522<HR>
1523
1524<H2><A NAME="none">none_t and none</A></H2>
1525<p>optional&lt;T&gt; supports uninitialized states with a convenient syntax via a constant of
1526the <i>implementation-defined</i> type <code>boost::none_t</code>, identified as <code>boost::none</code>.</p>
1527<p>Starting with Boost version 1.34.0, both <code>boost::none_t</code> and <code>boost::none</code> are
1528included in <code>boost/none.hpp</code>, which is automatically included by <code>boost/optional/optional.hpp</code>
1529</p>
1530<p>This contant is similar in purpose to NULL, except that is not a <i>null pointer value</i>. You can use it to initialize 
1531an optional&lt;T&gt; instance, which has the same effect of a default constructor, and you can assign it which has the
1532effect of reseting the optional&lt;T&gt; instance. You can also use it in relational operators to make the predicate expression
1533more clear.</p>
1534<p>Here are some typical examples:</p>
1535<pre>
1536#include "boost/optional/optional.hpp" // boost/none.hpp is included automatically
1537
1538boost::optional&lt;int&gt; foo ( int a )
1539{
1540  return some_condition(a) ? boost::make_optional(a) : boost::none ; 
1541 
1542  // NOTE: in real code you can just use this: make_optional(some_condition(a), a )
1543}
1544
1545boost::optional&lt;int&gt; opt = boost::none ;
1546
1547if ( opt == boost::none )
1548  opt = foo(123);
1549
1550opt = boost::none ;
1551
1552</pre>
1553
1554<HR>
1555
1556<H2><A NAME="inplace">In-Place Factories</A></H2>
1557<p>
1558One of the typical problems with wrappers and containers is that their
1559interfaces usually provide an operation to initialize or assign the contained
1560object as a copy of some other object. This not only requires the underlying
1561type to be <a href="../../utility/CopyConstructible.html">Copy Constructible</a>, but also requires the existence of a fully
1562constructed object, often temporary, just to follow the copy from:</p>
1563<pre>struct X
1564{
1565  X ( int, std:::string ) ;
1566} ;</pre>
1567<pre>class W
1568{
1569  X wrapped_ ;
1570
1571public:
1572
1573  W ( X const& x ) : wrapped_(x) {}
1574} ;</pre>
1575<pre>void foo()
1576{
1577  // Temporary object created.
1578  W ( X(123,"hello") ) ;
1579}
1580</pre>
1581<p>A solution to this problem is to support direct construction of the contained
1582object right in the container's storage.<br>
1583In this scheme, the user only needs to supply the arguments to the constructor
1584to use in the wrapped object construction.</p>
1585<pre>class W
1586{
1587  X wrapped_ ;
1588
1589public:
1590
1591  W ( X const& x ) : wrapped_(x) {}
1592  W ( int a0, std::string a1) : wrapped_(a0,a1) {}
1593} ;</pre>
1594<pre>void foo()
1595{
1596  // Wrapped object constructed in-place
1597  // No temporary created.
1598  W (123,"hello") ;
1599}
1600</pre>
1601<p>A limitation of this method is that it doesn't scale well to wrapped objects with multiple
1602constructors nor to generic code were the constructor overloads are unknown.</p>
1603<p>The solution presented in this library is the family of <b>InPlaceFactories</b> and <b>TypedInPlaceFactories</b>.<br>
1604These factories are a family of classes which encapsulate an increasing number of arbitrary
1605constructor parameters and supply a method to construct an object of a given type using those
1606parameters at an address specified by the user via placement new.</p>
1607<p>&nbsp;For example, one member of this family looks like:</p>
1608<pre>template&lt;class T,class A0, class A1&gt;
1609class TypedInPlaceFactory2
1610{
1611  A0 m_a0 ; A1 m_a1 ;
1612
1613public:
1614
1615  TypedInPlaceFactory2( A0 const& a0, A1 const& a1 ) : m_a0(a0), m_a1(a1) {}
1616
1617  void construct ( void* p ) { new (p) T(m_a0,m_a1) ; }
1618} ;
1619</pre>
1620<p>A wrapper class aware of this can use it as:</p>
1621<pre>class W
1622{
1623  X wrapped_ ;
1624
1625public:
1626
1627  W ( X const& x ) : wrapped_(x) {}
1628  W ( TypedInPlaceFactory2 const& fac ) { fac.construct(&wrapped_) ; }
1629} ;</pre>
1630<pre>void foo()
1631{
1632  // Wrapped object constructed in-place via a TypedInPlaceFactory.
1633  // No temporary created.
1634  W ( TypedInPlaceFactory2&lt;X,int,std::string&rt;(123,"hello")) ;
1635}
1636</pre>
1637<p>The factories are divided in two groups:<ul>
1638  <li><u>TypedInPlaceFactories</u>: those which take the target type as a primary template parameter.</li>
1639  <li><u>InPlaceFactories</u>: those with a template <code>construct(void*)</code> member function taking the target type.</li>
1640  </ul>
1641<p>Within each group, all the family members differ only in the number of parameters allowed.</p>
1642<p></p>
1643<p>This library provides an overloaded set of helper template functions to construct these factories
1644without requiring unnecessary template parameters:</p>
1645<pre>template&lt;class A0,...,class AN&gt;
1646InPlaceFactory<i>N </i>&lt;A0,...,AN&gt; <b>in_place</b> ( A0 const& a0, ..., AN const& aN) ;
1647
1648template&lt;class T,class A0,...,class AN&gt;
1649TypedInPlaceFactory<i>N </i>&lt;T,A0,...,AN&gt; <b>in_place</b> ( T const& a0, A0 const& a0, ..., AN const& aN) ;</pre>
1650
1651<p>In-place factories can be used generically by the wrapper and user as follows:</p>
1652<pre>class W
1653{
1654  X wrapped_ ;
1655
1656public:
1657
1658  W ( X const& x ) : wrapped_(x) {}
1659
1660  template<class InPlaceFactory></class>
1661  W ( InPlaceFactory const& fac ) { fac.template &lt;X&gt;construct(&wrapped_) ; }
1662
1663} ;</pre>
1664<pre>void foo()
1665{
1666  // Wrapped object constructed in-place via a InPlaceFactory.
1667  // No temporary created.
1668  W ( in_place(123,"hello") ) ;
1669}
1670</pre>
1671<p>The factories are implemented in the headers: <a href="../../../boost/utility/in_place_factory.hpp">in_place_factory.hpp</a> and <a href="../../../boost/utility/typed_in_place_factory.hpp">typed_in_place_factory.hpp</a> </p>
1672
1673<HR>
1674
1675<H2><A NAME="bool">A note about optional&lt;bool&gt;</A></H2>
1676<p><code>optional&lt;bool&gt;</code> should be used with special caution and consideration.</p>
1677<p>First, it is functionally similar to a tristate boolean (false,maybe,true) &mdash;such as <a href="http://www.boost.org/doc/html/tribool.html">boost::tribool</a>&mdash;except that in a tristate boolean,
1678the <i>maybe</i> state <u>represents a valid value</u>, unlike the corresponding state
1679of an uninitialized optional&lt;bool&gt;.<br>
1680It should be carefully considered if an optional&lt;bool&gt; instead of a tribool is really needed</p>
1681<p>Second, optional&lt;&gt; provides a simple way to test initialization state: an implicit conversion to a type that evaluates as a 'bool' in a boolean context.<br>
1682Using optional&lt;bool&gt; can lead to subtle errors due to this implicit conversion:</p>
1683<pre>void foo ( bool v ) ;
1684void bar()
1685{
1686&nbsp; optional&lt;bool&gt; v = try();
1687
1688&nbsp; // The following intended to pass the <b>value</b> of 'v' to foo():
1689&nbsp; foo(v);
1690&nbsp; // But instead, the <i>initialization state</i> is passed
1691&nbsp; // due to a typo: it should have been foo(<b>*</b>v).
1692}
1693</pre>
1694<p>The only implicit conversion is to bool, and it is <i>safe</i> in the sense that typical
1695integral promotions don't apply (i.e. if foo() takes an 'int' instead, it won't compile). <HR>
1696
1697<H2><A NAME="exsafety">Exception Safety Guarantees</A></H2>
1698
1699<H3><u>Assignment:</u></H3>
1700<p><i>IMPORTANT NOTE: This changed in 1.33.1 with respect to previous versions</i></p>
1701<p>Because of the current implementation (see <A HREF="#impl">Implementation Notes</A>), all
1702of the assignment methods:</p>
1703<ul>
1704  <li> <code>optional&lt;T&gt;::operator= ( optional&lt;T&gt; const&amp; ) </code>
1705  </li>
1706  <li> <code>optional&lt;T&gt;::operator= ( T const&amp; ) </code></li>
1707  <li> <code>template&lt;class U&gt; optional&lt;T&gt;::operator= ( optional&lt;U&gt; const&amp; ) </code>
1708  </li>
1709  <li> <code>template&lt;class InPlaceFactory&gt; optional&lt;T&gt;::operator= (
1710  InPlaceFactory const&amp; ) </code></li>
1711  <li> <code>template&lt;class TypedInPlaceFactory&gt; optional&lt;T&gt;::operator= (
1712  TypedInPlaceFactory const&amp; ) </code></li>
1713</ul>
1714<p>cannot offer any <i>exception safety guarantee</i> beyond that provided by <code>T::operator=( T const&amp; )</code></p>
1715<p>On the other hand, the <i>uninitializing</i> methods:</p>
1716<ul>
1717  <li><code>optional&lt;T&gt;::operator= ( detail::none_t ) </code></li>
1718</ul>
1719<p>Provides the no-throw guarantee (assuming a no-throw T::~T()) becuse it only destroys the stored object.</p>
1720
1721<H3><u>Swap:</u></H3>
1722<p><code>void swap( optional&lt;T&gt;&amp;, optional&lt;T&gt;&amp; )</code> has the same exception guarantee as <code>swap(T&amp;,T&amp;)</code> when both optionals are initialized.<br>
1723If only one of the optionals is initialized, it gives the same exception guarantee as <code>T::operator=( T const&amp; )</code> (since <code>optional&lt;T&gt;::operator=( none_t )</code> doesn't throw).<br>
1724If none of the optionals is initialized, it has no-throw guarantee since it is a no-op. </p>
1725
1726<HR>
1727
1728<H2><A NAME="requirements">Type requirements</A></H2>
1729<p>In general, T must be <a href="../../utility/CopyConstructible.html">Copy Constructible</a> and have a no-throw destructor. The copy-constructible requirement is not needed
1730if InPlaceFactories are used.<br>
1731T <u>is not</u> required to be <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default Constructible</a> </p>
1732
1733<HR>
1734
1735<H2><A NAME="impl">Implementation Notes</A></H2>
1736<p>optional&lt;T&gt; is currently implemented
1737  using a custom aligned storage facility built from <code>alignment_of</code> and <code>type_with_alignment</code> (both from Type Traits).
1738  It uses a separate boolean flag to indicate the initialization state.</p>
1739<p>Placement new with T's copy constructor and T's destructor
1740  is explicitly used to initialize and destroy optional values. This allows T's default constructor to be effectively by-passed.</p>
1741<p>If assignment is used and the lvalue optional is uninitialized, T's copy constructor is used. However, if it is already initialized, T's assignment operator is used. This prevents optional from offering any exception guarantee stronger than the one offered by the type T itself</p>
1742
1743<HR>
1744
1745<H2><A NAME="porta">Dependencies and Portability</A></H2>
1746
1747<p>The implementation uses <code>type_traits/alignment_of.hpp</code> and <code>type_traits/type_with_alignment.hpp</code></p>
1748
1749<HR>
1750
1751<H2><A NAME="credits">Acknowledgments</A></H2>
1752<p>Pre-formal review:</p>
1753<blockquote>
1754<p>Peter Dimov suggested the name 'optional', and was the first to point out the
1755  need for aligned storage<br>
1756  Douglas Gregor developed 'type_with_alignment', and later Eric Friedman coded
1757  'aligned_storage', which are the core of the optional class implementation.<br>
1758  Andrei Alexandrescu and Brian Parker also worked with aligned storage techniques
1759  and their work influenced the current implementation.<br>
1760  Gennadiy Rozental made extensive and important comments which shaped the design.<br>
1761  Vesa Karvonen and Douglas Gregor made quite useful comparisons between optional,
1762  variant and any; and made other relevant comments. Douglas Gregor and Peter
1763  Dimov commented on comparisons and evaluation in boolean contexts.<br>
1764  Eric Friedman helped understand the issues involved with aligned storage, move/copy
1765  operations and exception safety.<br>
1766  Many others have participated with useful comments: Aleksey Gurotov, Kevlin
1767  Henney, David Abrahams, and others I can't recall. </p>
1768</blockquote>
1769<p>Post-formal review:</p>
1770<blockquote>
1771  <p>William Kempf carefully considered the originally proposed interface and
1772    suggested the new interface which is currently used. He also started and fueled
1773    the discussion about the analogy optional&lt;&gt;/smart pointer and about
1774    relational operators.<br>
1775    Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson focused
1776    on the relational semantics of optional (originally undefined); concluding
1777    with the fact that the pointer-like interface doesn't make it a pointer so
1778    it shall have deep relational operators.<br>
1779    Augustus Saunders also explored the different relational semantics between
1780    optional&lt;&gt; and a pointer and developed the OptionalPointee concept as
1781    an aid against potential conflicts on generic code.<br>
1782    Joel de Guzman noticed that optional&lt;&gt; can be seen as an API on top
1783    of variant&lt;T,nil_t&gt;.<br>
1784    Dave Gomboc explained the meaning and usage of the Haskell analog to optional&lt;&gt;:
1785    the Maybe type constructor (analogy originally pointed out by David Sankel).<br>
1786    Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, Rob
1787    Stewart, and others.<br>
1788    Joel de Guzman made the case for the support of references and helped with
1789    the proper semantics.<br>
1790    Mat Marcus shown the virtues of a value-oriented interface, influencing the
1791    current design, and contributed the idea of &quot;none&quot;.</p>
1792</blockquote>
1793<HR>
1794
1795<P>Revised March 27, 2007</P>
1796<p>© Copyright Fernando Luis Cacciola Carballal, 2003-2007</p>
1797<p> Use, modification, and distribution are subject to the Boost Software
1798License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
1799<P>Developed by <A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A>,
1800the latest version of this file can be found at <A
1801HREF="http://www.boost.org">www.boost.org</A>, and the boost <A HREF="http://www.boost.org/more/mailing_lists.htm#main">discussion lists</A></P>
1802</pre></BODY>
1803</HTML>
Note: See TracBrowser for help on using the repository browser.