From 0fd45d73b100ccd6406edf4c98860084fc24cf1d Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Thu, 5 Apr 2007 18:55:22 +0000 Subject: [PATCH] Doc update to reflect latest additions [SVN r37368] --- doc/optional.html | 221 ++++++++++++++++++++++++++++++---------------- 1 file changed, 144 insertions(+), 77 deletions(-) diff --git a/doc/optional.html b/doc/optional.html index c0f62cc..e216db5 100644 --- a/doc/optional.html +++ b/doc/optional.html @@ -24,7 +24,7 @@ HREF="../../../boost/optional/optional.hpp">boost/optional/optional.hpp>
Examples
Optional references
Rebinding semantics for assignment of optional references
-
none_t
+
none_t and none
In-Place Factories
A note about optional<bool>
Exception Safety Guarantees
@@ -385,6 +385,30 @@ template<class T> inline bool operator <= ( optional<T> const& x, op template<class T> inline bool operator >= ( optional<T> const& x, optional<T> const& y ) ; +template<class T> inline bool operator == ( optional<T> const& x, T const& n ) ; [new in 1.34] + +template<class T> inline bool operator != ( optional<T> const& x, T const& n ) ; [new in 1.34] + +template<class T> inline bool operator < ( optional<T> const& x, T const& n ) ; [new in 1.34] + +template<class T> inline bool operator > ( optional<T> const& x, T const& n ) ; [new in 1.34] + +template<class T> inline bool operator <= ( optional<T> const& x, T const& n ) ; [new in 1.34] + +template<class T> inline bool operator >= ( optional<T> const& x, T const& n ) ; [new in 1.34] + +template<class T> inline bool operator == ( T const& n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator != ( T const& n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator < ( T const& n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator > ( T const& n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator <= ( T const& n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator >= ( T const& n, optional<T> const& y ) ; [new in 1.34] + template<class T> inline bool operator == ( optional<T> const& x, none_t n ) ; [new in 1.34] template<class T> inline bool operator != ( optional<T> const& x, none_t n ) ; [new in 1.34] @@ -912,32 +936,6 @@ assert ( *opt == w ) ;
-
T const& optional<T (not a ref)>::get_value_or( T const& default) const ;
-T&       optional<T (not a ref)>::get_value_or( T&       default ) ;
-
-inline T const& get_optional_value_or ( optional<T (not a ref)> const& o, T const& default ) ;
-inline T&       get_optional_value_or ( optional<T (not a ref)>&       o, T&       default ) ;
-
-
-

Returns: A reference to the contained value, if any, or default

-

Throws: Nothing.

-

Example:

-
-
T v, z ;
-optional<T> def;
-T const& y = def.get_value_or(z);
-assert ( y == z ) ;
-
-optional<T> opt ( v );
-T const& u = get_optional_value_or(opt,z);
-assert ( u == v ) ;
-assert ( u != z ) ;
-
-
-

-
-
-
T const& optional<T&>::operator*() const ;
 T      & optional<T&>::operator*();
@@ -967,6 +965,33 @@ assert ( *opt == v ) ;
+
T const& optional<T>::get_value_or( T const& default) const ;
+T&       optional<T>::get_value_or( T&       default ) ;
+
+inline T const& get_optional_value_or ( optional<T> const& o, T const& default ) ;
+inline T&       get_optional_value_or ( optional<T>&       o, T&       default ) ;
+
+
+

Returns: A reference to the contained value (which can be itself a reference), if any, or default

+

Throws: Nothing.

+

Example:

+
+
T v, z ;
+optional<T> def;
+T const& y = def.get_value_or(z);
+assert ( y == z ) ;
+
+optional<T> opt ( v );
+T const& u = get_optional_value_or(opt,z);
+assert ( u == v ) ;
+assert ( u != z ) ;
+
+
+

+
+ +
+
T const* optional<T>::get_ptr() const ;
 T*       optional<T>::get_ptr() ;
 
@@ -1235,18 +1260,37 @@ assert ( optX != optZ ) ;
 
 
-bool operator == ( optional<T> const& x, none_t n );
-bool operator != ( optional<T> const& x, none_t n );
-bool operator <  ( optional<T> const& x, none_t n );
-bool operator >  ( optional<T> const& x, none_t n );
-bool operator <= ( optional<T> const& x, none_t n );
-bool operator >= ( optional<T> const& x, none_t n );
-bool operator == ( none_t n, optional<T> const& y );
-bool operator != ( none_t n, optional<T> const& y );
-bool operator <  ( none_t n, optional<T> const& y );
-bool operator >  ( none_t n, optional<T> const& y );
-bool operator <= ( none_t n, optional<T> const& y );
-bool operator >= ( none_t n, optional<T> const& y );
+bool operator == ( optional<T> const& x, T const& n );
+bool operator != ( optional<T> const& x, T const& n );
+bool operator <  ( optional<T> const& x, T const& n );
+bool operator >  ( optional<T> const& x, T const& n );
+bool operator <= ( optional<T> const& x, T const& n );
+bool operator >= ( optional<T> const& x, T const& n );
+bool operator == ( T const& n, optional<T> const& y );
+bool operator != ( T const& n, optional<T> const& y );
+bool operator <  ( T const& n, optional<T> const& y );
+bool operator >  ( T const& n, optional<T> const& y );
+bool operator <= ( T const& n, optional<T> const& y );
+bool operator >= ( T const& n, optional<T> const& y );
+
+
+

Returns: The result obtained by replacing the argument 'n' by optional<T>(n).

+
+ +
+
+bool operator == ( optional<T> const& x, none_t n );
+bool operator != ( optional<T> const& x, none_t n );
+bool operator <  ( optional<T> const& x, none_t n );
+bool operator >  ( optional<T> const& x, none_t n );
+bool operator <= ( optional<T> const& x, none_t n );
+bool operator >= ( optional<T> const& x, none_t n );
+bool operator == ( none_t n, optional<T> const& y );
+bool operator != ( none_t n, optional<T> const& y );
+bool operator <  ( none_t n, optional<T> const& y );
+bool operator >  ( none_t n, optional<T> const& y );
+bool operator <= ( none_t n, optional<T> const& y );
+bool operator >= ( none_t n, optional<T> const& y );
 

Returns: The result obtained by replacing the argument 'n' by optional<T>().

@@ -1388,7 +1432,7 @@ some operations are not available in this case:

  • InPlace assignment
  • Also, even though optional<T&> treats it wrapped pseudo-object much as a real -value, a true real reference is stored so aliasing will ocurr:

    +value, a true real reference is stored, thus aliasing can ocurr:

    • Copies of optional<T&> copies the reference, but all copied references @@ -1396,7 +1440,7 @@ value, a true real reference is stored so aliasing will ocurr:

    • Value-access provides access to the referenced object rather than the reference itself.
    • Pointer-access provides a pointer to the referenced object rather - than the reference itself.
    • + than a pointer to the reference itself.

    @@ -1407,7 +1451,7 @@ Clearly, there is no other choice.

    int x = 1 ;
     int& rx = x ;
     optional<int&> ora ;
    -optional<int&> orb(x) ;
    +optional<int&> orb(rx) ;
     ora = orb ; // now 'ora' is bound to 'x' through 'rx'
     *ora = 2 ; // Changes value of 'x' through 'ora'
     assert(x==2); 
    @@ -1418,7 +1462,7 @@ referenced object; it's value changes but the reference is never rebound.

    int& ra = a ; int b = 2 ; int& rb = b ; -ra = rb ; // Changes the value of 'a' to 'b' +ra = rb ; // Changes the VALUE of 'a' to that of 'b' assert(a==b); b = 3 ; assert(ra!=b); // 'ra' is not rebound to 'b' @@ -1444,45 +1488,68 @@ C++ references.
    It is true that optional<U> strives to behave as much as possible as U does whenever it is initialized; but in the case when U is T&, doing so would result in inconsistent behavior w.r.t to the lvalue initialization state.

    -

    Imagine optional<T&> forwarding assignment to the referenced object (thus -changing the referenced object value but not rebinding), and consider the -following code :

    -
      optional<int&> a = get();
    -  int x = 1 ;
    -  int& rx = x ;
    -  optional<int&> b(rx);
    -  a = b ;
    +

    Consider the following code :

    +
    +int x = 1 ;
    +int& rx = x ;
    +void foo ( optional<int&> & outer )
    +{
    +  optional<int&> b(rx);
    +  outer = b ;
    +}
    +
    +

    What should the assignment to 'outer' do?
    +If 'outer' is uninitialized, the answer is clear: it should bind to 'x' (so we now have +a second reference to 'x').
    +But what if 'outer' is already initialized?
    +The assignment could change the value of the +referenced object (whatever that is), but doing that would be inconsistent with the uninitialized case +and then you wouldn't be able to reason at compile time about all the references to x since +the appearance of a new reference to it would depend on wheter the lvalue ('outer') +is initialized or not.

    +

    Arguably, if rebinding the reference to another object is wrong for your code, then is +likely that binding it for the fist time via assignment instead of intialization is also wrong. +In that case, you can always just assign the value to the referenced object directly via +the access operator *opt=value.

    +

    If rebinding is wrong but first-time binding +isn't (via assignment), you can always work around the rebinding semantics using a discriminator:

    +
    +if ( !opt )
    +      opt = value ; // first-time binding
    +else *opt = value ; // assign to referee without rebinding 
     
    -

    What does the assignment do?
    -If 'a' is uninitialized, the answer is clear: it binds to 'x' (we now have -another reference to 'x').
    -But what if 'a' is already initialized? it would change the value of the -referenced object (whatever that is); which is inconsistent with the other -possible case.

    -

    If optional<T&> would assign just like T& does, you would never be able to -use Optional's assignment without explicitly handling the previous -initialization state unless your code is capable of functioning whether after -the assignment, 'a' -aliases the same object as 'b' or not.

    -

    That is, you would have to discriminate in order to be consistency.
    -
    -If in your code rebinding to another object is not an option, then is very -likely that binding for the fist time isn't either. In such case, assignment to -an uninitialized optional<T&> shall be prohibited. It is quite -possible that in such scenario the precondition that the lvalue must be already -initialized exist. If it doesn't, then binding for the first time is OK while -rebinding is not which is IMO -very unlikely.
    -In such scenario, you can assign the value itself directly, as in:

    -
    assert(!!opt);
    -*opt=value;  

    -

    none_t

    -

    +

    none_t and none

    +

    optional<T> supports uninitialized states with a convenient syntax via a constant of +the implementation-defined type boost::none_t, identified as boost::none.

    +

    Starting with Boost version 1.34.0, both boost::none_t and boost::none are +included in boost/none.hpp, which is automatically included by boost/optional/optional.hpp

    +

    This contant is similar in purpose to NULL, except that is not a null pointer value. You can use it to initialize +an optional<T> instance, which has the same effect of a default constructor, and you can assign it which has the +effect of reseting the optional<T> instance. You can also use it in relational operators to make the predicate expression +more clear.

    +

    Here are some typical examples:

    +
    +#include "boost/optional/optional.hpp" // boost/none.hpp is included automatically
     
    +boost::optional<int> foo ( int a )
    +{
    +  return some_condition(a) ? boost::make_optional(a) : boost::none ;  
    +  
    +  // NOTE: in real code you can just use this: make_optional(some_condition(a), a ) 
    +}
    +
    +boost::optional<int> opt = boost::none ;
    +
    +if ( opt == boost::none )
    +  opt = foo(123);
    +
    +opt = boost::none ;
    +
    +

    @@ -1725,7 +1792,7 @@ T is not required to be LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt)