From 9516a779fe1fc8157c75102731752484e3ef2dd0 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Thu, 8 Jun 2006 01:47:33 +0000 Subject: [PATCH 01/15] Disambiguated certain constructs. [SVN r34227] --- include/boost/optional/optional.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 47340b5..7219be0 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -133,7 +133,7 @@ class optional_base : public optional_tag { private : - typedef BOOST_DEDUCED_TYPENAME detail::make_reference_content::type internal_type ; + typedef BOOST_DEDUCED_TYPENAME ::boost::detail::make_reference_content::type internal_type ; typedef aligned_storage storage_type ; From a77dff3e112471bdbd50181f39e012242741fc61 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 12 Jun 2006 19:02:41 +0000 Subject: [PATCH 02/15] workaround for Borland [SVN r34288] --- include/boost/optional/optional.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 7219be0..4421f4a 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -133,7 +133,11 @@ class optional_base : public optional_tag { private : - typedef BOOST_DEDUCED_TYPENAME ::boost::detail::make_reference_content::type internal_type ; + typedef +#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + BOOST_DEDUCED_TYPENAME +#endif + ::boost::detail::make_reference_content::type internal_type ; typedef aligned_storage storage_type ; From 734e5b52835a79a820e88e96c69c4d9bcb1d5def Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Mon, 26 Jun 2006 18:01:38 +0000 Subject: [PATCH 03/15] Some additional functions added to optional (being new there won't be regressions) [SVN r34411] --- doc/optional.html | 142 ++++++++++++++++++++-------- include/boost/optional/optional.hpp | 55 ++++++++++- test/optional_test.cpp | 95 ++++++++++++++++++- 3 files changed, 247 insertions(+), 45 deletions(-) diff --git a/doc/optional.html b/doc/optional.html index 895312d..61a29c5 100644 --- a/doc/optional.html +++ b/doc/optional.html @@ -3,7 +3,6 @@ - @@ -324,6 +323,8 @@ class optional optional ( T const& v ) ; + optional ( bool condition, T const& v ) ; [new in 1.34] + optional ( optional const& rhs ) ; template<class U> explicit optional ( optional<U> const& rhs ) ; @@ -347,6 +348,8 @@ class optional T const& get() const ; T& get() ; + T const& get_value_or( T const& default ) const ; [new in 1.34] + T const* operator ->() const ; T* operator ->() ; @@ -380,6 +383,12 @@ 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 optional<T> make_optional ( T const& v ) ; [new in 1.34] + +template<class T> inline optional<T> make_optional ( bool condition, T const& v ) ; [new in 1.34] + +template<class T> inline T const& get_optional_value_or ( optional<T> const& opt, T const& default ) ; [new in 1.34] + template<class T> inline T const& get ( optional<T> const& opt ) ; template<class T> inline T& get ( optional<T> & opt ) ; @@ -436,7 +445,7 @@ assert ( !def ) ;
optional<T>::optional( none_t );
-

Effect: Constructs an optional uninitialized.

+

Effect: Constructs an optional uninitialized.

Postconditions: *this is uninitialized.

Throws: Nothing.

Notes:

@@ -459,7 +468,6 @@ assert ( !n ) ;
optional<T (not a ref)>::optional( T const& v )

Effect: Directly-Constructs an optional.

-

Postconditions: *this is initialized and its value is a copy of 'v'.

Throws: Whatever T::T( T const& ) throws.

Notes: T::T( T const& ) is called.

@@ -495,6 +503,23 @@ assert (*opt == v);
+
optional<T (not a ref)>::optional( bool condition, T const& v ) ;
+optional<T&>           ::optional( bool condition, T&       v ) ;
+
+ +
+

If condition is true, same as:

+
optional<T (not a ref)>::optional( T const& v )
+optional<T&>           ::optional( T&       v )
+
+

otherwise, same as:

+
optional<T (not a ref)>::optional()
+optional<T&>           ::optional()
+
+
+ +
+
optional<T (not a ref)>::optional( optional const& rhs );

Effect: Copy-Constructs an optional.

@@ -797,7 +822,6 @@ assert ( *opt1 == static_cast<U>(v) ) ;
-
T const& optional<T (not a ref)>::operator*() const ;
 T&       optional<T (not a ref)>::operator*();
@@ -828,6 +852,32 @@ 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*();
@@ -965,18 +1015,47 @@ assert ( opt.is_initialized() );
+
optional<T (not a ref)> make_optional( T const& v )
+
+

Returns: optional<T>(v) for the deduced type T of v.

+

Example:

+
+
template<class T> void foo ( optional<T> const& opt ) ;
+
+foo ( make_optional(1+1) ) ; // Creates an optional<int>
+
+
+
+ +
optional<T (not a ref)> make_optional( bool condition, T const& v )
+
+

Returns: optional<T>(condition,v) for the deduced type T of v.

+

Example:

+
+
optional<double> calculate_foo()
+{
+  double val = compute_foo();
+  return make_optional(is_not_nan_and_finite(val),val);
+}
+
+optional<double> v = calculate_foo();
+if ( !v )
+  error("foo wasn't computed");
+
+
+ +
+
bool operator == ( optional<T> const& x, optional<T> const& y );

Returns: If both x and y are initialied, (*x == *y). -If only x or y is initialized, false. If both are uninitialized, true. -

+If only x or y is initialized, false. If both are uninitialized, true.

Throws: Nothing.

Notes: Pointers have shallow relational operators while optional has deep relational operators. Do not use operator == directly in generic code which expect to be given either an optional<T> or a pointer; -use equal_pointees() instead -

+use equal_pointees() instead

Example:

T x(12);
@@ -1012,14 +1091,12 @@ assert ( optX != optZ ) ;
 

Returns: If y is not initialized, false. If y is initialized and x is not initialized, true. -If both x and y are initialized, (*x < *y). -

+If both x and y are initialized, (*x < *y).

Throws: Nothing.

Notes: Pointers have shallow relational operators while optional has deep relational operators. Do not use operator < directly in generic code which expect to be given either an optional<T> or a pointer; -use less_pointees() instead -

+use less_pointees() instead

Example:

T x(12);
@@ -1082,23 +1159,17 @@ assert ( optX != optZ ) ;
 
void swap ( optional<T>& x, optional<T>& y );
-

Effect: If both x and y are initialized, calls swap(*x,*y) -using std::swap.
+

Effect: If both x and y are initialized, calls swap(*x,*y) using std::swap.
If only one is initialized, say x, calls: y.reset(*x); x.reset();
-If none is initialized, does nothing. -

+If none is initialized, does nothing.

Postconditions: The states of x and y interchanged.

Throws: If both are initialized, whatever swap(T&,T&) throws. -If only one is initialized, whatever T::T ( T const& ) throws. -

-

Notes: If both are initialized, swap(T&,T&) is used unqualified -but with std::swap introduced in scope.
-If only one is initialized, T::~T() and T::T( T const& ) is called. -

+If only one is initialized, whatever T::T ( T const& ) throws.

+

Notes: If both are initialized, swap(T&,T&) is used unqualified but with std::swap introduced in scope.
+If only one is initialized, T::~T() and T::T( T const& ) is called.

Exception Safety: If both are initialized, this operation has the exception safety guarantees of swap(T&,T&).
-If only one is initialized, it has the same basic guarantee as optional<T>::reset( T const& ). -

+If only one is initialized, it has the same basic guarantee as optional<T>::reset( T const& ).

Example:

T x(12);
@@ -1254,8 +1325,7 @@ assert(a==b);
 b = 3 ;
 assert(ra!=b); // 'ra' is not rebound to 'b'
 
-

Now, if you assign to an initialized optional<T&>, the effect is to -rebind to the new object instead of assigning the referee. This is unlike +

Now, if you assign to an initialized optional<T&>, the effect is to rebind to the new object instead of assigning the referee. This is unlike bare C++ references.

int a = 1 ;
 int b = 2 ;
@@ -1358,8 +1428,7 @@ public:
 

A limitation of this method is that it doesn't scale well to wrapped objects with multiple constructors nor to generic code were the constructor overloads are unknown.

-

The solution presented in this library is the family of InPlaceFactories and -TypedInPlaceFactories.
+

The solution presented in this library is the family of InPlaceFactories and TypedInPlaceFactories.
These factories are a family of classes which encapsulate an increasing number of arbitrary constructor parameters and supply a method to construct an object of a given type using those parameters at an address specified by the user via placement new.

@@ -1427,10 +1496,7 @@ public: W ( in_place(123,"hello") ) ; }
-

The factories are implemented in the headers: -in_place_factory.hpp and -typed_in_place_factory.hpp -

+

The factories are implemented in the headers: in_place_factory.hpp and typed_in_place_factory.hpp


@@ -1473,8 +1539,7 @@ of the assignment methods:

TypedInPlaceFactory const& )
  • optional<T>:::reset ( T const&)
  • -

    Can only guarantee the basic exception safety: The lvalue optional is left uninitialized -if an exception is thrown (any previous value is first destroyed using T::~T())

    +

    Can only guarantee the basic exception safety: The lvalue optional is left uninitialized if an exception is thrown (any previous value is first destroyed using T::~T())

    On the other hand, the uninitializing methods:

    \ No newline at end of file diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 4421f4a..8a78a40 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -185,6 +185,16 @@ class optional_base : public optional_tag { construct(val); } + + // Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional. + // Can throw if T::T(T const&) does + optional_base ( bool cond, argument_type val ) + : + m_initialized(false) + { + if ( cond ) + construct(val); + } // Creates a deep copy of another optional // Can throw if T::T(T const&) does @@ -455,6 +465,9 @@ class optional : public optional_detail::optional_base // Can throw if T::T(T const&) does optional ( argument_type val ) : base(val) {} + // Creates an optional initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional. + // Can throw if T::T(T const&) does + optional ( bool cond, argument_type val ) : base(cond,val) {} #ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR // NOTE: MSVC needs templated versions first @@ -549,6 +562,10 @@ class optional : public optional_detail::optional_base reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); } reference_type get() { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); } + // Returns a copy of the value if this is initialized, 'v' otherwise + reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; } + reference_type get_value_or ( reference_type v ) { return this->is_initialized() ? get() : v ; } + // Returns a pointer to the value if this is initialized, otherwise, // the behaviour is UNDEFINED // No-throw @@ -570,6 +587,22 @@ class optional : public optional_detail::optional_base bool operator!() const { return !this->is_initialized() ; } } ; +// Returns optional(v) +template +inline +optional make_optional ( T const& v ) +{ + return optional(v); +} + +// Returns optional(cond,v) +template +inline +optional make_optional ( bool cond, T const& v ) +{ + return optional(cond,v); +} + // Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED. // No-throw template @@ -606,6 +639,24 @@ get ( optional* opt ) return opt->get_ptr() ; } +// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED. +// No-throw +template +inline +BOOST_DEDUCED_TYPENAME optional::reference_const_type +get_optional_value_or ( optional const& opt, BOOST_DEDUCED_TYPENAME optional::reference_const_type v ) +{ + return opt.get_value_or(v) ; +} + +template +inline +BOOST_DEDUCED_TYPENAME optional::reference_type +get_optional_value_or ( optional& opt, BOOST_DEDUCED_TYPENAME optional::reference_type v ) +{ + return opt.get_value_or(v) ; +} + // Returns a pointer to the value if this is initialized, otherwise, returns NULL. // No-throw template @@ -767,10 +818,6 @@ template inline void swap ( optional& x, optional& y ) optional_detail::optional_swap(x,y); } -template inline optional make_optional ( T const& v ) -{ - return optional(v); -} } // namespace boost diff --git a/test/optional_test.cpp b/test/optional_test.cpp index 12dda2a..5c10eed 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -15,7 +15,9 @@ #define BOOST_ENABLE_ASSERT_HANDLER -#include "boost/optional.hpp" +#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin + +#include "boost/optional/optional.hpp" #ifdef __BORLANDC__ #pragma hdrstop @@ -151,6 +153,95 @@ void test_basics( T const* ) ob.reset(); check_is_pending_dtor( ARG(T) ) ; check_uninitialized(ob); + +} + +template +void test_conditional_ctor_and_get_valur_or ( T const* ) +{ + TRACE( std::endl << BOOST_CURRENT_FUNCTION ); + + T a(321); + + T z(123); + + optional const cdef0(false,a); + + optional def0(false,a); + optional def1 = boost::make_optional(false,a); // T is not within boost so ADL won't find make_optional unqualified + check_uninitialized(def0); + check_uninitialized(def1); + + optional const co0(true,a); + + optional o0(true,a); + optional o1 = boost::make_optional(true,a); // T is not within boost so ADL won't find make_optional unqualified + + check_initialized(o0); + check_initialized(o1); + check_value(o0,a,z); + check_value(o1,a,z); + + T b = def0.get_value_or(z); + BOOST_CHECK( b == z ) ; + + b = get_optional_value_or(def0,z); + BOOST_CHECK( b == z ) ; + + b = o0.get_value_or(z); + BOOST_CHECK( b == a ) ; + + b = get_optional_value_or(o0,z); + BOOST_CHECK( b == a ) ; + + + T const& crz = z ; + T& rz = z ; + + T const& crzz = def0.get_value_or(crz); + BOOST_CHECK( crzz == crz ) ; + + T& rzz = def0.get_value_or(rz); + BOOST_CHECK( rzz == rz ) ; + + T const& crzzz = get_optional_value_or(cdef0,crz); + BOOST_CHECK( crzzz == crz ) ; + + T& rzzz = get_optional_value_or(def0,rz); + BOOST_CHECK( rzzz == rz ) ; + + T const& crb = o0.get_value_or(crz); + BOOST_CHECK( crb == a ) ; + + T& rb = o0.get_value_or(rz); + BOOST_CHECK( rb == b ) ; + + T const& crbb = get_optional_value_or(co0,crz); + BOOST_CHECK( crbb == b ) ; + + T const& crbbb = get_optional_value_or(o0,crz); + BOOST_CHECK( crbbb == b ) ; + + T& rbb = get_optional_value_or(o0,rz); + BOOST_CHECK( rbb == b ) ; + + T& ra = a ; + + optional defref(false,ra); + BOOST_CHECK(!defref); + + optional ref(true,ra); + BOOST_CHECK(!!ref); + + a = T(432); + + BOOST_CHECK( *ref == a ) ; + + T& r1 = defref.get_value_or(z); + BOOST_CHECK( r1 == z ) ; + + T& r2 = ref.get_value_or(z); + BOOST_CHECK( r2 == a ) ; } // @@ -688,6 +779,7 @@ void test_with_builtin_types() TRACE( std::endl << BOOST_CURRENT_FUNCTION ); test_basics( ARG(double) ); + test_conditional_ctor_and_get_valur_or( ARG(double) ); test_uninitialized_access( ARG(double) ); test_no_throwing_swap( ARG(double) ); test_relops( ARG(double) ) ; @@ -699,6 +791,7 @@ void test_with_class_type() TRACE( std::endl << BOOST_CURRENT_FUNCTION ); test_basics( ARG(X) ); + test_conditional_ctor_and_get_valur_or( ARG(X) ); test_direct_value_manip( ARG(X) ); test_uninitialized_access( ARG(X) ); test_throwing_direct_init( ARG(X) ); From 16a8ccbecc3ab40027551715a2d235b74d324ae0 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Thu, 20 Jul 2006 23:17:22 +0000 Subject: [PATCH 04/15] removed unnamed namespace (see http://lists.boost.org/Archives/boost/2006/07/107873.php); usual copyright/license/url fixes [SVN r34646] --- include/boost/none.hpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/include/boost/none.hpp b/include/boost/none.hpp index 693dbdf..b0e94a2 100644 --- a/include/boost/none.hpp +++ b/include/boost/none.hpp @@ -1,10 +1,10 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. // -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/lib/optional/ for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com @@ -16,15 +16,12 @@ // NOTE: Borland users have to include this header outside any precompiled headers // (bcc<=5.64 cannot include instance data in a precompiled header) +// -- * To be verified, now that there's no unnamed namespace namespace boost { -namespace { - none_t const none = ((none_t)0) ; -} - } // namespace boost #endif From 1b7002f663d1e22bf8da545e7859c5107706c840 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 4 Nov 2006 02:13:53 +0000 Subject: [PATCH 05/15] misused "precedence" changed to "precedent" [SVN r35831] --- doc/optional.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/optional.html b/doc/optional.html index 61a29c5..fedf8d9 100644 --- a/doc/optional.html +++ b/doc/optional.html @@ -126,7 +126,7 @@ undefined behavior which in our case is either T or nil_t.
    Using the Boost.Variant library, this model can be implemented in terms of boost::variant<T,nil_t>.
    - There is precedence for a discriminated union as a model for an optional value: the + There is precedent for a discriminated union as a model for an optional value: the Haskell Maybe built-in type constructor. Thus, a discriminated union T+nil_t serves as a conceptual foundation.

    A variant<T,nil_t> follows naturally from the traditional idiom of extending @@ -1673,4 +1673,4 @@ License, Version 1.0. (See accompanying file the latest version of this file can be found at www.boost.org, and the boost discussion lists

    - \ No newline at end of file + From be7249b537653ee5fede426d019538e1ed28fdb2 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Tue, 7 Nov 2006 19:11:57 +0000 Subject: [PATCH 06/15] Add copyright, license [SVN r35905] --- index.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index cac816c..ed59314 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,10 @@ Automatic redirection failed, please go to -doc/optional.html. +doc/optional.html
    +

    © Copyright Beman Dawes, 2001

    +

    Distributed under the Boost Software License, Version 1.0. (See accompanying +file LICENSE_1_0.txt or copy +at www.boost.org/LICENSE_1_0.txt)

    \ No newline at end of file From 07ce2fc860c7302f548a9186e9064b22f6e31cd0 Mon Sep 17 00:00:00 2001 From: Matias Capeletto Date: Tue, 29 May 2007 06:40:25 +0000 Subject: [PATCH 07/15] new quickbook docs for optional [SVN r37809] --- doc/Jamfile.v2 | 28 + doc/acknowledgments.qbk | 60 + doc/dependencies.qbk | 17 + doc/development.qbk | 251 +++ doc/examples.qbk | 102 + doc/html/HTML.manifest | 14 + .../a_note_about_optional_bool_.html | 84 + doc/html/boost_optional/acknowledgments.html | 122 ++ .../dependencies_and_portability.html | 46 + .../boost_optional/detailed_semantics.html | 1703 +++++++++++++++++ doc/html/boost_optional/development.html | 415 ++++ doc/html/boost_optional/examples.html | 151 ++ .../exception_safety_guarantees.html | 140 ++ .../boost_optional/implementation_notes.html | 52 + .../boost_optional/in_place_factories.html | 200 ++ .../boost_optional/optional_references.html | 82 + ...for_assignment_of_optional_references.html | 151 ++ doc/html/boost_optional/synopsis.html | 147 ++ .../boost_optional/type_requirements.html | 50 + doc/html/boostbook.css | 582 ++++++ doc/html/images/callouts/1.png | Bin 0 -> 391 bytes doc/html/images/callouts/10.png | Bin 0 -> 485 bytes doc/html/images/callouts/11.png | Bin 0 -> 410 bytes doc/html/images/callouts/12.png | Bin 0 -> 488 bytes doc/html/images/callouts/13.png | Bin 0 -> 509 bytes doc/html/images/callouts/14.png | Bin 0 -> 499 bytes doc/html/images/callouts/15.png | Bin 0 -> 507 bytes doc/html/images/callouts/2.png | Bin 0 -> 446 bytes doc/html/images/callouts/3.png | Bin 0 -> 431 bytes doc/html/images/callouts/4.png | Bin 0 -> 441 bytes doc/html/images/callouts/5.png | Bin 0 -> 423 bytes doc/html/images/callouts/6.png | Bin 0 -> 431 bytes doc/html/images/callouts/7.png | Bin 0 -> 397 bytes doc/html/images/callouts/8.png | Bin 0 -> 434 bytes doc/html/images/callouts/9.png | Bin 0 -> 420 bytes doc/html/images/callouts/R.png | Bin 0 -> 293 bytes doc/html/images/caution.png | Bin 0 -> 4286 bytes doc/html/images/home.png | Bin 0 -> 1105 bytes doc/html/images/important.png | Bin 0 -> 4666 bytes doc/html/images/next.png | Bin 0 -> 768 bytes doc/html/images/note.png | Bin 0 -> 4648 bytes doc/html/images/prev.png | Bin 0 -> 741 bytes doc/html/images/space.png | Bin 0 -> 81 bytes doc/html/images/tip.png | Bin 0 -> 3902 bytes doc/html/images/up.png | Bin 0 -> 766 bytes doc/html/images/warning.png | Bin 0 -> 3927 bytes doc/html/index.html | 168 ++ doc/implementation_notes.qbk | 28 + doc/optional.qbk | 131 ++ doc/reference.qbk | 880 +++++++++ doc/special_cases.qbk | 376 ++++ 51 files changed, 5980 insertions(+) create mode 100644 doc/Jamfile.v2 create mode 100644 doc/acknowledgments.qbk create mode 100644 doc/dependencies.qbk create mode 100644 doc/development.qbk create mode 100644 doc/examples.qbk create mode 100644 doc/html/HTML.manifest create mode 100644 doc/html/boost_optional/a_note_about_optional_bool_.html create mode 100644 doc/html/boost_optional/acknowledgments.html create mode 100644 doc/html/boost_optional/dependencies_and_portability.html create mode 100644 doc/html/boost_optional/detailed_semantics.html create mode 100644 doc/html/boost_optional/development.html create mode 100644 doc/html/boost_optional/examples.html create mode 100644 doc/html/boost_optional/exception_safety_guarantees.html create mode 100644 doc/html/boost_optional/implementation_notes.html create mode 100644 doc/html/boost_optional/in_place_factories.html create mode 100644 doc/html/boost_optional/optional_references.html create mode 100644 doc/html/boost_optional/rebinding_semantics_for_assignment_of_optional_references.html create mode 100644 doc/html/boost_optional/synopsis.html create mode 100644 doc/html/boost_optional/type_requirements.html create mode 100755 doc/html/boostbook.css create mode 100644 doc/html/images/callouts/1.png create mode 100644 doc/html/images/callouts/10.png create mode 100644 doc/html/images/callouts/11.png create mode 100644 doc/html/images/callouts/12.png create mode 100644 doc/html/images/callouts/13.png create mode 100644 doc/html/images/callouts/14.png create mode 100644 doc/html/images/callouts/15.png create mode 100644 doc/html/images/callouts/2.png create mode 100644 doc/html/images/callouts/3.png create mode 100644 doc/html/images/callouts/4.png create mode 100644 doc/html/images/callouts/5.png create mode 100644 doc/html/images/callouts/6.png create mode 100644 doc/html/images/callouts/7.png create mode 100644 doc/html/images/callouts/8.png create mode 100644 doc/html/images/callouts/9.png create mode 100644 doc/html/images/callouts/R.png create mode 100755 doc/html/images/caution.png create mode 100755 doc/html/images/home.png create mode 100755 doc/html/images/important.png create mode 100755 doc/html/images/next.png create mode 100755 doc/html/images/note.png create mode 100755 doc/html/images/prev.png create mode 100644 doc/html/images/space.png create mode 100755 doc/html/images/tip.png create mode 100755 doc/html/images/up.png create mode 100755 doc/html/images/warning.png create mode 100644 doc/html/index.html create mode 100644 doc/implementation_notes.qbk create mode 100644 doc/optional.qbk create mode 100644 doc/reference.qbk create mode 100644 doc/special_cases.qbk diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 new file mode 100644 index 0000000..95574ce --- /dev/null +++ b/doc/Jamfile.v2 @@ -0,0 +1,28 @@ +# Boost.Optional +# +# Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + + +# Quickbook +# ----------------------------------------------------------------------------- + +import quickbook ; + +xml optional + : + optional.qbk + ; + +boostbook standalone + : + optional + : + toc.max.depth=1 + toc.section.depth=1 + chunk.section.depth=1 + ; + diff --git a/doc/acknowledgments.qbk b/doc/acknowledgments.qbk new file mode 100644 index 0000000..117a468 --- /dev/null +++ b/doc/acknowledgments.qbk @@ -0,0 +1,60 @@ +[/ + Boost.Optional + + Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +] + + +[section Acknowledgments] + +[heading Pre-formal review] + +* Peter Dimov suggested the name 'optional', and was the first to point out +the need for aligned storage. +* Douglas Gregor developed 'type_with_alignment', and later Eric Friedman +coded 'aligned_storage', which are the core of the optional class +implementation. +* Andrei Alexandrescu and Brian Parker also worked with aligned storage +techniques and their work influenced the current implementation. +* Gennadiy Rozental made extensive and important comments which shaped the +design. +* Vesa Karvonen and Douglas Gregor made quite useful comparisons between +optional, variant and any; and made other relevant comments. +* Douglas Gregor and Peter Dimov commented on comparisons and evaluation +in boolean contexts. +* Eric Friedman helped understand the issues involved with aligned storage, +move/copy operations and exception safety. +* Many others have participated with useful comments: Aleksey Gurotov, +Kevlin Henney, David Abrahams, and others I can't recall. + +[heading Post-formal review] + +* William Kempf carefully considered the originally proposed interface +and suggested the new interface which is currently used. He also started and +fueled the discussion about the analogy optional<>/smart pointer and about +relational operators. +* Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson +focused on the relational semantics of optional (originally undefined); +concluding with the fact that the pointer-like interface doesn't make it a +pointer so it shall have deep relational operators. +* Augustus Saunders also explored the different relational semantics between +optional<> and a pointer and developed the OptionalPointee concept as an aid +against potential conflicts on generic code. +* Joel de Guzman noticed that optional<> can be seen as an API on top of +variant. +* Dave Gomboc explained the meaning and usage of the Haskell analog to +optional<>: the Maybe type constructor (analogy originally pointed out by +David Sankel). +* Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, +Rob Stewart, and others. +* Joel de Guzman made the case for the support of references and helped +with the proper semantics. +* Mat Marcus shown the virtues of a value-oriented interface, influencing +the current design, and contributed the idea of "none". + +[endsect] + diff --git a/doc/dependencies.qbk b/doc/dependencies.qbk new file mode 100644 index 0000000..6aa0eb5 --- /dev/null +++ b/doc/dependencies.qbk @@ -0,0 +1,17 @@ +[/ + Boost.Optional + + Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +] + + +[section Dependencies and Portability] + +The implementation uses `type_traits/alignment_of.hpp` and +`type_traits/type_with_alignment.hpp` + +[endsect] \ No newline at end of file diff --git a/doc/development.qbk b/doc/development.qbk new file mode 100644 index 0000000..cd00e45 --- /dev/null +++ b/doc/development.qbk @@ -0,0 +1,251 @@ +[/ + Boost.Optional + + Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +] + +[section Development] + +[section The models] + +In C++, we can ['declare] an object (a variable) of type `T`, and we can give this +variable an ['initial value] (through an ['initializer]. (c.f. 8.5)). +When a declaration includes a non-empty initializer (an initial value is given), +it is said that the object has been initialized. +If the declaration uses an empty initializer (no initial value is given), and +neither default nor value initialization applies, it is said that the object is +[*uninitialized]. Its actual value exist but has an ['indeterminate initial value] +(c.f. 8.5.9). +`optional` intends to formalize the notion of initialization (or lack of it) +allowing a program to test whether an object has been initialized and stating +that access to the value of an uninitialized object is undefined behavior. That +is, when a variable is declared as `optional` and no initial value is given, +the variable is ['formally] uninitialized. A formally uninitialized optional object +has conceptually no value at all and this situation can be tested at runtime. It +is formally ['undefined behavior] to try to access the value of an uninitialized +optional. An uninitialized optional can be assigned a value, in which case its initialization state changes to initialized. Furthermore, given the formal +treatment of initialization states in optional objects, it is even possible to +reset an optional to ['uninitialized]. + +In C++ there is no formal notion of uninitialized objects, which means that +objects always have an initial value even if indeterminate. +As discussed on the previous section, this has a drawback because you need +additional information to tell if an object has been effectively initialized. +One of the typical ways in which this has been historically dealt with is via +a special value: `EOF`, `npos`, -1, etc... This is equivalent to adding the +special value to the set of possible values of a given type. This super set of +`T` plus some ['nil_t]—were `nil_t` is some stateless POD-can be modeled in modern +languages as a [*discriminated union] of T and nil_t. Discriminated unions are +often called ['variants]. A variant has a ['current type], which in our case is either +`T` or `nil_t`. +Using the __BOOST_VARIANT__ library, this model can be implemented in terms of `boost::variant`. +There is precedent for a discriminated union as a model for an optional value: +the __HASKELL__ [*Maybe] built-in type constructor. Thus, a discriminated union +`T+nil_t` serves as a conceptual foundation. + +A `variant` follows naturally from the traditional idiom of extending +the range of possible values adding an additional sentinel value with the +special meaning of ['Nothing]. However, this additional ['Nothing] value is largely +irrelevant for our purpose since our goal is to formalize the notion of +uninitialized objects and, while a special extended value can be used to convey +that meaning, it is not strictly necessary in order to do so. + +The observation made in the last paragraph about the irrelevant nature of the +additional `nil_t` with respect to [_purpose] of `optional` suggests an +alternative model: a ['container] that either has a value of `T` or nothing. + +As of this writing I don't know of any precedence for a variable-size +fixed-capacity (of 1) stack-based container model for optional values, yet I +believe this is the consequence of the lack of practical implementations of +such a container rather than an inherent shortcoming of the container model. + +In any event, both the discriminated-union or the single-element container +models serve as a conceptual ground for a class representing optional—i.e. +possibly uninitialized—objects. +For instance, these models show the ['exact] semantics required for a wrapper +of optional values: + +Discriminated-union: + +* [*deep-copy] semantics: copies of the variant implies copies of the value. +* [*deep-relational] semantics: comparisons between variants matches both +current types and values +* If the variant's current type is `T`, it is modeling an ['initialized] optional. +* If the variant's current type is not `T`, it is modeling an ['uninitialized] +optional. +* Testing if the variant's current type is `T` models testing if the optional +is initialized +* Trying to extract a `T` from a variant when its current type is not `T`, models +the undefined behavior of trying to access the value of an uninitialized optional + +Single-element container: + +* [*deep-copy] semantics: copies of the container implies copies of the value. +* [*deep-relational] semantics: comparisons between containers compare container +size and if match, contained value +* If the container is not empty (contains an object of type `T`), it is modeling +an ['initialized] optional. +* If the container is empty, it is modeling an ['uninitialized] optional. +* Testing if the container is empty models testing if the optional is +initialized +* Trying to extract a `T` from an empty container models the undefined behavior +of trying to access the value of an uninitialized optional + +[endsect] + +[section The semantics] + +Objects of type `optional` are intended to be used in places where objects of +type `T` would but which might be uninitialized. Hence, `optional`'s purpose is +to formalize the additional possibly uninitialized state. +From the perspective of this role, `optional` can have the same operational +semantics of `T` plus the additional semantics corresponding to this special +state. +As such, `optional` could be thought of as a ['supertype] of `T`. Of course, we +can't do that in C++, so we need to compose the desired semantics using a +different mechanism. +Doing it the other way around, that is, making `optional` a ['subtype] of `T` +is not only conceptually wrong but also impractical: it is not allowed to +derive from a non-class type, such as a built-in type. + +We can draw from the purpose of `optional` the required basic semantics: + +* [*Default Construction:] To introduce a formally uninitialized wrapped +object. +* [*Direct Value Construction via copy:] To introduce a formally initialized +wrapped object whose value is obtained as a copy of some object. +* [*Deep Copy Construction:] To obtain a new yet equivalent wrapped object. +* [*Direct Value Assignment (upon initialized):] To assign a value to the +wrapped object. +* [*Direct Value Assignment (upon uninitialized):] To initialize the wrapped +object with a value obtained as a copy of some object. +* [*Assignment (upon initialized):] To assign to the wrapped object the value +of another wrapped object. +* [*Assignment (upon uninitialized):] To initialize the wrapped object with +value of another wrapped object. +* [*Deep Relational Operations (when supported by the type T):] To compare +wrapped object values taking into account the presence of uninitialized states. +* [*Value access:] To unwrap the wrapped object. +* [*Initialization state query:] To determine if the object is formally +initialized or not. +* [*Swap:] To exchange wrapped objects. (with whatever exception safety +guarantees are provided by `T`'s swap). +* [*De-initialization:] To release the wrapped object (if any) and leave the +wrapper in the uninitialized state. + +Additional operations are useful, such as converting constructors and +converting assignments, in-place construction and assignment, and safe +value access via a pointer to the wrapped object or null. + +[endsect] + +[section The Interface] + +Since the purpose of optional is to allow us to use objects with a formal +uninitialized additional state, the interface could try to follow the +interface of the underlying `T` type as much as possible. In order to choose +the proper degree of adoption of the native `T` interface, the following must +be noted: Even if all the operations supported by an instance of type `T` are +defined for the entire range of values for such a type, an `optional` +extends such a set of values with a new value for which most +(otherwise valid) operations are not defined in terms of `T`. + +Furthermore, since `optional` itself is merely a `T` wrapper (modeling a `T` +supertype), any attempt to define such operations upon uninitialized optionals +will be totally artificial w.r.t. `T`. + +This library chooses an interface which follows from `T`'s interface only for +those operations which are well defined (w.r.t the type `T`) even if any of the +operands are uninitialized. These operations include: construction, +copy-construction, assignment, swap and relational operations. + +For the value access operations, which are undefined (w.r.t the type `T`) when +the operand is uninitialized, a different interface is chosen (which will be +explained next). + +Also, the presence of the possibly uninitialized state requires additional +operations not provided by `T` itself which are supported by a special interface. + +[heading Lexically-hinted Value Access in the presence of possibly +untitialized optional objects: The operators * and ->] + +A relevant feature of a pointer is that it can have a [*null pointer value]. +This is a ['special] value which is used to indicate that the pointer is not +referring to any object at all. In other words, null pointer values convey +the notion of inexistent objects. + +This meaning of the null pointer value allowed pointers to became a ['de +facto] standard for handling optional objects because all you have to do +to refer to a value which you don't really have is to use a null pointer +value of the appropriate type. Pointers have been used for decades—from +the days of C APIs to modern C++ libraries—to ['refer] to optional (that is, +possibly inexistent) objects; particularly as optional arguments to a +function, but also quite often as optional data members. + +The possible presence of a null pointer value makes the operations that +access the pointee's value possibly undefined, therefore, expressions which +use dereference and access operators, such as: `( *p = 2 )` and `( p->foo() )`, +implicitly convey the notion of optionality, and this information is tied to +the ['syntax] of the expressions. That is, the presence of operators `*` and `->` +tell by themselves —without any additional context— that the expression will +be undefined unless the implied pointee actually exist. + +Such a ['de facto] idiom for referring to optional objects can be formalized +in the form of a concept: the __OPTIONAL_POINTEE__ concept. +This concept captures the syntactic usage of operators `*`, `->` and +conversion to `bool` to convey the notion of optionality. + +However, pointers are good to [_refer] to optional objects, but not particularly +good to handle the optional objects in all other respects, such as initializing +or moving/copying them. The problem resides in the shallow-copy of pointer +semantics: if you need to effectively move or copy the object, pointers alone +are not enough. The problem is that copies of pointers do not imply copies of +pointees. For example, as was discussed in the motivation, pointers alone +cannot be used to return optional objects from a function because the object +must move outside from the function and into the caller's context. + +A solution to the shallow-copy problem that is often used is to resort to +dynamic allocation and use a smart pointer to automatically handle the details +of this. For example, if a function is to optionally return an object `X`, it can +use `shared_ptr` as the return value. However, this requires dynamic allocation +of `X`. If `X` is a built-in or small POD, this technique is very poor in terms of +required resources. Optional objects are essentially values so it is very +convenient to be able to use automatic storage and deep-copy semantics to +manipulate optional values just as we do with ordinary values. Pointers do +not have this semantics, so are inappropriate for the initialization and +transport of optional values, yet are quite convenient for handling the access +to the possible undefined value because of the idiomatic aid present in the +__OPTIONAL_POINTEE__ concept incarnated by pointers. + + +[heading Optional as a model of OptionalPointee] + +For value access operations `optional<>` uses operators `*` and `->` to +lexically warn about the possibly uninitialized state appealing to the +familiar pointer semantics w.r.t. to null pointers. + +[warning +However, it is particularly important to note that `optional<>` objects +are not pointers. [_`optional<>` is not, and does not model, a pointer]. +] + +For instance, `optional<>` does not have shallow-copy so does not alias: +two different optionals never refer to the ['same] value unless `T` itself is +a reference (but may have ['equivalent] values). +The difference between an `optional` and a pointer must be kept in mind, +particularly because the semantics of relational operators are different: +since `optional` is a value-wrapper, relational operators are deep: they +compare optional values; but relational operators for pointers are shallow: +they do not compare pointee values. +As a result, you might be able to replace `optional` by `T*` on some +situations but not always. Specifically, on generic code written for both, +you cannot use relational operators directly, and must use the template +functions __FUNCTION_EQUAL_POINTEES__ and __FUNCTION_LESS_POINTEES__ instead. + +[endsect] + +[endsect] diff --git a/doc/examples.qbk b/doc/examples.qbk new file mode 100644 index 0000000..4bd7f6a --- /dev/null +++ b/doc/examples.qbk @@ -0,0 +1,102 @@ +[/ + Boost.Optional + + Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +] + + +[section Examples] + +[section Optional return values] + + optional get_async_input() + { + if ( !queue.empty() ) + return optional(queue.top()); + else return optional(); // uninitialized + } + + void receive_async_message() + { + optional rcv ; + // The safe boolean conversion from 'rcv' is used here. + while ( (rcv = get_async_input()) && !timeout() ) + output(*rcv); + } + +[endsect] + +[section Optional local variables] + + optional name ; + if ( database.open() ) + { + name.reset ( database.lookup(employer_name) ) ; + } + else + { + if ( can_ask_user ) + name.reset ( user.ask(employer_name) ) ; + } + + if ( name ) + print(*name); + else print("employer's name not found!"); + +[endsect] + +[section Optional data members] + + class figure + { + public: + + figure() + { + // data member 'm_clipping_rect' is uninitialized at this point. + } + + void clip_in_rect ( rect const& rect ) + { + .... + m_clipping_rect.reset ( rect ) ; // initialized here. + } + + void draw ( canvas& cvs ) + { + if ( m_clipping_rect ) + do_clipping(*m_clipping_rect); + + cvs.drawXXX(..); + } + + // this can return NULL. + rect const* get_clipping_rect() { return get_pointer(m_clipping_rect); } + + private : + + optional m_clipping_rect ; + + }; + +[endsect] + +[section Bypassing expensive unnecessary default construction] + + class ExpensiveCtor { ... } ; + class Fred + { + Fred() : mLargeVector(10000) {} + + std::vector< optional > mLargeVector ; + } ; + +[endsect] + +[endsect] + + diff --git a/doc/html/HTML.manifest b/doc/html/HTML.manifest new file mode 100644 index 0000000..759b268 --- /dev/null +++ b/doc/html/HTML.manifest @@ -0,0 +1,14 @@ +index.html +boost_optional/development.html +boost_optional/synopsis.html +boost_optional/detailed_semantics.html +boost_optional/examples.html +boost_optional/optional_references.html +boost_optional/rebinding_semantics_for_assignment_of_optional_references.html +boost_optional/in_place_factories.html +boost_optional/a_note_about_optional_bool_.html +boost_optional/exception_safety_guarantees.html +boost_optional/type_requirements.html +boost_optional/implementation_notes.html +boost_optional/dependencies_and_portability.html +boost_optional/acknowledgments.html diff --git a/doc/html/boost_optional/a_note_about_optional_bool_.html b/doc/html/boost_optional/a_note_about_optional_bool_.html new file mode 100644 index 0000000..42d69df --- /dev/null +++ b/doc/html/boost_optional/a_note_about_optional_bool_.html @@ -0,0 +1,84 @@ + + + +A note about + optional<bool> + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + optional<bool> should + be used with special caution and consideration. +

    +

    + First, it is functionally similar to a tristate boolean (false,maybe,true) + —such as boost::tribool— + except that in a tristate boolean, the maybe state represents + a valid value, unlike the corresponding state of an uninitialized + optional<bool>. It + should be carefully considered if an optional<bool> + instead of a tribool is really + needed. +

    +

    + Second, optional<> + provides an implicit conversion to bool. + This conversion refers to the initialization state and not to the contained + value. Using optional<bool> can + lead to subtle errors due to the implicit bool + conversion: +

    +
    +void foo ( bool v ) ;
    +void bar()
    +{
    +    optional<bool> v = try();
    +
    +    // The following intended to pass the value of 'v' to foo():
    +    foo(v);
    +    // But instead, the initialization state is passed
    +    // due to a typo: it should have been foo(*v).
    +}
    +
    +

    + The only implicit conversion is to bool, + and it is safe in the sense that typical integral promotions don't apply (i.e. + if foo() + takes an int instead, it won't + compile). +

    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/acknowledgments.html b/doc/html/boost_optional/acknowledgments.html new file mode 100644 index 0000000..e2cc05a --- /dev/null +++ b/doc/html/boost_optional/acknowledgments.html @@ -0,0 +1,122 @@ + + + +Acknowledgments + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHome +
    +
    + +

    + + Pre-formal + review +

    +
      +
    • + Peter Dimov suggested the name 'optional', and was the first to point out + the need for aligned storage. +
    • +
    • + Douglas Gregor developed 'type_with_alignment', and later Eric Friedman coded + 'aligned_storage', which are the core of the optional class implementation. +
    • +
    • + Andrei Alexandrescu and Brian Parker also worked with aligned storage techniques + and their work influenced the current implementation. +
    • +
    • + Gennadiy Rozental made extensive and important comments which shaped the + design. +
    • +
    • + Vesa Karvonen and Douglas Gregor made quite useful comparisons between optional, + variant and any; and made other relevant comments. +
    • +
    • + Douglas Gregor and Peter Dimov commented on comparisons and evaluation in + boolean contexts. +
    • +
    • + Eric Friedman helped understand the issues involved with aligned storage, + move/copy operations and exception safety. +
    • +
    • + Many others have participated with useful comments: Aleksey Gurotov, Kevlin + Henney, David Abrahams, and others I can't recall. +
    • +
    +

    + + Post-formal + review +

    +
      +
    • + William Kempf carefully considered the originally proposed interface and + suggested the new interface which is currently used. He also started and + fueled the discussion about the analogy optional<>/smart pointer and + about relational operators. +
    • +
    • + Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson + focused on the relational semantics of optional (originally undefined); concluding + with the fact that the pointer-like interface doesn't make it a pointer so + it shall have deep relational operators. +
    • +
    • + Augustus Saunders also explored the different relational semantics between + optional<> and a pointer and developed the OptionalPointee concept + as an aid against potential conflicts on generic code. +
    • +
    • + Joel de Guzman noticed that optional<> can be seen as an API on top + of variant<T,nil_t>. +
    • +
    • + Dave Gomboc explained the meaning and usage of the Haskell analog to optional<>: + the Maybe type constructor (analogy originally pointed out by David Sankel). +
    • +
    • + Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, Rob + Stewart, and others. +
    • +
    • + Joel de Guzman made the case for the support of references and helped with + the proper semantics. +
    • +
    • + Mat Marcus shown the virtues of a value-oriented interface, influencing the + current design, and contributed the idea of "none". +
    • +
    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHome +
    + + diff --git a/doc/html/boost_optional/dependencies_and_portability.html b/doc/html/boost_optional/dependencies_and_portability.html new file mode 100644 index 0000000..ccc0d2c --- /dev/null +++ b/doc/html/boost_optional/dependencies_and_portability.html @@ -0,0 +1,46 @@ + + + +Dependencies + and Portability + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + The implementation uses type_traits/alignment_of.hpp and + type_traits/type_with_alignment.hpp +

    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/detailed_semantics.html b/doc/html/boost_optional/detailed_semantics.html new file mode 100644 index 0000000..bbebfd7 --- /dev/null +++ b/doc/html/boost_optional/detailed_semantics.html @@ -0,0 +1,1703 @@ + + + +Detailed Semantics + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + Because T might be of reference + type, in the sequel, those entries whose semantic depends on T being of reference type or not will be + distinguished using the following convention: * If the entry reads: optional<T(not a ref)>, the description corresponds only to the + case where T is not of reference + type. * If the entry reads: optional<T&>, + the description corresponds only to the case where T + is of reference type. * If the entry reads: optional<T>, + the description is the same for both cases. +

    +
    + + + + + +
    [Note]Note
    +

    +

    +

    + The following section contains various assert() which are used only to show the postconditions + as sample code. It is not implied that the type T + must support each particular expression but that if the expression is supported, + the implied condition holds. +

    +

    +

    +
    +

    + space +

    +

    + + optional + class member functions +

    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional<T>::optional(); +

    +

    +

    +
    +
      +
    • +Effect: Default-Constructs an optional. +
    • +
    • +Postconditions:*this is uninitialized. +
    • +
    • +Throws: Nothing. +
    • +
    • + Notes: T's default constructor is not + called. +
    • +
    • +Example:
      +optional<T> def ;
      +assert ( !def ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional<T>::optional( none_t ); +

    +

    +

    +
    +
      +
    • +Effect: Constructs an optional + uninitialized. +
    • +
    • +Postconditions:*this is uninitialized. +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes:T's + default constructor is not called. + The expression boost::none denotes an instance of boost::none_t that can be used as the parameter. +
    • +
    • +Example:
      +#include <boost/none.hpp>
      +optional<T> n(none) ;
      +assert ( !n ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional<T (not a ref)>::optional( T const& v ) +

    +

    +

    +
    +
      +
    • +Effect: Directly-Constructs an optional. +
    • +
    • +Postconditions:*this is initialized + and its value is acopy of v. +
    • +
    • +Throws: Whatever T::T( + T const& ) throws. +
    • +
    • +Notes: T::T( + T const& ) is + called. +
    • +
    • +Exception Safety: Exceptions can only be + thrown during T::T( T + const& + ); in that case, this constructor + has no effect. +
    • +
    • +Example:
      +T v;
      +optional<T> opt(v);
      +assert ( *opt == v ) ;
      +
      +
    • +
    +

    + space +

    +
    +

    +

    +

    + optional<T&>::optional( T& ref ) +

    +

    +

    +
    +
      +
    • +Effect: Directly-Constructs an optional. +
    • +
    • +Postconditions:*this is initialized + and its value is an instance of an internal type wrapping the reference + ref. +
    • +
    • +Throws: Nothing. +
    • +
    • +Example:
      +T v;
      +T& vref = v ;
      +optional<T&> opt(vref);
      +assert ( *opt == v ) ;
      +++ v ; // mutate referee
      +assert (*opt == v);
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional<T (not a ref)>::optional( bool condition, + T const& v ) ; +

    +

    +

    +
    +
    +

    +

    +

    + optional<T&> + ::optional( bool condition, + T& + v ) + ; +

    +

    +

    +
    +
    • + If condition is true, same as: +
    +
    +

    +

    +

    + optional<T (not a ref)>::optional( T const& v ) +

    +

    +

    +
    +
    +

    +

    +

    + optional<T&> + ::optional( T& + v ) +

    +

    +

    +
    +
    • + otherwise, same as: +
    +
    +

    +

    +

    + optional<T [#(not a + ref)]>::optional() +

    +

    +

    +
    +
    +

    +

    +

    + optional<T&> + ::optional() +

    +

    +

    +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional<T (not a ref)>::optional( optional + const& + rhs ); +

    +

    +

    +
    +
      +
    • +Effect: Copy-Constructs an optional. +
    • +
    • +Postconditions: If rhs is initialized, + *this + is initialized and its value is a copy of the value + of rhs; else *this is uninitialized. +
    • +
    • +Throws: Whatever T::T( + T const& ) throws. +
    • +
    • +Notes: If rhs is initialized, T::T(T const& ) is + called. +
    • +
    • +Exception Safety: Exceptions can only be + thrown during T::T( T + const& + ); in that case, this constructor + has no effect. +
    • +
    • +Example:
      +optional<T> uninit ;
      +assert (!uninit);
      +
      +optional<T> uinit2 ( uninit ) ;
      +assert ( uninit2 == uninit );
      +
      +optional<T> init( T(2) );
      +assert ( *init == T(2) ) ;
      +
      +optional<T> init2 ( init ) ;
      +assert ( init2 == init ) ;
      +
      +
    • +
    +

    + space +

    +
    +

    +

    +

    + optional<T&>::optional( optional const& rhs ); +

    +

    +

    +
    +
      +
    • +Effect: Copy-Constructs an optional. +
    • +
    • +Postconditions: If rhs + is initialized, *this + is initialized and its value is another reference to the same object referenced + by *rhs; + else *this + is uninitialized. +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes: If rhs + is initialized, both *this + and *rhs + will reefer to the same object (they alias). +
    • +
    • +Example:
      +optional<T&> uninit ;
      +assert (!uninit);
      +
      +optional<T&> uinit2 ( uninit ) ;
      +assert ( uninit2 == uninit );
      +
      +T v = 2 ; T& ref = v ;
      +optional<T> init(ref);
      +assert ( *init == v ) ;
      +
      +optional<T> init2 ( init ) ;
      +assert ( *init2 == v ) ;
      +
      +v = 3 ;
      +
      +assert ( *init  == 3 ) ;
      +assert ( *init2 == 3 ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + template<U> explicit optional<T + (not a ref)>::optional( optional<U> const& rhs ); +

    +

    +

    +
    +
      +
    • +Effect: Copy-Constructs an optional. +
    • +
    • +Postconditions: If rhs + is initialized, *this + is initialized and its value is a copy of the value + of rhs converted to type T; + else *this + is uninitialized. +
    • +
    • +Throws: Whatever T::T( + U const& ) throws. +
    • +
    • +Notes: T::T( + U const& ) is + called if rhs is initialized, + which requires a valid conversion from U + to T. +
    • +
    • +Exception Safety: Exceptions can only be + thrown during T::T( U + const& + ); in that case, this constructor + has no effect. +
    • +
    • +Example:
      +optional<double> x(123.4);
      +assert ( *x == 123.4 ) ;
      +
      +optional<int> y(x) ;
      +assert( *y == 123 ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + template<InPlaceFactory> + explicit optional<T + (not a ref)>::optional( InPlaceFactory const& f ); +

    +

    +

    +
    +
    +

    +

    +

    + template<TypedInPlaceFactory> + explicit optional<T + (not a ref)>::optional( TypedInPlaceFactory const& f ); +

    +

    +

    +
    +
      +
    • +Effect: Constructs an optional + with a value of T obtained + from the factory. +
    • +
    • +Postconditions: *this is initialized + and its value is directly given from the factory f (i.e., the value is + not copied). +
    • +
    • +Throws: Whatever the T + constructor called by the factory throws. +
    • +
    • +Notes: See In-Place + Factories +
    • +
    • +Exception Safety: Exceptions can only be + thrown during the call to the T + constructor used by the factory; in that case, this constructor has no effect. +
    • +
    • +Example:
      +class C { C ( char, double, std::string ) ; } ;
      +
      +C v('A',123.4,"hello");
      +
      +optional<C> x( in_place   ('A', 123.4, "hello") ); // InPlaceFactory used
      +optional<C> y( in_place<C>('A', 123.4, "hello") ); // TypedInPlaceFactory used
      +
      +assert ( *x == v ) ;
      +assert ( *y == v ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional& + optional<T (not a ref)>::operator= ( T + const& + rhs ) + ; +

    +

    +

    +
    +
      +
    • +Effect: Assigns the value rhs to an optional. +
    • +
    • +Postconditions: *this is initialized and its value is a copy + of rhs. +
    • +
    • +Throws: Whatever T::operator=( T const& ) or + T::T(T + const&) + throws. +
    • +
    • +Notes: If *this was initialized, T's + assignment operator is used, otherwise, its copy-constructor is used. +
    • +
    • +Exception Safety: In the event of an exception, + the initialization state of *this is unchanged and its value unspecified + as far as optional is concerned + (it is up to T's operator=()). + If *this + is initially uninitialized and T's + copy constructor fails, *this is left properly uninitialized. +
    • +
    • +Example:
      +T x;
      +optional<T> def ;
      +optional<T> opt(x) ;
      +
      +T y;
      +def = y ;
      +assert ( *def == y ) ;
      +opt = y ;
      +assert ( *opt == y ) ;
      +
      +
    • +
    +

    + space +

    +
    +

    +

    +

    + optional<T&>& + optional<T&>::operator= ( T& + const& + rhs ) + ; +

    +

    +

    +
    +
      +
    • +Effect: (Re)binds thee wrapped reference. +
    • +
    • +Postconditions: *this is initialized and it references the + same object referenced by rhs. +
    • +
    • +Notes: If *this was initialized, is is rebound + to the new object. See here for + details on this behavior. +
    • +
    • +Example:
      +int a = 1 ;
      +int b = 2 ;
      +T& ra = a ;
      +T& rb = b ;
      +optional<int&> def ;
      +optional<int&> opt(ra) ;
      +
      +def = rb ; // binds 'def' to 'b' through 'rb'
      +assert ( *def == b ) ;
      +*def = a ; // changes the value of 'b' to a copy of the value of 'a'
      +assert ( b == a ) ;
      +int c = 3;
      +int& rc = c ;
      +opt = rc ; // REBINDS to 'c' through 'rc'
      +c = 4 ;
      +assert ( *opt == 4 ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional& + optional<T (not a ref)>::operator= ( optional + const& + rhs ) + ; +

    +

    +

    +
    +
      +
    • +Effect: Assigns another optional + to an optional. +
    • +
    • +Postconditions: If rhs + is initialized, *this + is initialized and its value is a copy of the value + of rhs; else *this is uninitialized. +
    • +
    • +Throws: Whatever T::operator( T const&) or T::T( + T const& ) throws. +
    • +
    • +Notes: If both *this and rhs + are initially initialized, T's + assignment operator is used. If *this is initially initialized but rhs is uninitialized, T's + [destructor] is called. If *this is initially uninitialized but rhs is initialized, T's + copy constructor is called. +
    • +
    • +Exception Safety: In the event of an exception, + the initialization state of *this is unchanged and its value unspecified + as far as optional is concerned (it is up to T's + operator=()). + If *this + is initially uninitialized and T's + copy constructor fails, *this is left properly uninitialized. +
    • +
    • +Example:
      +T v;
      +optional<T> opt(v);
      +optional<T> def ;
      +
      +opt = def ;
      +assert ( !def ) ;
      +// previous value (copy of 'v') destroyed from within 'opt'.
      +
      +
    • +
    +

    + space +

    +
    +

    +

    +

    + optional<T&> + & optional<T&>::operator= ( optional<T&> const& rhs ) ; +

    +

    +

    +
    +
      +
    • +Effect: (Re)binds thee wrapped reference. +
    • +
    • +Postconditions: If *rhs is initialized, *this is initialized and it references the + same object referenced by *rhs; otherwise, *this is uninitialized (and references no object). +
    • +
    • +Notes: If *this was initialized and so is *rhs, this + is is rebound to the new object. See here + for details on this behavior. +
    • +
    • +Example:
      +int a = 1 ;
      +int b = 2 ;
      +T& ra = a ;
      +T& rb = b ;
      +optional<int&> def ;
      +optional<int&> ora(ra) ;
      +optional<int&> orb(rb) ;
      +
      +def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb'
      +assert ( *def == b ) ;
      +*def = ora ; // changes the value of 'b' to a copy of the value of 'a'
      +assert ( b == a ) ;
      +int c = 3;
      +int& rc = c ;
      +optional<int&> orc(rc) ;
      +ora = orc ; // REBINDS ora to 'c' through 'rc'
      +c = 4 ;
      +assert ( *ora == 4 ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + template<U> optional& + optional<T (not a ref)>::operator= ( optional<U> const& rhs ) ; +

    +

    +

    +
    +
      +
    • +Effect: Assigns another convertible optional + to an optional. +
    • +
    • +Postconditions: If rhs + is initialized, *this + is initialized and its value is a copy of the value + of rhsconverted + to type T; else *this is uninitialized. +
    • +
    • +Throws: Whatever T::operator=( U const& ) or + T::T( U + const& + ) throws. +
    • +
    • +Notes: If both *this and rhs are initially initialized, T's assignment operator + (from U) is used. If *this is initially + initialized but rhs is uninitialized, + T's destructor + is called. If *this + is initially uninitialized but rhs is initialized, T's + converting constructor (from U) + is called. +
    • +
    • +Exception Safety: In the event of an exception, + the initialization state of *this is unchanged and its value unspecified + as far as optional is concerned (it is up to T's + operator=()). + If *this + is initially uninitialized and T's + converting constructor fails, *this is left properly uninitialized. +
    • +
    • +Example:
      +T v;
      +optional<T> opt0(v);
      +optional<U> opt1;
      +
      +opt1 = opt0 ;
      +assert ( *opt1 == static_cast<U>(v) ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + void optional<T + (not a ref)>::reset( T const& v ) ; +

    +

    +

    +
    +
    • +Deprecated: same as operator= ( T + const& + v) ; +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + void optional<T>::reset() ; +

    +

    +

    +
    +
    • +Deprecated: Same as operator=( detail::none_t ); +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + T const& optional<T + (not a ref)>::operator*() const ; +

    +

    +

    +
    +
    +

    +

    +

    + T& + optional<T (not a ref)>::operator*(); +

    +

    +

    +
    +
    +

    +

    +

    + T const& optional<T + (not a ref)>::get() const ; +

    +

    +

    +
    +
    +

    +

    +

    + T& + optional<T (not a ref)>::get() ; +

    +

    +

    +
    +
    +

    +

    +

    + inline T + const& + get ( + optional<T (not a ref)> const& ) ; +

    +

    +

    +
    +
    +

    +

    +

    + inline T& get ( optional<T + (not a ref)> + &) ; +

    +

    +

    +
    +
      +
    • +Requirements:*this is initialized +
    • +
    • +Returns: A reference to the contained value +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes: The requirement is asserted via + BOOST_ASSERT(). +
    • +
    • +Example:
      +T v ;
      +optional<T> opt ( v );
      +T const& u = *opt;
      +assert ( u == v ) ;
      +T w ;
      +*opt = w ;
      +assert ( *opt == w ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + 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 ) ;
      +
      +
    • +
    +

    + space +

    +
    +

    +

    +

    + T const& optional<T&>::operator*() const ; +

    +

    +

    +
    +
    +

    +

    +

    + T & + optional<T&>::operator*(); +

    +

    +

    +
    +
    +

    +

    +

    + T const& optional<T&>::get() const ; +

    +

    +

    +
    +
    +

    +

    +

    + T& + optional<T&>::get() ; +

    +

    +

    +
    +
    +

    +

    +

    + inline T + const& + get ( + optional<T&> + const& + ) ; +

    +

    +

    +
    +
    +

    +

    +

    + inline T& get ( optional<T&> &) + ; +

    +

    +

    +
    +
      +
    • +Requirements: *this is initialized +
    • +
    • +Returns:The + reference contained. +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes: The requirement is asserted via + BOOST_ASSERT(). +
    • +
    • +Example:
      +T v ;
      +T& vref = v ;
      +optional<T&> opt ( vref );
      +T const& vref2 = *opt;
      +assert ( vref2 == v ) ;
      +++ v ;
      +assert ( *opt == v ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + T const* optional<T + (not a ref)>::get_ptr() const ; +

    +

    +

    +
    +
    +

    +

    +

    + T* + optional<T (not a ref)>::get_ptr() ; +

    +

    +

    +
    +
    +

    +

    +

    + inline T + const* + get_pointer ( + optional<T (not a ref)> const& ) ; +

    +

    +

    +
    +
    +

    +

    +

    + inline T* get_pointer + ( optional<T + (not a ref)> + &) ; +

    +

    +

    +
    +
      +
    • +Returns: If *this is initialized, a pointer to the contained + value; else 0 (null). +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes: The contained value is permanently + stored within *this, + so you should not hold nor delete this pointer +
    • +
    • +Example:
      +T v;
      +optional<T> opt(v);
      +optional<T> const copt(v);
      +T* p = opt.get_ptr() ;
      +T const* cp = copt.get_ptr();
      +assert ( p == get_pointer(opt) );
      +assert ( cp == get_pointer(copt) ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + T const* optional<T + (not a ref)>::operator ->() + const ; +

    +

    +

    +
    +
    +

    +

    +

    + T* + optional<T (not a ref)>::operator + ->() ; +

    +

    +

    +
    +
      +
    • +Requirements: *this is initialized. +
    • +
    • +Returns: A pointer to the contained value. +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes: The requirement is asserted via + BOOST_ASSERT(). +
    • +
    • +Example:
      +struct X { int mdata ; } ;
      +X x ;
      +optional<X> opt (x);
      +opt->mdata = 2 ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional<T>::operator unspecified-bool-type() const ; +

    +

    +

    +
    +
      +
    • +Returns: An unspecified value which if used + on a boolean context is equivalent to (get() != 0) +
    • +
    • +Throws: Nothing. +
    • +
    • +Example:
      +optional<T> def ;
      +assert ( def == 0 );
      +optional<T> opt ( v ) ;
      +assert ( opt );
      +assert ( opt != 0 );
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + bool optional<T>::operator!() ; +

    +

    +

    +
    +
      +
    • +Returns: If *this is uninitialized, true; + else false. +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes: This operator is provided for those + compilers which can't use the unspecified-bool-type operator + in certain boolean contexts. +
    • +
    • +Example:
      +optional<T> opt ;
      +assert ( !opt );
      +*opt = some_T ;
      +
      +// Notice the "double-bang" idiom here.
      +assert ( !!opt ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + bool optional<T>::is_initialized() const ; +

    +

    +

    +
    +
      +
    • +Returns: true + if the optional is initialized, + false otherwise. +
    • +
    • +Throws: Nothing. +
    • +
    • +Example:
      +optional<T> def ;
      +assert ( !def.is_initialized() );
      +optional<T> opt ( v ) ;
      +assert ( opt.is_initialized() );
      +
      +
    • +
    +

    + space +

    +

    + + Free functions +

    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional<T (not a ref)> make_optional( T const& v ) +

    +

    +

    +
    +
      +
    • +Returns: optional<T>(v) for + the deduced type T + of v. +
    • +
    • +Example:
      +template<class T> void foo ( optional<T> const& opt ) ;
      +
      +foo ( make_optional(1+1) ) ; // Creates an optional<int>
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + optional<T (not a ref)> make_optional( bool condition, + T const& v ) +

    +

    +

    +
    +
      +
    • +Returns: optional<T>(condition,v) for + the deduced type T + of v. +
    • +
    • +Example:
      +optional<double> calculate_foo()
      +{
      +  double val = compute_foo();
      +  return make_optional(is_not_nan_and_finite(val),val);
      +}
      +
      +optional<double> v = calculate_foo();
      +if ( !v )
      +  error("foo wasn't computed");
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

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

    +

    +

    +
    +
      +
    • +Returns: If both x + and y are initialized, (*x == + *y). If only x + or y is initialized, false. If both are uninitialized, true. +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes: Pointers have shallow relational + operators while optional + has deep relational operators. Do not use operator + == directly in generic code which + expect to be given either an optional<T> + or a pointer; use equal_pointees() + instead +
    • +
    • +Example:
      +T x(12);
      +T y(12);
      +T z(21);
      +optional<T> def0 ;
      +optional<T> def1 ;
      +optional<T> optX(x);
      +optional<T> optY(y);
      +optional<T> optZ(z);
      +
      +// Identity always hold
      +assert ( def0 == def0 );
      +assert ( optX == optX );
      +
      +// Both uninitialized compare equal
      +assert ( def0 == def1 );
      +
      +// Only one initialized compare unequal.
      +assert ( def0 != optX );
      +
      +// Both initialized compare as (*lhs == *rhs)
      +assert ( optX == optY ) ;
      +assert ( optX != optZ ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + bool operator + < ( + optional<T> const& x, optional<T> const& y ); +

    +

    +

    +
    +
      +
    • +Returns: If y + is not initialized, false. If + y is initialized and x is not initialized, true. + If both x and y are initialized, (*x < *y). +
    • +
    • +Throws: Nothing. +
    • +
    • +Notes: Pointers have shallow relational + operators while optional + has deep relational operators. Do not use operator + < directly in generic code which + expect to be given either an optional<T> + or a pointer; use less_pointees() + instead. +
    • +
    • +Example:
      +T x(12);
      +T y(34);
      +optional<T> def ;
      +optional<T> optX(x);
      +optional<T> optY(y);
      +
      +// Identity always hold
      +assert ( !(def < def) );
      +assert ( optX == optX );
      +
      +// Both uninitialized compare equal
      +assert ( def0 == def1 );
      +
      +// Only one initialized compare unequal.
      +assert ( def0 != optX );
      +
      +// Both initialized compare as (*lhs == *rhs)
      +assert ( optX == optY ) ;
      +assert ( optX != optZ ) ;
      +
      +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

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

    +

    +

    +
    +
      +
    • +Returns: !( + x == + y ); +
    • +
    • +Throws: Nothing. +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + bool operator + > ( + optional<T> const& x, optional<T> const& y ); +

    +

    +

    +
    +
      +
    • +Returns: ( + y < + x ); +
    • +
    • +Throws: Nothing. +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

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

    +

    +

    +
    +
      +
    • +Returns: !( + y<x ); +
    • +
    • +Throws: Nothing. +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

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

    +

    +

    +
    +
      +
    • +Returns: !( + x<y ); +
    • +
    • +Throws: Nothing. +
    • +
    +

    + space +

    +

    +

    +
    +

    +

    +

    + void swap + ( optional<T>& x, optional<T>& y + ); +

    +

    +

    +
    +
      +
    • +Effect: If both x + and y are initialized, calls + swap(*x,*y) using std::swap. + If only one is initialized, say x, + calls: y.reset(*x); x.reset(); If none is initialized, does nothing. +
    • +
    • +Postconditions: The states of x and y + interchanged. +
    • +
    • +Throws: If both are initialized, whatever + swap(T&,T&) + throws. If only one is initialized, whatever T::T ( + T const& ) throws. +
    • +
    • +Notes: If both are initialized, swap(T&,T&) is used unqualified but with std::swap + introduced in scope. If only one is initialized, T::~T() + and T::T( T + const& + ) is called. +
    • +
    • +Exception Safety: If both are initialized, + this operation has the exception safety guarantees of swap(T&,T&). + If only one is initialized, it has the same basic guarantee as optional<T>::reset( T const& ). +
    • +
    • +Example:
      +T x(12);
      +T y(21);
      +optional<T> def0 ;
      +optional<T> def1 ;
      +optional<T> optX(x);
      +optional<T> optY(y);
      +
      +boost::swap(def0,def1); // no-op
      +
      +boost::swap(def0,optX);
      +assert ( *def0 == x );
      +assert ( !optX );
      +
      +boost::swap(def0,optX); // Get back to original values
      +
      +boost::swap(optX,optY);
      +assert ( *optX == y );
      +assert ( *optY == x );
      +
      +
    • +
    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/development.html b/doc/html/boost_optional/development.html new file mode 100644 index 0000000..c013432 --- /dev/null +++ b/doc/html/boost_optional/development.html @@ -0,0 +1,415 @@ + + + +Development + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + + +
    + +

    + In C++, we can declare an object (a variable) of type + T, and we can give this variable + an initial value (through an initializer. + (c.f. 8.5)). When a declaration includes a non-empty initializer (an initial + value is given), it is said that the object has been initialized. If the + declaration uses an empty initializer (no initial value is given), and neither + default nor value initialization applies, it is said that the object is + uninitialized. Its actual value exist but + has an indeterminate initial value (c.f. 8.5.9). optional<T> intends + to formalize the notion of initialization (or lack of it) allowing a program + to test whether an object has been initialized and stating that access to + the value of an uninitialized object is undefined behavior. That is, when + a variable is declared as optional<T> + and no initial value is given, the variable is formally + uninitialized. A formally uninitialized optional object has conceptually + no value at all and this situation can be tested at runtime. It is formally + undefined behavior to try to access the value of an + uninitialized optional. An uninitialized optional can be assigned a value, + in which case its initialization state changes to initialized. Furthermore, + given the formal treatment of initialization states in optional objects, + it is even possible to reset an optional to uninitialized. +

    +

    + In C++ there is no formal notion of uninitialized objects, which means that + objects always have an initial value even if indeterminate. As discussed + on the previous section, this has a drawback because you need additional + information to tell if an object has been effectively initialized. One of + the typical ways in which this has been historically dealt with is via a + special value: EOF, npos, -1, etc... This is equivalent to + adding the special value to the set of possible values of a given type. This + super set of T plus some + nil_t—were nil_t + is some stateless POD-can be modeled in modern languages as a discriminated + union of T and nil_t. Discriminated unions are often called variants. + A variant has a current type, which in our case is either + T or nil_t. + Using the Boost.Variant + library, this model can be implemented in terms of boost::variant<T,nil_t>. + There is precedent for a discriminated union as a model for an optional value: + the Haskell Maybe + built-in type constructor. Thus, a discriminated union T+nil_t + serves as a conceptual foundation. +

    +

    + A variant<T,nil_t> follows naturally from the traditional + idiom of extending the range of possible values adding an additional sentinel + value with the special meaning of Nothing. However, + this additional Nothing value is largely irrelevant + for our purpose since our goal is to formalize the notion of uninitialized + objects and, while a special extended value can be used to convey that meaning, + it is not strictly necessary in order to do so. +

    +

    + The observation made in the last paragraph about the irrelevant nature of + the additional nil_t with + respect to purpose of optional<T> suggests + an alternative model: a container that either has a + value of T or nothing. +

    +

    + As of this writing I don't know of any precedence for a variable-size fixed-capacity + (of 1) stack-based container model for optional values, yet I believe this + is the consequence of the lack of practical implementations of such a container + rather than an inherent shortcoming of the container model. +

    +

    + In any event, both the discriminated-union or the single-element container + models serve as a conceptual ground for a class representing optional—i.e. + possibly uninitialized—objects. For instance, these models show the exact + semantics required for a wrapper of optional values: +

    +

    + Discriminated-union: +

    +
      +
    • +deep-copy semantics: copies of the variant + implies copies of the value. +
    • +
    • +deep-relational semantics: comparisons + between variants matches both current types and values +
    • +
    • + If the variant's current type is T, + it is modeling an initialized optional. +
    • +
    • + If the variant's current type is not T, + it is modeling an uninitialized optional. +
    • +
    • + Testing if the variant's current type is T + models testing if the optional is initialized +
    • +
    • + Trying to extract a T from + a variant when its current type is not T, + models the undefined behavior of trying to access the value of an uninitialized + optional +
    • +
    +

    + Single-element container: +

    +
      +
    • +deep-copy semantics: copies of the container + implies copies of the value. +
    • +
    • +deep-relational semantics: comparisons + between containers compare container size and if match, contained value +
    • +
    • + If the container is not empty (contains an object of type T), it is modeling an initialized + optional. +
    • +
    • + If the container is empty, it is modeling an uninitialized + optional. +
    • +
    • + Testing if the container is empty models testing if the optional is initialized +
    • +
    • + Trying to extract a T from + an empty container models the undefined behavior of trying to access the + value of an uninitialized optional +
    • +
    +
    +
    + +

    + Objects of type optional<T> + are intended to be used in places where objects of type T + would but which might be uninitialized. Hence, optional<T>'s + purpose is to formalize the additional possibly uninitialized state. From + the perspective of this role, optional<T> + can have the same operational semantics of T + plus the additional semantics corresponding to this special state. As such, + optional<T> could + be thought of as a supertype of T. + Of course, we can't do that in C++, so we need to compose the desired semantics + using a different mechanism. Doing it the other way around, that is, making + optional<T> a + subtype of T + is not only conceptually wrong but also impractical: it is not allowed to + derive from a non-class type, such as a built-in type. +

    +

    + We can draw from the purpose of optional<T> + the required basic semantics: +

    +
      +
    • +Default Construction: To introduce a formally + uninitialized wrapped object. +
    • +
    • +Direct Value Construction via copy: To + introduce a formally initialized wrapped object whose value is obtained + as a copy of some object. +
    • +
    • +Deep Copy Construction: To obtain a new + yet equivalent wrapped object. +
    • +
    • +Direct Value Assignment (upon initialized): + To assign a value to the wrapped object. +
    • +
    • +Direct Value Assignment (upon uninitialized): + To initialize the wrapped object with a value obtained as a copy of some + object. +
    • +
    • +Assignment (upon initialized): To assign + to the wrapped object the value of another wrapped object. +
    • +
    • +Assignment (upon uninitialized): To initialize + the wrapped object with value of another wrapped object. +
    • +
    • +Deep Relational Operations (when supported by the + type T): To compare wrapped object values taking into account + the presence of uninitialized states. +
    • +
    • +Value access: To unwrap the wrapped object. +
    • +
    • +Initialization state query: To determine + if the object is formally initialized or not. +
    • +
    • +Swap: To exchange wrapped objects. (with + whatever exception safety guarantees are provided by T's + swap). +
    • +
    • +De-initialization: To release the wrapped + object (if any) and leave the wrapper in the uninitialized state. +
    • +
    +

    + Additional operations are useful, such as converting constructors and converting + assignments, in-place construction and assignment, and safe value access + via a pointer to the wrapped object or null. +

    +
    +
    + +

    + Since the purpose of optional is to allow us to use objects with a formal + uninitialized additional state, the interface could try to follow the interface + of the underlying T type + as much as possible. In order to choose the proper degree of adoption of + the native T interface, the + following must be noted: Even if all the operations supported by an instance + of type T are defined for + the entire range of values for such a type, an optional<T> + extends such a set of values with a new value for which most (otherwise valid) + operations are not defined in terms of T. +

    +

    + Furthermore, since optional<T> + itself is merely a T wrapper + (modeling a T supertype), + any attempt to define such operations upon uninitialized optionals will be + totally artificial w.r.t. T. +

    +

    + This library chooses an interface which follows from T's + interface only for those operations which are well defined (w.r.t the type + T) even if any of the operands + are uninitialized. These operations include: construction, copy-construction, + assignment, swap and relational operations. +

    +

    + For the value access operations, which are undefined (w.r.t the type T) when the operand is uninitialized, a + different interface is chosen (which will be explained next). +

    +

    + Also, the presence of the possibly uninitialized state requires additional + operations not provided by T + itself which are supported by a special interface. +

    +
    + + Lexically-hinted + Value Access in the presence of possibly untitialized optional objects: The + operators * and -> +
    +

    + A relevant feature of a pointer is that it can have a null + pointer value. This is a special value which + is used to indicate that the pointer is not referring to any object at all. + In other words, null pointer values convey the notion of inexistent objects. +

    +

    + This meaning of the null pointer value allowed pointers to became a de + facto standard for handling optional objects because all you have + to do to refer to a value which you don't really have is to use a null pointer + value of the appropriate type. Pointers have been used for decades—from + the days of C APIs to modern C++ libraries—to refer + to optional (that is, possibly inexistent) objects; particularly as optional + arguments to a function, but also quite often as optional data members. +

    +

    + The possible presence of a null pointer value makes the operations that access + the pointee's value possibly undefined, therefore, expressions which use + dereference and access operators, such as: ( + *p = 2 ) + and ( p->foo() ), implicitly + convey the notion of optionality, and this information is tied to the syntax + of the expressions. That is, the presence of operators * + and -> tell by themselves + —without any additional context— that the expression will be undefined + unless the implied pointee actually exist. +

    +

    + Such a de facto idiom for referring to optional objects + can be formalized in the form of a concept: the OptionalPointee + concept. This concept captures the syntactic usage of operators *, -> + and conversion to bool to convey + the notion of optionality. +

    +

    + However, pointers are good to refer + to optional objects, but not particularly good to handle the optional objects + in all other respects, such as initializing or moving/copying them. The problem + resides in the shallow-copy of pointer semantics: if you need to effectively + move or copy the object, pointers alone are not enough. The problem is that + copies of pointers do not imply copies of pointees. For example, as was discussed + in the motivation, pointers alone cannot be used to return optional objects + from a function because the object must move outside from the function and + into the caller's context. +

    +

    + A solution to the shallow-copy problem that is often used is to resort to + dynamic allocation and use a smart pointer to automatically handle the details + of this. For example, if a function is to optionally return an object X, it can use shared_ptr<X> + as the return value. However, this requires dynamic allocation of X. If X + is a built-in or small POD, this technique is very poor in terms of required + resources. Optional objects are essentially values so it is very convenient + to be able to use automatic storage and deep-copy semantics to manipulate + optional values just as we do with ordinary values. Pointers do not have + this semantics, so are inappropriate for the initialization and transport + of optional values, yet are quite convenient for handling the access to the + possible undefined value because of the idiomatic aid present in the OptionalPointee concept + incarnated by pointers. +

    +
    + + Optional<T> + as a model of OptionalPointee +
    +

    + For value access operations optional<> uses operators * + and -> to lexically warn + about the possibly uninitialized state appealing to the familiar pointer + semantics w.r.t. to null pointers. +

    +
    + + + + + +
    [Warning]Warning
    +

    +

    +

    + However, it is particularly important to note that optional<> objects are not pointers. optional<> is not, and does not model, a + pointer. +

    +

    +

    +
    +

    + For instance, optional<> + does not have shallow-copy so does not alias: two different optionals never + refer to the same value unless T + itself is a reference (but may have equivalent values). + The difference between an optional<T> + and a pointer must be kept in mind, particularly because the semantics of + relational operators are different: since optional<T> + is a value-wrapper, relational operators are deep: they compare optional + values; but relational operators for pointers are shallow: they do not compare + pointee values. As a result, you might be able to replace optional<T> + by T* + on some situations but not always. Specifically, on generic code written + for both, you cannot use relational operators directly, and must use the + template functions equal_pointees() + and less_pointees() + instead. +

    +
    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/examples.html b/doc/html/boost_optional/examples.html new file mode 100644 index 0000000..7fdb8c8 --- /dev/null +++ b/doc/html/boost_optional/examples.html @@ -0,0 +1,151 @@ + + + +Examples + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + + +
    + +
    +optional<char> get_async_input()
    +{
    +    if ( !queue.empty() )
    +        return optional<char>(queue.top());
    +    else return optional<char>(); // uninitialized
    +}
    +
    +void receive_async_message()
    +{
    +    optional<char> rcv ;
    +    // The safe boolean conversion from 'rcv' is used here.
    +    while ( (rcv = get_async_input()) && !timeout() )
    +        output(*rcv);
    +}
    +
    +
    +
    + +
    +optional<string> name ;
    +if ( database.open() )
    +{
    +    name.reset ( database.lookup(employer_name) ) ;
    +}
    +else
    +{
    +    if ( can_ask_user )
    +        name.reset ( user.ask(employer_name) ) ;
    +}
    +
    +if ( name )
    +    print(*name);
    +else print("employer's name not found!");
    +
    +
    +
    + +
    +class figure
    +{
    +    public:
    +
    +    figure()
    +    {
    +        // data member 'm_clipping_rect' is uninitialized at this point.
    +    }
    +
    +    void clip_in_rect ( rect const& rect )
    +    {
    +        ....
    +        m_clipping_rect.reset ( rect ) ; // initialized here.
    +    }
    +
    +    void draw ( canvas& cvs )
    +    {
    +        if ( m_clipping_rect )
    +            do_clipping(*m_clipping_rect);
    +
    +        cvs.drawXXX(..);
    +    }
    +
    +    // this can return NULL.
    +    rect const* get_clipping_rect() { return get_pointer(m_clipping_rect); }
    +
    +    private :
    +
    +    optional<rect> m_clipping_rect ;
    +
    +};
    +
    +
    +
    + +
    +class ExpensiveCtor { ... } ;
    +class Fred
    +{
    +    Fred() : mLargeVector(10000) {}
    +
    +    std::vector< optional<ExpensiveCtor> > mLargeVector ;
    +} ;
    +
    +
    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/exception_safety_guarantees.html b/doc/html/boost_optional/exception_safety_guarantees.html new file mode 100644 index 0000000..6b4ab64 --- /dev/null +++ b/doc/html/boost_optional/exception_safety_guarantees.html @@ -0,0 +1,140 @@ + + + +Exception Safety + Guarantees + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + Because of the current implementation (see Implementation + Notes), all of the assignment methods: +

    +
      +
    • optional<T>::operator= ( optional<T> + const& + )
    • +
    • optional<T>::operator= ( T const& )
    • +
    • template<class U> optional<T>::operator= ( optional<U> + const& + )
    • +
    • template<class InPlaceFactory> optional<T>::operator= ( InPlaceFactory + const& + )
    • +
    • template<class TypedInPlaceFactory> optional<T>::operator= ( TypedInPlaceFactory + const& + )
    • +
    • optional<T>:::reset ( T const&)
    • +
    +

    + Can only guarantee the basic + exception safety: The lvalue optional is left uninitialized + if an exception is thrown (any previous value is first + destroyed using T::~T()) +

    +

    + On the other hand, the uninitializing methods: +

    +
      +
    • optional<T>::operator= ( detail::none_t )
    • +
    • optional<T>::reset()
    • +
    +

    + Provide the no-throw guarantee (assuming a no-throw T::~T()) +

    +

    + However, since optional<> + itself doesn't throw any exceptions, the only source for exceptions here are + T's constructor, so if you + know the exception guarantees for T::T ( + T const& ), you + know that optional's assignment + and reset has the same guarantees. +

    +
    +//
    +// Case 1: Exception thrown during assignment.
    +//
    +T v0(123);
    +optional<T> opt0(v0);
    +try
    +{
    +    T v1(456);
    +    optional<T> opt1(v1);
    +    opt0 = opt1 ;
    +
    +    // If no exception was thrown, assignment succeeded.
    +    assert( *opt0 == v1 ) ;
    +}
    +catch(...)
    +{
    +    // If any exception was thrown, 'opt0' is reset to uninitialized.
    +    assert( !opt0 ) ;
    +}
    +
    +//
    +// Case 2: Exception thrown during reset(v)
    +//
    +T v0(123);
    +optional<T> opt(v0);
    +try
    +{
    +    T v1(456);
    +    opt.reset ( v1 ) ;
    +
    +    // If no exception was thrown, reset succeeded.
    +    assert( *opt == v1 ) ;
    +}
    +catch(...)
    +{
    +    // If any exception was thrown, 'opt' is reset to uninitialized.
    +    assert( !opt ) ;
    +}
    +
    +

    + + Swap +

    +

    + void swap( optional<T>&, + optional<T>& ) has the same exception guarantee as swap(T&,T&) + when both optionals are initialized. If only one of the optionals is initialized, + it gives the same basic exception guarantee as optional<T>::reset( T const& ) (since + optional<T>::reset() doesn't throw). If none of the optionals + is initialized, it has no-throw guarantee since it is a no-op. +

    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/implementation_notes.html b/doc/html/boost_optional/implementation_notes.html new file mode 100644 index 0000000..54af9ab --- /dev/null +++ b/doc/html/boost_optional/implementation_notes.html @@ -0,0 +1,52 @@ + + + +Implementation Notes + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + optional<T> is + currently implemented using a custom aligned storage facility built from alignment_of and type_with_alignment + (both from Type Traits). It uses a separate boolean flag to indicate the initialization + state. Placement new with T's + copy constructor and T's destructor + are explicitly used to initialize,copy and destroy optional values. As a result, + T's default constructor is + effectively by-passed, but the exception guarantees are basic. It is planned + to replace the current implementation with another with stronger exception + safety, such as a future boost::variant. +

    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/in_place_factories.html b/doc/html/boost_optional/in_place_factories.html new file mode 100644 index 0000000..be2ccbf --- /dev/null +++ b/doc/html/boost_optional/in_place_factories.html @@ -0,0 +1,200 @@ + + + +In-Place Factories + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + One of the typical problems with wrappers and containers is that their interfaces + usually provide an operation to initialize or assign the contained object as + a copy of some other object. This not only requires the underlying type to + be Copy Constructible, + but also requires the existence of a fully constructed object, often temporary, + just to follow the copy from: +

    +
    +struct X
    +{
    +    X ( int, std:::string ) ;
    +} ;
    +
    +class W
    +{
    +    X wrapped_ ;
    +
    +    public:
    +
    +    W ( X const& x ) : wrapped_(x) {}
    +} ;
    +
    +void foo()
    +{
    +    // Temporary object created.
    +    W ( X(123,"hello") ) ;
    +}
    +
    +

    + A solution to this problem is to support direct construction of the contained + object right in the container's storage. In this scheme, the user only needs + to supply the arguments to the constructor to use in the wrapped object construction. +

    +
    +class W
    +{
    +    X wrapped_ ;
    +
    +    public:
    +
    +    W ( X const& x ) : wrapped_(x) {}
    +    W ( int a0, std::string a1) : wrapped_(a0,a1) {}
    +} ;
    +
    +void foo()
    +{
    +    // Wrapped object constructed in-place
    +    // No temporary created.
    +    W (123,"hello") ;
    +}
    +
    +

    + A limitation of this method is that it doesn't scale well to wrapped objects + with multiple constructors nor to generic code were the constructor overloads + are unknown. +

    +

    + The solution presented in this library is the family of InPlaceFactories + and TypedInPlaceFactories. These factories + are a family of classes which encapsulate an increasing number of arbitrary + constructor parameters and supply a method to construct an object of a given + type using those parameters at an address specified by the user via placement + new. +

    +

    + For example, one member of this family looks like: +

    +
    +template<class T,class A0, class A1>
    +class TypedInPlaceFactory2
    +{
    +    A0 m_a0 ; A1 m_a1 ;
    +
    +    public:
    +
    +    TypedInPlaceFactory2( A0 const& a0, A1 const& a1 ) : m_a0(a0), m_a1(a1) {}
    +
    +    void construct ( void* p ) { new (p) T(m_a0,m_a1) ; }
    + } ;
    +
    +

    + A wrapper class aware of this can use it as: +

    +
    +class W
    +{
    +    X wrapped_ ;
    +
    +    public:
    +
    +    W ( X const& x ) : wrapped_(x) {}
    +    W ( TypedInPlaceFactory2 const& fac ) { fac.construct(&wrapped_) ; }
    +} ;
    +
    +void foo()
    +{
    +    // Wrapped object constructed in-place via a TypedInPlaceFactory.
    +    // No temporary created.
    +    W ( TypedInPlaceFactory2<X,int,std::string&rt(123,"hello")) ;
    +}
    +
    +

    + The factories are divided in two groups: +

    +
      +
    • +TypedInPlaceFactories: those which + take the target type as a primary template parameter. +
    • +
    • +InPlaceFactories: those with a template + construct(void*) member + function taking the target type. +
    • +
    +

    + Within each group, all the family members differ only in the number of parameters + allowed. +

    +

    + This library provides an overloaded set of helper template functions to construct + these factories without requiring unnecessary template parameters: +

    +
    +template<class A0,...,class AN>
    +InPlaceFactoryN <A0,...,AN> in_place ( A0 const& a0, ..., AN const& aN) ;
    +
    +template<class T,class A0,...,class AN>
    +TypedInPlaceFactoryN <T,A0,...,AN> in_place ( T const& a0, A0 const& a0, ..., AN const& aN) ;
    +
    +

    + In-place factories can be used generically by the wrapper and user as follows: +

    +
    +class W
    +{
    +    X wrapped_ ;
    +
    +    public:
    +
    +    W ( X const& x ) : wrapped_(x) {}
    +
    +    template< class InPlaceFactory >
    +    W ( InPlaceFactory const& fac ) { fac.template <X>construct(&wrapped_) ; }
    +
    +} ;
    +
    +void foo()
    +{
    +    // Wrapped object constructed in-place via a InPlaceFactory.
    +    // No temporary created.
    +    W ( in_place(123,"hello") ) ;
    +}
    +
    +

    + The factories are implemented in the headers: in_place_factory.hpp + and typed_in_place_factory.hpp +

    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/optional_references.html b/doc/html/boost_optional/optional_references.html new file mode 100644 index 0000000..396dff0 --- /dev/null +++ b/doc/html/boost_optional/optional_references.html @@ -0,0 +1,82 @@ + + + +Optional references + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + This library allows the template parameter T + to be of reference type: T&, and to some extent, T + const&. +

    +

    + However, since references are not real objects some restrictions apply and + some operations are not available in this case: +

    +
      +
    • + Converting constructors +
    • +
    • + Converting assignment +
    • +
    • + InPlace construction +
    • +
    • + InPlace assignment +
    • +
    • + Value-access via pointer +
    • +
    +

    + 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: +

    +
      +
    • + Copies of optional<T&> + will copy the references but all these references will nonetheless reefer + to the same object. +
    • +
    • + Value-access will actually provide access to the referenced object rather + than the reference itself. +
    • +
    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/rebinding_semantics_for_assignment_of_optional_references.html b/doc/html/boost_optional/rebinding_semantics_for_assignment_of_optional_references.html new file mode 100644 index 0000000..8906812 --- /dev/null +++ b/doc/html/boost_optional/rebinding_semantics_for_assignment_of_optional_references.html @@ -0,0 +1,151 @@ + + + +Rebinding + semantics for assignment of optional references + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + If you assign to an uninitialized optional<T&> + the effect is to bind (for the first time) to the object. Clearly, there is + no other choice. +

    +
    +int x = 1 ;
    +int& rx = x ;
    +optional<int&> ora ;
    +optional<int&> orb(x) ;
    +ora = orb ; // now 'ora' is bound to 'x' through 'rx'
    +*ora = 2 ; // Changes value of 'x' through 'ora'
    +assert(x==2); 
    +
    +

    + If you assign to a bare C++ reference, the assignment is forwarded to the referenced + object; it's value changes but the reference is never rebound. +

    +
    +int a = 1 ;
    +int& ra = a ;
    +int b = 2 ;
    +int& rb = b ;
    +ra = rb ; // Changes the value of 'a' to 'b'
    +assert(a==b);
    +b = 3 ;
    +assert(ra!=b); // 'ra' is not rebound to 'b'
    +
    +

    + Now, if you assign to an initialized optional<T&>, + the effect is to rebind to the new object + instead of assigning the referee. This is unlike bare C++ references. +

    +
    +int a = 1 ;
    +int b = 2 ;
    +int& ra = a ;
    +int& rb = b ;
    +optional<int&> ora(ra) ;
    +optional<int&> orb(rb) ;
    +ora = orb ; // 'ora' is rebound to 'b'
    +*ora = 3 ; // Changes value of 'b' (not 'a')
    +assert(a==1); 
    +assert(b==3); 
    +
    +

    + + Rationale +

    +

    + Rebinding semantics for the assignment of initialized + optional references has been + chosen to provide consistency among initialization states + even at the expense of lack of consistency with the semantics of bare 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 ;
    +
    +

    + 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;
    +
    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/synopsis.html b/doc/html/boost_optional/synopsis.html new file mode 100644 index 0000000..198750e --- /dev/null +++ b/doc/html/boost_optional/synopsis.html @@ -0,0 +1,147 @@ + + + +Synopsis + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +
    +namespace boost {
    +
    +template<class T>
    +class optional
    +{
    +    public :
    +
    +    // (If T is of reference type, the parameters and results by reference are by value)
    +
    +    optional () ; R
    +
    +    optional ( none_t ) ; R
    +
    +    optional ( T const& v ) ; R
    +
    +    // [new in 1.34]
    +    optional ( bool condition, T const& v ) ; R 
    +
    +    optional ( optional const& rhs ) ; R
    +
    +    template<class U> explicit optional ( optional<U> const& rhs ) ; R
    +
    +    template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ; R
    +
    +    template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ; R
    +
    +    optional& operator = ( none_t ) ; 
    +
    +    optional& operator = ( T const& v ) ; R
    +
    +    optional& operator = ( optional const& rhs ) ; R
    +
    +    template<class U> optional& operator = ( optional<U> const& rhs ) ; R
    +
    +    template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ; 
    +
    +    template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ; 
    +
    +    T const& get() const ; R
    +    T&       get() ; R
    +
    +    // [new in 1.34]
    +    T const& get_value_or( T const& default ) const ; R 
    +
    +    T const* operator ->() const ; R
    +    T*       operator ->() ; R
    +
    +    T const& operator *() const ; R
    +    T&       operator *() ; R
    +
    +    T const* get_ptr() const ; R
    +    T*       get_ptr() ; R
    +
    +    operator unspecified-bool-type() const ; R
    +
    +    bool operator!() const ; R
    +
    +    // deprecated methods
    +
    +    // (deprecated)
    +    void reset() ; R
    +
    +    // (deprecated)
    +    void reset ( T const& ) ; R
    +
    +    // (deprecated)
    +    bool is_initialized() const ; R
    +
    +};
    +
    +template<class T> inline bool operator == ( optional<T> const& x, optional<T> const& y ) ; R
    +
    +template<class T> inline bool operator != ( optional<T> const& x, optional<T> const& y ) ; R
    +
    +template<class T> inline bool operator <  ( optional<T> const& x, optional<T> const& y ) ; R
    +
    +template<class T> inline bool operator >  ( optional<T> const& x, optional<T> const& y ) ; R
    +
    +template<class T> inline bool operator <= ( optional<T> const& x, optional<T> const& y ) ; R
    +
    +template<class T> inline bool operator >= ( optional<T> const& x, optional<T> const& y ) ; R
    +
    +// [new in 1.34]
    +template<class T> inline optional<T> make_optional ( T const& v ) ; R
    +
    +// [new in 1.34]
    +template<class T> inline optional<T> make_optional ( bool condition, T const& v ) ; R
    +
    +// [new in 1.34]
    +template<class T> inline T const& get_optional_value_or ( optional<T> const& opt, T const& default ) ; R 
    +
    +template<class T> inline T const& get ( optional<T> const& opt ) ; R
    +
    +template<class T> inline T& get ( optional<T> & opt ) ; R
    +
    +template<class T> inline T const* get ( optional<T> const* opt ) ; R
    +
    +template<class T> inline T* get ( optional<T>* opt ) ; R
    +
    +template<class T> inline T const* get_pointer ( optional<T> const& opt ) ; R
    +
    +template<class T> inline T* get_pointer ( optional<T> & opt ) ; R
    +
    +template<class T> inline void swap( optional<T>& x, optional<T>& y ) ; R
    +
    +} // namespace boost
    +
    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boost_optional/type_requirements.html b/doc/html/boost_optional/type_requirements.html new file mode 100644 index 0000000..8da1a86 --- /dev/null +++ b/doc/html/boost_optional/type_requirements.html @@ -0,0 +1,50 @@ + + + +Type requirements + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + In general, T must be Copy Constructible and + have a no-throw destructor. The copy-constructible requirement is not needed + if InPlaceFactories are used. +

    +

    + T is + not required to be Default + Constructible. +

    +
    + + + +
    Copyright © 2003 -2007 Fernando Luis Cacciola Carballal
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css new file mode 100755 index 0000000..e5d7bb5 --- /dev/null +++ b/doc/html/boostbook.css @@ -0,0 +1,582 @@ +/*============================================================================= + Copyright (c) 2004 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to the Boost Software + License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ + +/*============================================================================= + Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= + Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= + Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 10pt; + } + + pre.synopsis + { + font-size: 10pt; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 10pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + /* Program listings in tables don't get borders */ + td .programlisting, + td .screen + { + margin: 0pc 0pc 0pc 0pc; + padding: 0pc 0pc 0pc 0pc; + } + +/*============================================================================= + Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font: 140% } + h2 { font: bold 140% } + h3 { font: bold 130% } + h4 { font: bold 120% } + h5 { font: italic 110% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 120% } + h5 tt.computeroutput { font-size: 110% } + h6 tt.computeroutput { font-size: 100% } + +/*============================================================================= + Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= + Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= + Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= + Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= + Table of contents +=============================================================================*/ + + .toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 10pt; + line-height: 1.15; + } + + .toc-main + { + text-align: center; + margin: 3pc 16% 3pc 16%; + padding: 3pc 1pc 3pc 1pc; + line-height: 0.1; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 120%; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + font-size: 10pt; + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + div.sidebar img + { + padding: 1pt; + } + + + +/*============================================================================= + Callouts +=============================================================================*/ + .line_callout_bug img + { + float: left; + position:relative; + left: 4px; + top: -12px; + clear: left; + margin-left:-22px; + } + + .callout_bug img + { + } + + + +/*============================================================================= + Variable Lists +=============================================================================*/ + + /* Make the terms in definition lists bold */ + div.variablelist dl dt, + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + + /* Make the terms in definition lists bold */ + div.variablelist dl dt + { + margin-bottom: 0.2em; + } + + div.variablelist dl dd + { + margin: 0em 0em 0.5em 2em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p + div.variablelist dl dd p + { + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + /* Links */ + a + { + color: #0C7445; + } + + a:visited + { + color: #663974; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, + h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited + { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #E8FBE9; } + .dk_grey_bkd { background-color: #A0DAAC; } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc-main + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #E3F9E4; + border: 1px solid #DCDCDC; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + background-color: #FAFFFB; + } + + .programlisting, + .screen + { + border: 1px solid gray; + background-color: #FAFFFB; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + /* Table of contents */ + .toc-main + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + background-color: #FAFFFB; + } + + .informaltable table, + .table table + { + border: 1px solid #DCDCDC; + border-bottom: 3px solid #9D9D9D; + border-right: 3px solid #9D9D9D; + border-collapse: collapse; + background-color: #FAFFFB; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid #DCDCDC; + background-color: #FAFFFB; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } diff --git a/doc/html/images/callouts/1.png b/doc/html/images/callouts/1.png new file mode 100644 index 0000000000000000000000000000000000000000..6003ad3af44ecde89a963d5af6a4180217319dfb GIT binary patch literal 391 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBqFpV_;w?d&FzWz`*F|>EaktF{gKeVcsDJ z0oVU;*6~a;Smx2ZrsEQ?ZxM&ygvBnFE?nmtg94rky>!~x8m)3j$<^(USQPg)>&zq; zMi;kRX=V2=&tIr>`d!)XyUpL@9=UmHetuZ+!_#HmOU>-J$pS3-bN!ardIyAF-G1#? z>&)f7E`k#|4sWoP;JM|(l6I_WZ`%~1y>agujE%b%?TB9+mb}(fsxyPFgQGMy*=%;A z(aZyu>`GQPiY$*T-1gu1pAwY3_N%b5cB#xoiRPn8jf*q{Trb|_a%sui&dtzin6_r? zu}%d~p(mAmOGTO#c2u;xJ(}Y^?ex>t7XL(?7U+1p1hOa|ab;w%c)sCoo@_(^WX<=s zr#89B91nl^w~jx#=XQ?S<*?OXYm`>JmO9g8;`^U+STt2<{M7jt yFTo&UT%Db3I{*CoWB+`guig6oxB?on>HF_suX>mE-_|+p)}_VbyG%XWRxDs!Bbdb`rSkCf z_opQpQ)e&z9?Q3;X^2drllMU70&71c8CwuJm{abIp zeHPuYNTZJ3@x#oHxOW1*hRe1@t$mhYkYRMp!NudU$f{L`HtEbcpPpkT-Q%WwW82?% zC04fVjt$l>J1E5m&cv;Mo-ym249h`b!OT;yI|^kU z7g#)~+Iz@=rzNo?Z+rL2lqSFB&0ni{FPmfwyfr;gD5K)Z38R1FYejhuGSfQP|hTIvQJ?m5M8zE|_KJ2Ny0Fm1o>%kU%6J0MhalaBNL z`|XP~Ht29?&a!*3EqAew_mM&!z3HdD7hn7l!t9~x=u!|XzH8m#&o*bC7c(?GuT1E< zIxY74U)KBI?en(Zj`8vg@_IC9@{~!dRw-$!in=2h%i uo%h^T#Pz@K#3`Fjeg5EaktF{gFX#;)5A z0&V{%irr-ME}D3(<3UjG?A^;f=DTxNc8JvRJ?~omN$9208L_ft0gE{24F|>2&Q_(X zyZRk}S@Y!IJLwtuX$cuSW9kad-E9>}+B4ar@B8JKU&IA}ZdvzvdHazWz|5Z1g ze)`Eh`){a=Ty&?>q6`CxFY1#$=XWS5S;+8pJeF8|am8VmFNNE0pWSjTLp3m4UCF?B z)v7}^cJ1H)wSBfZUSXp*CCGT~*L1 z!O^woK;8cKATG~IcM5iAPD}l8PyF`VZ_(}ou7b0cInG+vv8ev~-ZX{}_a4{SRWsNx zp57$DG;5jTyyy8w3^D7&C6fPqtf+bOwJP3cC`GVy&NA$7e!FZ3*ZX_(gMKMn{jgqg*t>n5-mVwdc+LxmI|e9UlrZu5 zQ({_ROHtjRNV$1z%lk=bT+YJ`-QVnLY|jT_oBf)`qRPnx(gN%Xx|4tEMdaVwoi3 z8lgAcLau*<4)^ratatOor+TqI{wNVS?clathJwW!uZ)j$%&5q+Ew{P&-MZ_q|3(_ifRH$!b{%@XfPPgvO) wR!x~yId8sr_tEzopr0G&e8k^lez literal 0 HcmV?d00001 diff --git a/doc/html/images/callouts/13.png b/doc/html/images/callouts/13.png new file mode 100644 index 0000000000000000000000000000000000000000..5b41e02a670f020ae62b7854482c4ba1980d73cf GIT binary patch literal 509 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBqFpV_;w?d&FzWz`%IK)5S5QVovKN`}4B` zMA$w&XL9s;aOlF(1%)YvneO4jm-o(&U;MKD#e?Mq8+>b)^R3G((>5$`ILflv=tsMT zqri^uWh?XJrteF)Ir(#L@uYSZ#}5m2PWL-;h`yh)YSr?%_21hCg6ylJ<~^TZ68k@M z*0PUs0U}2m4Zrz%{ru!$;?!{|$E-JRd$xd+!qOu@YuZ+=+K?-K{IOu7#Gy?(C029K zJuHwgKK8+3O1mEi<8zsP?~|?OE?SqZ;@R}Hh*OcJN#Q`=cIVYsi%fl`jgRf~&@_Gf zwzE(sdH3B%ReKL@(z)}#{LAm!8Ou74CNVNBn8MT`ef;AL!#4E;rLlAT)H7zW#a>U8 zU^AP|o3>d}=J>$`0|rHwDM43C-@g0)`~9hChd_}fnOvtgEzsbyc%HHSwnVR+$0Qaf z4hDzV>nAp?Vf*l#Q@}~VH~7Z3-c_p%=AWOKD!ECAd8tU(q6Mq8jughk>rJ2Tw)o@M zm#pV3mrVI!!@p|Pp+XrSHQ@j+Lm56tj!LO-Hu>!LzuT|B{(4Tap5^mRI^HKOr#o>( zhECmcH*b>$SLC#%J&RUEtqrq3WKa^{tg=+3a-Mjg$X|1pImHv7|6G6l?EhE#0)GDv Vq@B#jVqjok@O1TaS?83{1OO3{4iFg+V~@k_l_W_wBcH zWmp*BaqNHHW9Xsz@VDKv%bG0$2|bO5Z6>~kGkrGPetRKrdu;6W&)@+-S^-5e@qWpx=%~ppu-*HbtcU?B((KtQse2TO*ZEl8Jswt zRO&J4%x73CvPq};vBd=w-op^F6<=oH98=hD0fB5^~^0#Ht9-5wBo~e$L z1lS(@e{k6MP=#(Q)65P&Df1-{87Bltt+Mf&((ZAvc!Ef@>!Js&9H9b5iNOkrjBYL6 zJ*_!sB>iV?h@ACiit<@=<+J)R*K4P%cxw9w^X5-kmdSp5TRo@ZmA&eVHGWMv{dC`S zuce2g9b}I0mp%UT(3$h)E?kO6N0T-NtiR6f#9?6EcU;-Tw>eSb#{2IdZ1@=hR$sjr zzyA8Z#}+%3XYST(VGvBTnww-G;h@R7RHW^&qTY1wDM1E2%vZCnP73-ad;I5-GeP_8 zE`G0F6Q(`qeEN%Bd`m@QuDc4b82Acr%ROx3%dny5{(I}bX7&S{bY%G0Jv1kte!3xU z{l(W`FJx^snCW9M|9s%ekN~~u3#V){n|<~=yTas?3Ovp)cJVPNC~di&>!GEaktF{gFH!7eFB zfwuoy?SYP89?67Uc^u>7$ueKD;_TuU8yCKP?%y^nk6}6Q`Xb ztf|`>GH3mp6jYb?>^RdSfr%@^R!^go|6uIuQi$NDW>upBo%&=x}fma9VINW5Ly|Qkmm3JvHr(Hb1rr&)I%k zqW}1XsO0Up4@Uid#O=~jwU>`!u0>yZkk=jF7J(OKyBQi3I1HqEAMAR!+FC^5{Aa5( zf1b8B8nUgv%H`5>GKER;h_=JWcU60(815ha{H$oF%dBM*eC_{b&TZl;l$m|{>8A+2 z>GpSd7ik$I?GB%onzMHA^lP*F zk0)=tnX|7g@rLFCKI7=6AyTdvVl+z`(%Z>FVdQ I&MBb@0M`i8D*ylh literal 0 HcmV?d00001 diff --git a/doc/html/images/callouts/3.png b/doc/html/images/callouts/3.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff0a93931515bb97a045dfa61a8530d87e458fd GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBqFpV_;w?d&FzWz`$7M>EaktF{gFH*{(+p zB5wOOu6l7m)8 z=-oKUH}V^&iJyB|uo8LF()AHB5)-MfO`N3nt zvX}OXM~sd8*9*0GtV!A!kzpdmy4F;zn{|?kqeR<^5G@5I1_ong&q>Sg=9!B)JHv7pU)=hauMINB3;oaL&ye>}mU!H{id4Bxig=9%^>^=*s?64R8I`k2o? pd-p8Ef~{sjr?y8+Fx+F*x_2OD_kw447#J8BJYD@<);T3K0RY@Tw*mkF literal 0 HcmV?d00001 diff --git a/doc/html/images/callouts/4.png b/doc/html/images/callouts/4.png new file mode 100644 index 0000000000000000000000000000000000000000..6aa29fc0b48c17aa6ce5540e1af5c00510c33ff7 GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBqFpV_;w?d&FzWz`)qx>EaktF{gFH#x5mC zfwup%GG$o)=ergqP)_hu?Cbmc-FuV6=PTSkE z?z;W`K`XyJWKnY38^_LI-}iXo6rn{K^Ugm{NGsVLTQQIQc;ScrMIF~}*~{?xZ|}UC z)%voeOU2Vbu7Bb(%{5!g=daxAHc3V5z+>?E76HlSc>&q{{ zJgU5>EY^K=``x_dYqp*_vnNK+lE-=9auZ+6u0=XLho7HKd(8afJ98Qv1B>H_g?h*I z^7xt(_!*jJt_^x6<$Ce%iJd)$VVYl~OqdVEFZF#=7-s1t%fP_E;OXk;vd$@?2>|9n B#bp2h literal 0 HcmV?d00001 diff --git a/doc/html/images/callouts/5.png b/doc/html/images/callouts/5.png new file mode 100644 index 0000000000000000000000000000000000000000..36e785867ad9b06bb5da296fee61b67cd8159ded GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBqFpV_;w?d&FzWz`&U2>EaktF{gFn*{nkj zBCY4o9LZ47@QCRUnZAf+N!}-g*k62kUh<2$=N}3cU-wJsu7~Tf`D?j51GwEfg_G2_ zuV#t97&qf=>*tSit#h_USr*FJFU!>WaGpbPU+ne2DLtw;&jomW^|@TLId}ILd4;Y; z`kGI<1$&J<4oW?f4p9*ch$x|rP+;KqSwET0Ksa~vKtM(>J91HOJ>EhB>xN^tsw+8di7uv`rMqUeL zJtlGLsS$%o&3$<<&56<(YY$o;PcU%UfB(F1o@3V5sOFBi;${Vo2fOrSjvstkva9-x zil;zZBGUt9^BXy4GknxI4hvj-p!#HTV6S6ePsEk3N^VkheYYwwc>v z!48gj&!5^CXy3`&YF5dr$YOKedHr?gg#ir$OfFx%f9Fdu@F;mr4Z2vhci-*k?73P? f@97_A_`n?SY~RWh)zCHu1_lOCS3j3^P6EaktF{gFH{#8D;%7vjax1W#KXIAnv(J`n z&5VyM+63~m6_r{NIT!+`rAn_gmE-I&+!3QUA?T1q^ClfZ7RG!2%96cqg2wgyaq?lS zMX$X!U8LbO@45W6mvfv$L-`J@Z+FmS&DLGD$|-VMfY)E~efQs=*mUM;<-bcWOZM5Z zTz)B%D3P@Lt`d*4kJ{wr1(Q_jEaktF{gLJ{wyX( zf%f{%yMM5|1Qs>DxO#n#YtRpleGYL4%{eMNMC?4cR!{jhN$+gat*(bhBwQW8eR)?F zba$a+^0L_vzt^7O@l~6=`|-z${Iyee1O}bTzyIC7L&Goql*H!=r=P}oFAaJ)O@ZgI z{@Sm`#{5B@N=kt`V%+OqiyeDxcc)!#?*L7k5+eADVIg?*L>hpfK3x*)1hCVBt; z;|%wV8@Gym{wcFIjN7SWb%BU0N0Y+6yzR|3cK@fSPF7(wKKyx4{o#4fYt#Iv1TDJ# z*2#-AZQqV>`4S8w#?i?>7PHU(+hgr1l-*Nl-OBiY{af+c^=0Sh`7EaktF{kyy#=ct) z0&EZJryZ5xyvdOv(510`p{HDvlxC~E$|>iVgULHQ3PYvrom?h2P4(>+k=FEToVfLb z-1}ul4-dV}J2m&O{aGGazV^u2>+);2+U^P78~6Tv*4AI1E_e2NCZAD1|9M}poAQ6# z2UUCjU5lzOJ!f0qp`v6c!}s@T(aY_*-6p<)(^RJf%{ZH;pv2Hn%$FKjXEE0=dabFI zOUbTczTJ2ED(5xNoT$P%L(+vssY!q-Q6kB1zW$Oa(QCh^Kc6#2_JRrTx8JslG@1mM zBBvdU`kln8=_3m^%&og1Cq^RrH#tzmz{IfafeFfcH9y85}Sb4q9e0BP^KrT_o{ literal 0 HcmV?d00001 diff --git a/doc/html/images/callouts/9.png b/doc/html/images/callouts/9.png new file mode 100644 index 0000000000000000000000000000000000000000..abe636072b61306fbcd6157b95dfdf7e86a77e5d GIT binary patch literal 420 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBqFpV_;w?d&FzWz`&U8>EaktF{gEcf7T%f znb!OIl8YM`EC?0g)MK6LySsR*bBW@-#a{$sD|jaA?Rq5|BVw*<(2>_Fw2;L_Ls+eT z*=m-pP5G8*zMrjje*N{AqvqEc&v$lO8~PeQnNu$u7&XUG^XcT&$oGAZue{@YWbseb zX;0Q#doE68rNi6aM(w}9J~guKY8ESl1YdhX&(saqqyj~D?!KF+)#9L-_*{J2Y1Ks< zObjyp?mceG5^anO3Q8tYyaIvx98EzeZXaKe_`Z|7b6wRX+{3FhZAn{V<2dEM9+du_kptYsE+ z{WKfa2W_~S^T2{nZ8E1=H*3uG*3`)V4^%t_SRAV?Wb9U5edYbrW%=bs0jAGCWzMDv z&-uLjLxRB%P3bLBx;@8}pH%jFEoHiFvT*CZ6}7y~440#x2c4?eefQp-XqD5OV!VD< d@-ZKf|NC_Jf+y*vd<+Z>44$rjF6*2UngH>Mv>N~b literal 0 HcmV?d00001 diff --git a/doc/html/images/callouts/R.png b/doc/html/images/callouts/R.png new file mode 100644 index 0000000000000000000000000000000000000000..bee36a1ddd846ec8b96557a7887a831291a80ee6 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznVBqFpV_;w?d&FzWz`*dv)5S4FW8%_4>%L|O zkFNHQ&Hj`1Uqc&pGeQxH@fGHtQJsOj2QFu;^nJbi8cx z#m2vf<#^$pxtB~-J>`xcER=cwfAZ|-GfQJHdwk$hYFebBHz)V@jqkFlkwG4dUR&*2 z$1UhMEw$sZMCCl`kMlR?O1C8**rfC0*I8Rnp(BMgFCSN0axhhD3b+a~DDWKKe%h_G z-ZJ_Acb%?BRc=c~e(kHjuD<13fS2u@`VYLRKN(N_m{=ypz`(%Z>FVdQ&MBb@0QszW Aq5uE@ literal 0 HcmV?d00001 diff --git a/doc/html/images/caution.png b/doc/html/images/caution.png new file mode 100755 index 0000000000000000000000000000000000000000..3c3b859c2276a628a5b5c7dc50ac720abec0b612 GIT binary patch literal 4286 zcmeAS@N?(olHy`uVBq!ia0y~yV31>AV36WqV_;xdu<*?m1_lPk;vjb?X7l5|!3+$X z#hK2|0h!6k3=9>w-p))95XqD}e*fJ(8HpK^Z9L9?LaICpmg*B_Tv*di7#x})VxZWq zy`ibYBZx(iHKw4Hb5mEB2Ahi`BlE6i9i~&ec66;+ai^#5!>V_$?CwrqJ^O$A_WG}1 zg1?qjto{{#mEnY+%Erl;6Py_)?R;rtAI_fUks%>$&9;GobwvZ?6Xlzkn)m+cF**n& z>i?L&N1A!UhYJ7q_viobS1g*eQ-(odPJ^(;#mpSW<=hs1lg|iVQ*W6wb)M3SgMLiQ zKC_5xJP=THuYIhdc)afM-1usyKQgQ_d<=aezo&A#x5|8-x^j8TnZC!W%nG-4UxfcQ z`<{JdYm528p6AQlKku06dF#Rcx%IPDr>WIE2$cNj`LgQco&Ogt5B>erdoQB?F1x_u zPu01bAINTqV{DjGw|=E8Tf-*lhI9AcZ(Z@2p=2tP!rv)#51#%L=FBN>qQJnlfLU?@ zM@XaC1?FQ1WFi=?AMn^T@N+OMOi)f}wwSI3zb&ztZI9;Fzto-3z-thU5vcW{0luZ_^9gKFY<%gy}jQ*f;rak^pH-|$92Xmm?7Xh(H9X}KjJ$Mc| zZ&PmdV7=6^MbY*ILlOT&<x@g@dv416( zCA78SSCiV}rx$l+cyF<`Vv+4W=On&B`-1NazAvF)G^(Wj@--hcFqkD#+#{_fGP&X8 zL6Ky>=UBzt z9zXh2Ai6^=Mn8|mygB+<_v5P{r&Y+?ug)Og|s`DcV6$De1u;`%d`E72bX&4gl`l5Cg@F+n{;o& z$rRpAvX(t_{O-Busl_YWtL_(H-1)M5XLsR|vW}}ArCq%pdlx;>d?iwS%FWAcX;aa( zqIM(wKJn`U-=hBY66?o5>*~5Pt*z2xu{g=oHVU#X;#48l`>g&UnRbB zm3FmV2+8a-G0QbyJF#r4neXunrZ3-pVW|@QoBm6n)^U*DNs+O@Z<*vmv!dTGVdqNUwl`ZFf^RHq4To^%!%N z;=(S5aE6==&J3?yYNKo**CM6W|?N(y?!iX^A_Q){Mq-fHkSI7J}Sv7dH3Sb zuC!erceR(chc66|T=QsMR)py~_e-0vpT3fPb@r9?7u7GHzbt>b-zdPC!}vzNLBfZl z7p@qb+;H*3M!~Bm4r`oWar{MovTX9U!rqU6uRgh|x4L}IySTr%T&}C!deU){Ie6B} z?Jwmn+g(1N_AJe2v)N|LV$;tYpQAn(ip|~H7kXw_UgNfc4L1@C?>%Z>Ix}_GQ_0i& z*L+zcv^Hu@+VzZeopG0Uq@9X7YISMXy;=E(w{&i>%sRY1bX)J1+zqv9%d?Je%-%G6 z^8=hpm+;R5fB;iL-UWL3cdE!&bSF*0G?$x44La#5q+Vmjn z)vU)=CwbpKd%5j??w#0!bKl;3v+qITyNzcT-=F;C<@?CDKhJm{?|y#uF>iHsh5Uzk z5v%u2+r8~H`;Q&JWj<7H@+*#gwd;P3;l9^3*){WjOa6TNi}%OnKjuHT|Jcu6z@foe zA+thshTsix7fvqzEWRkNGA=#tXYCR#Iovx%wWOuwZ^^dta&u*KMaR6~^Y6j0mj#zU zG=12}J4hST~q|ncfGRO5er7ZJJ^L_Sv&4M+XqgA#QZ0E_ldUIF#YoBf2-#*HO@L4a{54S82fA_@fckb8Q z3*QFb{#~}>-HH2#doPzhKN;H++qpaMx#Y8{Pxs!H-LqRgUa>y?-xdCK_FKd{L_csH z`yTOja`y_p)!zK6eLn(=Aw)A!}>lzeb&^>n?fcxYjd^B=GEr`~C8U3F=d z|JA~)i%t1V-){Z1wK{t`Uol_5%tq@=Vao%;L%x5^_;Zo{>$bK43 z$&#@+XLaw6%I%OVUw*QDXZgS6{>gu7pPxMw`#Eh=*bdXhrSC$1tlVvH{rAq@W!J;* zpUcp<;`K|PQ}@yPh<thwOC)X?^)B6)=6x{;a{0*vFZ?{n84g{J(pqCD#i;Pj15Bn`2V^xTe|DM zEn{F{P^b!tC`l|W$;dAPwZK06>YVh^2`li^@i^0!AO@)k!$L4eg+1%vz{)F zAs)x4hDGPcx{JnTpWRnE|M%Z_kG*SsAH^7K6JDNo$to!Oa@#RI#a#IbKNuf|e`xr{ ztsttP!@6_5%}17|?Hc-;9SvGrm9}{&ZD05H#`8I~GhfcCy%gj$XI@@rX4CA>R^3UDk ze?(@c?fUWI@P65?@BZ4pF5fd>d`i^;tySUGS5_;vYk6E)GW+~GzS!Nf3BVf;bqnK-~F{Rmn-ZH z>U}jbPI#&1T@inFy0g)d;eL3X*3u|p;Zv)xPT^t_ElRi|&n+2n@RkC)HmJ+t7%B&Ewc;^tWy#?7(ncGBcrr_Fyk^XKfX zra#Z^et#-{&-ZzE&Zekb$qK62w`K>YY1CSg;%OhZHCtE|`|wBlz4>omcbnC0$HKHn zOAiGV*WD{i@@#16?}*}cI^KA8?b;VNew%wI+-6AMv1lE4-}A#BYT4Ie7Gg?z}{JGI@1p(Jc!X_Z%cGpe6+#BgvG*)?MdZ? zbg7;+^8~=A1iwYuSb!RZIy93<`4W-LqGp zIxG6Ta%m9bY}t$NuO9982`F1~w@vV{2=mD!ogxpjxD<^4mMpgAT~pcX(%g5ue6LlE z{;mGNsHudwD9|)1V8r<2a^3e30XW@(4f#p`Q55DjAUZ&amUG?$mssEf#{mEfw z_KP;CV^S#&Gg`rR&41SGwT|3>;;a|V&)9$Mfpmi89v3bv_IQW0Ti@(?yyr|{e46g+ zZ=wd~Dz(jalKVLFM1HSUH@ac=^znJmUO&N@UyQBGoD(I4$hDCzDoT4X#8TXW&ggQ6AkgF z|NXODw|@QOv$M@VURxWzWAo-_xp=XOER3(2yG~BdIKQ{!j+2C(Y|!P>pqF`T)puOj zW!-2}`{RC+Vd$BCG3UNUW>q`0<^{=~jSZYz;ZhQO3-+okmTH5-3D@)tTH{RV`-l10?l}34HS$sRGa)|4GoFv~Ae~m?Im(#ai(hz_1 z*Ii;;-;WY6hZA?Eva>Jv!4z=k;-sI_1?->MKYZJ2o|yJZlM=jS!txY4mpriZ8UiNco? z$9}|b+kH)$xtT5X;<=LRJ?Hse`6(rozGIZInc%G)BasurH;!Nbe}t`JpYXIf)mqP+8gEHX>XNhwExol zb+5nK@Avt3v!0q*t*VaGu2nF|IZ}A+n)kx9uWREr_Z{*GPu@K3&AC8%W20O3MJqCP my?XOulB2mf<2BO{(rMq>1 z7#LWXJzX3_D&~Ybz{S|QJTtnsltMyEt#Tl;v|NO;v9`l_))3dflS?I6H zS$jb(b8Yh49f>lyi&H+{FUwhqPozXyMAgO$PLw+`X@4OhhomGBmA=~_D1Q| z?(N^;kt-&UeO&ro!23z_CpvBXaP{id|0zp@PKp*eZJl6q)iCX`F;BBgsd=1hc4&a) zEyh_>uAVrSc;ahrP7&MLKNGHInTDUx&k)}w9vO34`!qEvb~Xy+uOKSNk6( zv>&s)yq>k+I;w5?&Zpg<%4gdDwqZYaQLJjmv+%jmwG|syM_%oVReo^o_PjjaM7Ish z%6k_b6+O8rr!cN%apG0A(wB=$YHNA-OxUBqxl-n{cURlZO&2dNS(0$Q<181K_wme! z!n{)kHWuM&S&UCb0aq0ZIGZW?u^!O<=L>-K(iWQ#!f&awIi~NtKn%sIO zysE`fPPtq4blT$3bj|?BBjQ%~?%&@&tBlv`vO)QZg=^(J6gAz#^&9)vzubFYGj(I{ z;}Tc-#3qy78U}A?EOcP#Q?apAnRvqG0f$UuEMI?tTUTx!%L4g}&z+lIz6|B7-m>kl z{@$C2P*-MY*kqgm~B%yI-s@dRDYk{?7W}Z?E5f|EK8s&W{ye*gx9diU zmOq8Ze{aYYzx3*^*y;8PBROw5)u6)m!yljToz+(LCcgfPjEu~jdGi)&tO}DlG?61f zZ+dF}*L%$?Zu8zQQ(T-`e_qx@ab<+kG!NC7_pvkDdvlNQojL3_|N8W^X@MeFn~tSu zvBuQxHhFhLMQQ74&b`&*29bNJ^)%*s9-q81#p>n93c2kQB5Z4agc-50<}GzhKbyAM zVQbXc`g6_Fw<;Ij$@`nI{ijW}qe`<%(8my~r=Ndorri2`P*7^B91lyN$XSIB$Mn-r zi|%i4dS;i`H0!41%9~HV{eEz!P;I84k|ayhf^~e)44$hl-W|W#tU>y=*Uqq|H?%~! z?7#ig{GS=TcFIjTcIC6 zg}t5zefbcecUez&&H3|QF5Z`Pn-4xMYkgo))FX0^>uAu&N1ql&t-W{W&L8ec{U2rK Uy!q45z`(%Z>FVdQ&MBb@04`<@YXATM literal 0 HcmV?d00001 diff --git a/doc/html/images/important.png b/doc/html/images/important.png new file mode 100755 index 0000000000000000000000000000000000000000..54b4846b49cb77d09578e03fddef8173e5b2cde6 GIT binary patch literal 4666 zcmeAS@N?(olHy`uVBq!ia0y~yV2}f04mJh`25Wk44otVv!`vx;GaF%2` zI|pPYCo?cq+iGS4^JFAuNVf4f%QU%gGJBl!RACQnlr-uwP+|2s@rY}U zg3=@rM;Au%nAoN@i)u_i-MQ;$eZ}u^fBR7X z_U)_cLwOtCR4A!yikdMfbWT6^y>w$bTYHPq#>EWW0S#PB8oXH4O>dq)e^Z`g^Cj+o zs_)$xw-oJJ{`>v;|HlP(dfMnQ2>6}&cxOdO--OF8GN*kXt-EqO+`?ElGNM_w)#o|4 ze!z)?+A=?Tg~KhLNx%Pd>+$>73Qvp}3YN@R?_;s+(8TzeRavc;8~>;RLJ@J^KWEz9Q-zk&No&OQ$yjCZ}fkDK9-N-?3 z1(WXr?w$t84J_LZaPDBvf57i_!0iCzMg`6fj%p_ucRSc=u&6#zSi!V)0i#J{SOHr} z)8_|9JJ|9XcPFseurV31#x+%b;L~vwXlXqmz&ojNibAOeyHV4P38qh2DxLNPaES07 zb+FNpJ=Iv|+!~-6!g|%w_k#Wf%NIr^%u-EqPQn*-zL1s<_R1!E%BRqtmtJ%vj*IjhsssQys*%fwIY_G6n z$$e$@bvwPd^nzH1d5M7)+uY7`?$Z}bUwr#w^$Wo-BEMwWniCTuB#e8s)mVi4PaYFV z6eM50-!MX5nP&PH_F8enhxTP>W-2 z%j%ZGL()nUS2&rd{}OoIVcjWurp`3r$_(TcprB@sj6n4|R{}9{is9CsH=C z-JB-l<){2!*?i*q3G*l2@4k5C%aJ=rb|hIJS#{LvNZZl4zz-s&U9zdls@*|;mfky^ zX9^$h&hD`8aPP<$UoU2_Zl|_S!Ev&|ln>K9CTUE{n6^XF(D`VP=?cFPJ=6ZGo~l+W zPv?wPChSt}+h$*L*zGlYQSu9&UDCGm;ynJ(wDXuheTkQpH=9@9#5L3QC}<`q@bI=t zD^CnOV{up_wPs4tgiVvXCf(A$s%5IPRYO-jS6fy!R^hIitlNC0{FAILw zspAzEea+o0_*=)D(3_T)yXGvFabM@~uIG+&Wkg)`y>Pqee>46x{Ap@h)YR>?$!X~! z(N;^>wnb}`_9V?r>VLFG$oFKFrr%1Rmy0fOFH^bPH}k}rgl~q=r#_t;JN5F^*HhT1 zP7jIDV$|BHm8<0+!nrEvYQ|Ngt8rH=O;t_xx5{i4+v@(RqI6r;nqP`v>%O}3PIH@Z zOs?0jS8|%k>E5YFvl4r=CzaFsU1li!Z z7IP0k_om$~}onwhgAcSQEyl$d=k?zmo3yt(`A+q2&r*ysN{c<74K*+)G`_yj1*38@zw6SZ$s?9TmT)%vGv z-+p1cmv@hS&-^vXYrP}C&*ndtKG%Qi`Qmuz`!e_I>}TCq+n=_-{NJ~KNB{LRn=oHu zu42|~Ol~`#PTcBwRlr?@s#4Sr#?BGZ-;G{y(PDEZ+ZKx zzCE(R*0E*t?zrBVy5V)%I>)@scen34?%w@b3=%!mVBW7 zvA-5O%D>(_wKtw?2dgDT3yWW4NER(x3VVpYg$ot1w=M59fEa^vrY zDaUW#p7zn;`-cyLx0Tm!<=Wc1Rlfh2Y;C~vpzDF_1LNy>igg~}_}q4&?cd`!k9~VL z^|toT_y6F>;rDCan{1=(tgLDIdU=h}m!i}BTj%cjz4`I^*tNUXmge?sJ9PO$$*-5< z`&<4SRULcm^FH$1&1>;j>(^#3-zr|>ARBG{%sSbcHC8d!`T3pmU(2G)w*O!D{dVW) zQ_olHd&FtHQ~dJet4{oxT{{Xie_p!tbjIn)duLb4$8+v0+JAm|{)bh^ufD!MXMOC; z?XUM&+Hh9}C-zu=y!Ipa{h?j0%imABr>iTr zXL@D*C+6SI|Bo-|zwAA8{)YKlcG

    {yqAbT4R}68To`sNnBuO!wFUwJ%u91iQFAA z4(LLEUpNJL3u zX-P(Y5vU3F*;nVJk4{*DpN_{_PhHKE>He{kMlDyaCmsSIEHu}FAdKwmT?!g zEtmT}E$sc(!yD&F=&(m`6P9LT)S4<1T63EHAEW%w=$hp#9w}=s4^k0$qx9g$!D+(# zA4T|QFP-|$(%QJz@~*M=T4tZn_ut<6eBb;1PVxD-f}wwH8_X?hQl=Mm%-(UjW0s=N zrO?SHtS9wUEW`ZSl%y2>dR9$gd1&py4$MMs|kK4HvId)u+3dzd06JY z`5nGb_9<`L_O=KXy^pP^IK z$G5qfAz}|I8Qm84f8#HZT2|cl?s5XRM;Qm>;?G?%Pg3hX%1O*L=FM`u z?LT)4Ui~X!dnsbb@pFgl#;P>-j~C}(@MMdcyR*+gXIHJxm-P;7Go{b1nEoN|rYpB5 z$ES{+t0jaN-|sFgxifvm?UD`Re?p$Ub~yMs(?CGFzrgSKl2^HpfBaCEnYqg6?CleW zgIDODQF~e3|6U@KB|U^|PwbM7O3j}x=Eyxbc{%;Zr+2nBpMO}g1@b)SJ8L4Q_Tl#Z zJ&i{rXM5W_HzUA;W`3rhJ3+#&f-h2?;(PY>;tHR&*?WKZ1u zWgHXz)YV^S@lHM{8+Jm^a>|EFZzla_b7>*58XevB503Rp7rp$X>T@mqp{Vv9KLNw7 zaa9^mKiNvXeze6(sJNoDC zZ@Fc!O?jqESyY#aCT{HMu;XiE<5bl5;<;}Wb)5TI%jR>e-2ZZ(vXi=|yzjBKFK-m=k9EyZ zu=TC(|FU7{@I;VeDXLCP`@nzMVw<0M5t{h!#nx?H;C;#vU z@ZNspJ?E;is@RDMk0z{PiLIT?%X#SqYu{{rm5z3mkQyJon}32PmK-@H7}ObjIY?3Q zN!Q^r`9w?A%bkLaoEozi-fy2A^t@z_^?d&D`{xwjITc>C&DpxmBlgus{l7e7!jX0_ zBKnNlCZ{Z1Z)N{FdGk%T?RM+8`At@FJer>^SaK(#*@t)1M8&gH&Pi^|i|SQ(itXLi za_f+mM2b?r*JpEGPj6K_OFT7r-up};9>M)C~-pj+K zTH8)uE_~!+=JO~(l8?znFnEfTfAXu`i}EW@uiW@y)}7N1bIrHOoP3gX@YGWV_O~9d zzloWD_L5z<`B-lElfJYW(z4Hr(<5SUr|4U}`;_^~@&gkWqf?mIlU>p||IJpW+*L1N zGMZF8t%qar>+jVwX2_iI+0h#HV-iQvThA$LIArVc=PgxOsO=J}MW~NwwW-wP1^n~NzFeEDHtYDByN`O>o=W|-KIHQ= z;=2Bi9Tj0W+m+Q+%uV=q+n)UJdq$+Cl+KHtpS`7i)OiNI@7ZECIcP@3$u(-*rl$qm zzIH5rtzVb@ze?fxf3h{YKXb1z6?+*yHPyP+ae3$Z?cbi3%a>hP!GEIFWWB7g?X4nv?^4Sc-f+YJw^Bt`U4EyM zc;c1Ht3`r!t}pT({chMw`7rPAeVJG+zvJ^8n``%~gnM0`a`{cRX1Qul7B8uOu6O9A zdz4mosx7+i7b=%#$&*t!fH&zoht7We=<;H5(cdtx3Ep^)E#M3M1e&^lG zSzT9EE;x1O>Kz4%y}RO-SKIcVYd5mqts{LqeB;%c#;dK&oNqD@%~SEve0}#4%La?W z6PKU-UGvC9bhV3|OyP-dD(9bfJQQ3k>!t5k@cW<0yL~%U^OA!aNN$A zV>65MA6{&BE}4Jt2!D9r%JY%dqElmBW%oxG?i5jyz5MiHXGVmQrt*8fYmIh^IP!zw=8 z{`}M}qA&l4Reaj~)32QPS*2_1E|fRxlnPq6ZeBYfaMSLuzdLhm_zORGyVl%}nlAtU z$@GfvcgsKAnrWQ(|4)bZH{VC=7n^tPDc4@=`|bPpj~^cH|N8Oze~~ZmA3nNNYzC)wmA!f6#(`(${H8DMr%&2{`r5^9%Y`>S|B&eP&u!kDt;;1p zZ#t*H=G3iQ`~`)%zMd*pQL+cE|H)mgQ+@RR>!oSSR+j9Jee>SDwEFwfoZOFdYOY+0 zTd%FQHR*BY%8*GfZ(8c;o0e?cs8Ia*^NKJnuihW~-~0V%wBwUGdMNm~9|HpegQu&X J%Q~loCIHo{?ri`7 literal 0 HcmV?d00001 diff --git a/doc/html/images/next.png b/doc/html/images/next.png new file mode 100755 index 0000000000000000000000000000000000000000..f3a1221df31c3c2ba4e3a72edad38c13703767b9 GIT binary patch literal 768 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj4kiW$hQCG&XEQJ`a29w(7Bet#3xP1>rMq>1 z7#Nr~dAc};RLp6eeB1w40K>80^1pI=K031Q+}6PA-o zut+zF-j;Gw?uf*D*{((14$Hcux3in6E_!$R{mVIjisa6HXWSoM6uZ0c{E^r9Ur$om zdhZ^4hON-~BYZ2GeK$N>`J?GiOJzY(!s6V|uRrr03%sLkr*1#v(teTeT^zk4U9DU7 zv%f8b6P+XKjO)LDUiZ<0p*o>#X6mOi#R1wP z8(l6)T21PWa1OIO8vZ)ea}qY-^=ZrWvbZQ6m)_kQvcrVw=bvte)59DYyUFcC9E$Tt4>&6 z+W%-jd;GDDoIH;dN(0uWOyTmnDE=b*gwcE+xwelYeE}Q`Hm&Y3XPNlB+x+oXzleq5 z0w#UgMVr)jUI2-(`lA6OUY& zu=Q|M1xs0v^{>u8Av+EoyuB{di7k}!tvm{Q)|ESyVT{*EHLXF20N@PNRO*vTc;nVG>kH2j-tEeVx#8P4@BjRN>Ropm;oHA%y^x5t(%-w` ajXhtHa_t{xfsG6d3=E#GelF{r5}E)mona0D literal 0 HcmV?d00001 diff --git a/doc/html/images/note.png b/doc/html/images/note.png new file mode 100755 index 0000000000000000000000000000000000000000..c3bebc7ea6aae0fd9b713ef8ab3cefc31751a03a GIT binary patch literal 4648 zcmeAS@N?(olHy`uVBq!ia0y~yV2}f04mJh`25Wk44otVv!`vx;GaF%2` zI|pPYCo?cq+iGS4^JFAuNVf4f%QU%gGJBl!RACQnlr-uwP+|2s@rY}U zg3=@rM;Au%nAoN@i)u_i-MQ;$eZ}u^fBR7X z_U)_cLwOtCR4A!yikdMfbWT6^y>w$bTYHPq#>EWW0S#PB8oXH4O>dq)e^Z`g^Cj+o zs_)$xw-oJJ{`>v;|HlP(dfMnQ2>6}&cxOdO--OF8GN*kXt-EqO+`?ElGNM_w)#o|4 ze!z)?+A=?Tg~KhLNx%Pd>+$>73Qvp}3YN@R?_;s+(8TzeRavc;8~>;RLJ@J^KWEz9Q-zk&No&OQ$yjCZ}fkDK9-N-?3 z1(WXr?w$t84J_LZaPDBvf57i_!0iCzMg`6fj%p_ucRSc=u&6#zSi!V)0i#J{SOHr} z)8_|9JJ|9XcPFseurV31#x+%b;L~vwXlXqmz&ojNibAOeyHV4P38qh2DxLNPaES07 zb+FNpJ=Iv|+!~-6!g|%w_k#Wf%NIr^%u-EqPQn*-zL1s<_R1!E%BRqtmtJ%vj*IjhsssQys*%fwIY_G6n z$$e$@bvwPd^nzH1d5M7)+uY7`?$Z}bUwr#w^$Wo-BEMwWniCTuB#e8s)mVi4PaYFV z6eM50-!MX5nP&PH_F8enhxTP>W-2 z%j%ZGL()nUS2&rd{}OoIVcjWurp`3r$_(TcprB@sj6n4|R{}9{is9CsH=C z-JB-l<){2!*?i*q3G*l2@4k5C%aJ=rb|hIJS#{LvNZZl4zz-s&U9zdls@*|;mfky^ zX9^$h&hD`8aPP<$UoU2_Zl|_S!Ev&|ln>K9CTUE{n6^XF(D`VP=?cFPJ=6ZGo~l+W zPv?wPChSt}+h$*L*zGlYQSu9&UDCGm;ynJ(wDXuheTkQpH=9@9#5L3QC}<`q@bI=t zD^CnOV{up_wPs4tgiVvXCf(A$s%5IPRYO-jS6fy!R^hIitlNC0{FAILw zspAzEea+o0_*=)D(3_T)yXGvFabM@~uIG+&Wkg)`y>Pqee>46x{Ap@h)YR>?$!X~! z(N;^>wnb}`_9V?r>VLFG$oFKFrr%1Rmy0fOFH^bPH}k}rgl~q=r#_t;JN5F^*HhT1 zP7jIDV$|BHm8<0+!nrEvYQ|Ngt8rH=O;t_xx5{i4+v@(RqI6r;nqP`v>%O}3PIH@Z zOs?0jS8|%k>E5YFvl4r=CzaFsU1li!Z z7IP0k_om$~}onwhgAcSQEyl$d=k?zmo3yt(`A+q2&r*ysN{c<74K*+)G`_yj1*38@zw6SZ$s?9TmT)%vGv z-+p1cmv@hS&-^vXYrP}C&*ndtKG%Qi`Qmuz`!e_I>}TCq+n=_-{NJ~KNB{LRn=oHu zu42|~Ol~`#PTcBwRlr?@s#4Sr#?BGZ-;G{y(PDEZ+ZKx zzCE(R*0E*t?zrBVy5V)%I>)@scen34?%w@b3=%!mVBW7 zvA-5O%D>(_wKtw?2dgDT3yWW4NER(x3VVpYg$ot1w=M59fEa^vrY zDaUW#p7zn;`-cyLx0Tm!<=Wc1Rlfh2Y;C~vpzDF_1LNy>igg~}_}q4&?cd`!k9~VL z^|toT_y6F>;rDCan{1=(tgLDIdU=h}m!i}BTj%cjz4`I^*tNUXmge?sJ9PO$$*-5< z`&<4SRULcm^FH$1&1>;j>(^#3-zr|>ARBG{%sSbcHC8d!`T3pmU(2G)w*O!D{dVW) zQ_olHd&FtHQ~dJet4{oxT{{Xie_p!tbjIn)duLb4$8+v0+JAm|{)bh^ufD!MXMOC; z?XUM&+Hh9}C-zu=y!Ipa{h?j0%imABr>iTr zXL@D*C+6SI|Bo-|zwAA8{)YKlcG

    {yqAbT4R}68To`sNnBuO!wFUwJ%u91iQFAA z4(LLEUpNJL3u zX-P(Y5vU3F*;nVJk4{*DpN_{_PhHKE>He{kMlDyaF}_zIEHu}FAdMkmpLw2 zYkK_L8%MqA$3IQTi0XRsqCv%Z!<-|HB1bwN=C=tw@%|T5=VHgkF@eS7(Si9%tc5Jz z6Pb>0(LJ@urE9s%yMwmR-tBoeGj^>^%93Ya3aWOkx>p?bR_4iV)_xxiq$DKI?ns`b zc{A6&;#!}fh=a%1#LUF}dyN z%!Y@ii`5Ua{J+V+LHyQ?)!~I@r`VbeHyk;ke06nf-iyla0UIclG86^Uu%YE6ncQKmTLKol~*T z|6V!`>@NlTN_yd zl@gDbJmN@JP0#jPXQpsHP4W5iDN8E5KE|FZUHPU|xUyn`)Ls2+IhGPyk@qDpv`KN_ zlyt2&>iM|-t)0wy_q)P1pN$Sq4m%aIA;GYy+ko?Z=CSm@{zd0b*u5}$A+SZjB-ZNJ z+<=4USj3;@R_tqT-(9=M@O|=02R`PlmySNT`7q$^+?0seO;;37ZTP6%TDGqO0XHgH6P6o2B}4);WjzbySwLl^zoK^4L^<`}wDu zpN_k0{@W(`Y3|3)``XVk(q1H|CGDR3u;y@+FU!1gp)J*ht5T(&ZRTm)C{yaJdDXi^ z;%}inlP3FCB_6h2E~^f4o)?Q;GmY2iRzdSi;g*RlE6aQ`4{msoZpBde!bM54%9-8F zpDD~d^ShGH+0Y{wH+(tF;(q4-QcXRs;4Lpgtpk#irP2;>owqq8&GVDi_sb%lb0++@ zS!!}U^58~2J-f_T1^Kf->n(mM5Sx4X;;fG3rB#lrB8nw7`B|!tc4bb9(YV!d+Ge#( zQRp12TLCi56#}H9f*Fj9R&$l|Yi`%;%~bEu3DUcAx@U)vNX#9zBVAV&7gtP*;MOwM zH1SjSRl2O{eW|nK>#ZvpPSU0smow71ywWcD?!Nizc*kN3{kdM(v(8FCefRn00#ldF ztxVI`91Dz+*s8W*S;LmZL(y|Cux(R#vdrz~TO5h%RxMHCcEJvAS<4D9e*d|P zyZ!j%y6gtk^OLH2Zzeoi@O0Jl2R6pGQY<%Y-aP#6+doHSQKy@-9KYW>~>pJZbaq0#d>pAX|4<8H@}^=@Y#ys;J!tPM|nS0 z&$%x=X?=;t(L%4j2C4UPtr~vdzmI` zZxwy~V7IW%t(T9kEwwyz!TN2jh2Y5vD?c7B<3E2hGiUO4_cdgW_$DJ#uX1QdCgu~xuY_Zk$?NHAHRQb-P+wQjz-zVqxwMV(Z)I0;nQV*ts!Xxc`-k4Yf0xvF-hTHbm(7k3cUAhY zR5lY=oM60s*;8@zuqCU4e*U;uymG_(pHKP2Q`SE85;}gU<4nS>lY7th)%;s>)=R|e z$SKj*jRJx*SKs<{@$0fR8)bi9{u}#p8~dk=TPt^daEr})qqSzDE7#NYUp}c@EoTl} zyH~vS>&d^ef1aH)a}wLjzfM0nci}2IyVno?rLniGmnej9(3+*OLuc`4Q|a)q*RPK4 zWV6~UF#k_={I9!;dGYaK_VxLq+1jSpGIDQRY3>XDawsihop@Sp>E}<2>{345K411> zx3z!a&$Dg2N(<%8&t2Jgy?4WD=OwlszVD;8tt0ZL6z+Pbn8dl~_gBStwsyyOy1%Zk z+tBp=eq7jcvDF&C^?3Vs+x=bpYlg7!#+P$fM8w|u7WeJr)5+8RJUwXlZqv(4PfJ>5 z_HK-sd~~MKDb>Be ztk+A*m43F0Rtj4eWuwvhgDFjR{X{Aex82ms+k$zbJcbn|CXM(P3H;g*_}pu`y!7&{3yWw)}hZ& zX<0zhixnGwoVgYgIp^z5&tGp2)|xD{4dLi~{p@S4$-jJO`1tMO_}k&NpNnc#Nc uqerwuqg^+zYt_2{^P6@3mfoXZ;{*5dChuIwP|v`?z~JfX=d#Wzp$P!oJ@O|2 literal 0 HcmV?d00001 diff --git a/doc/html/images/prev.png b/doc/html/images/prev.png new file mode 100755 index 0000000000000000000000000000000000000000..f7f036150f816cbbd5abb1adc8b0b3a23cb18884 GIT binary patch literal 741 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj4kiW$hQCG&XEQJ`a29w(7Bet#3xP1>rMq>1 z7#NtQd%8G=RLtp}eB1w4fK0=0`CmCb9}jX&i{|bS;8JZU(rk@m$+@m&*6<)z@HwyJ zLBqu}Z%$LK7D(P>EYqc@HB&Dyz50OU9-qHYtF3<)O)B0e|K<5fMusbOSCWJ`ZtmV( z?SA2M)XNP=j_wrOvh>T^FG0c#0e7^lB950N-a2-pjIV5-IU~dL@adCpdRAZ9_a#*` z{!B7Y*d48=`p-K!8CJ{-`^oZt`k$BQGc!ZI>O5v;Tz+xp#l7o$FFkbJ8MH1$`?&h? z3$bs%KYO=q^?g$dQ;Uyh&b<`7lXvi~plwP^$w$2x-&VbjzrJ&- z%)R#hz0%$L``hog-LyIVEOOle*YHJ`HeK;h5pH~StMYA(2iLU;rjt4iGTY`Tzhs?t zcH{r%+0PXi4xBq^rYPVtMZw*JcWt9)#Ods_fyMc&rk@J>qV#vdg&2;gzgv=)ojH?z z%qU^v?~<GESXNgP1H(Vx*XJ);U?7_^S|hIc3Yfca{P?#O1blEjvK!&?6Z15 zm7&ag_qPdqXTLv|G{f&oChJ<&M8i(Ct^R9yGfElf&buW2yNB)62aj6y`~FQE7aUr? zfhU^BnN6p0>&;vLu7+#LPu0G9>f_6gkB`Rx-Q$%Syn%b0ip~#CYoGmB{M1&%dzJIVTo@P_7(8A5T-G@yGywp< C*k44otVv!`vx;GaF%2` zI|pPYCo?cq+iGS4^JFAuNVf4f%QU%gGJBl!RACQnlr-uwP+|2s@rY}U zg3=@rM;Au%nAoN@i)u_i-MQ;$eZ}u^fBR7X z_U)_cLwOtCR4A!yikdMfbWT6^y>w$bTYHPq#>EWW0S#PB8oXH4O>dq)e^Z`g^Cj+o zs_)$xw-oJJ{`>v;|HlP(dfMnQ2>6}&cxOdO--OF8GN*kXt-EqO+`?ElGNM_w)#o|4 ze!z)?+A=?Tg~KhLNx%Pd>+$>73Qvp}3YN@R?_;s+(8TzeRavc;8~>;RLJ@J^KWEz9Q-zk&No&OQ$yjCZ}fkDK9-N-?3 z1(WXr?w$t84J_LZaPDBvf57i_!0iCzMg`6fj%p_ucRSc=u&6#zSi!V)0i#J{SOHr} z)8_|9JJ|9XcPFseurV31#x+%b;L~vwXlXqmz&ojNibAOeyHV4P38qh2DxLNPaES07 zb+FNpJ=Iv|+!~-6!g|%w_k#Wf%NIr^%u-EqPQn*-zL1s<_R1!E%BRqtmtJ%vj*IjhsssQys*%fwIY_G6n z$$e$@bvwPd^nzH1d5M7)+uY7`?$Z}bUwr#w^$Wo-BEMwWniCTuB#e8s)mVi4PaYFV z6eM50-!MX5nP&PH_F8enhxTP>W-2 z%j%ZGL()nUS2&rd{}OoIVcjWurp`3r$_(TcprB@sj6n4|R{}9{is9CsH=C z-JB-l<){2!*?i*q3G*l2@4k5C%aJ=rb|hIJS#{LvNZZl4zz-s&U9zdls@*|;mfky^ zX9^$h&hD`8aPP<$UoU2_Zl|_S!Ev&|ln>K9CTUE{n6^XF(D`VP=?cFPJ=6ZGo~l+W zPv?wPChSt}+h$*L*zGlYQSu9&UDCGm;ynJ(wDXuheTkQpH=9@9#5L3QC}<`q@bI=t zD^CnOV{up_wPs4tgiVvXCf(A$s%5IPRYO-jS6fy!R^hIitlNC0{FAILw zspAzEea+o0_*=)D(3_T)yXGvFabM@~uIG+&Wkg)`y>Pqee>46x{Ap@h)YR>?$!X~! z(N;^>wnb}`_9V?r>VLFG$oFKFrr%1Rmy0fOFH^bPH}k}rgl~q=r#_t;JN5F^*HhT1 zP7jIDV$|BHm8<0+!nrEvYQ|Ngt8rH=O;t_xx5{i4+v@(RqI6r;nqP`v>%O}3PIH@Z zOs?0jS8|%k>E5YFvl4r=CzaFsU1li!Z z7IP0k_om$~}onwhgAcSQEyl$d=k?zmo3yt(`A+q2&r*ysN{c<74K*+)G`_yj1*38@zw6SZ$s?9TmT)%vGv z-+p1cmv@hS&-^vXYrP}C&*ndtKG%Qi`Qmuz`!e_I>}TCq+n=_-{NJ~KNB{LRn=oHu zu42|~Ol~`#PTcBwRlr?@s#4Sr#?BGZ-;G{y(PDEZ+ZKx zzCE(R*0E*t?zrBVy5V)%I>)@scen34?%w@b3=%!mVBW7 zvA-5O%D>(_wKtw?2dgDT3yWW4NER(x3VVpYg$ot1w=M59fEa^vrY zDaUW#p7zn;`-cyLx0Tm!<=Wc1Rlfh2Y;C~vpzDF_1LNy>igg~}_}q4&?cd`!k9~VL z^|toT_y6F>;rDCan{1=(tgLDIdU=h}m!i}BTj%cjz4`I^*tNUXmge?sJ9PO$$*-5< z`&<4SRULcm^FH$1&1>;j>(^#3-zr|>ARBG{%sSbcHC8d!`T3pmU(2G)w*O!D{dVW) zQ_olHd&FtHQ~dJet4{oxT{{Xie_p!tbjIn)duLb4$8+v0+JAm|{)bh^ufD!MXMOC; z?XUM&+Hh9}C-zu=y!Ipa{h?j0%imABr>iTr zXL@D*C+6SI|Bo-|zwAA8{)YKlcG

    {yqAbT4R}68To`sNnBuO!wFUwJ%u91iQFAA z4(LLEUpNJL3u zX-P(Y5vU3F*;nVJk4{*DpN_{_PhHKE>He{kMlDyu=;qqIEHu}-x?O3FC8lI z@7bKMw>D1R!FRS*W!bCVdkle&uAzz{itqTRI!v8V@rd^yOGo{|{SQPr6<00dit609 zN-N{?GS8_k$1>*}>CNAL@3cYn#?76v$7>&`Y_8t3J3Z~(neS&Mvo?NKZZLP5!qFX2 z!(aFNV}60jiI2HCmZEtTVyPu;$t!JqrY3f=30ZA$_pfGo|Eevp)E+mJT(-%pVo3j$0unviQ}N zli%JP=w-<`WYE5Vd*8+^-*aikOQ!Y-UHR8%_27_Pfu^$CocRVf_Bl`dl-{P6VPeX3 zdfSY}0>`Zv2CUtioA~jY&Hs=U7bCWH%sj-?Kabs@N1shDS`hW&j#KLDrb`); z*_*MV@y&Z@9p6{`k%f#6h)a9e>9NfD2%e|NUFHal^ z2~pUppm|Rym;$X*ZmG6Y_gA*>mP`Vtnd2ybn1#} zY!8Dca)k#iRBaHxEG!`_=X%V4@x2v?%Ccf(xZL99zCTb|<;y6 zvhQ<^P52S^_3=lXcCt)8e{e!HZyvfeSxD`x#=gIQq|fXN5s_J8D}7J> z_&)VBTXOQGMHO0&FQ0fc*<8Q)Y~G{k)!_w?kCk?|rv1=6=G*)Dr;>l=;c}b?KB1mm`l{Oo-0<@#t3Vny_mRDop)6m(G&W zeUPAc{`$IqUPqmm7k>QfJ;%uSkfqcb!G!p8s^{;2G!|T0#(HYTVT;fj?-pxSyA><; zJ$P`(viH)h*od=SLC>B%SSYq{)AOHi4N7HOtcg;K>V49^U>kskX)! zB5jwS?>&DpUGBHDqCoSV3}xl5M>(Vy#+3y94Y=!gZNX99e|7~9(to=jebyHLx-Q1{ zS?qhI!z;@;rS>pSbZ!hS;GEqTyEbe6&vo}5=WLl`9yBEto(`(>tF_CQWW{D{`JPaYN|_K{dUgtfF0uEzhM}t6EQH psb#a8d#Lo`e!guT|C9f)E5E#+x?G@Khk=2C!PC{xWt~$(696HeggpQN literal 0 HcmV?d00001 diff --git a/doc/html/images/up.png b/doc/html/images/up.png new file mode 100755 index 0000000000000000000000000000000000000000..ef434074cab1625251ba558c14e5bf47c5add70b GIT binary patch literal 766 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rjj4kiW$hQCG&XEQJ`a29w(7Bet#3xP1>rMq>1 z7#Nr~c)B=-RLp6;bl3k@f(YA(e{|{j<+dCaBWI8i{UJGmx+J6bk>#`QET?BKe36&H*(nnSBa;ApSy0(ER7Nl zYjK~DdPMD3MyK4#Cy_?w)4JauzrJMaoGHfVq|e*WcV=C=Vc&MWXGed2*wbhhAslAX z7UinF)0wTSaiWO7tC8C-rFCD@tmMPc4`y z%U|lDdFu7GtxYm~?Q8wGlMTW1?_|wC`1<}Q_HE2> z^iIDmzSz7XK*VES&i%h3)A;-OuW+R<)KS~csg`gxduo+mZiGRCh}r2gmkfVB{P?~2 br+99$L2LK4shb%X7#KWV{an^LB{Ts5mN;Xz literal 0 HcmV?d00001 diff --git a/doc/html/images/warning.png b/doc/html/images/warning.png new file mode 100755 index 0000000000000000000000000000000000000000..51a30f751179811a3367891c0e54b1dea7afd3ac GIT binary patch literal 3927 zcmeAS@N?(olHy`uVBq!ia0y~yV2}f04mJh`25Wk44otVv!`vx;GaF%2` zI|pPYCo?cq+iGS4^JFAuNVf4f%QU%gGJBl!RACQnlr-uwP+|2s@rY}U zg3=@rM;Au%nAoN@i)u_i-MQ;$eZ}u^fBR7X z_U)_cLwOtCR4A!yikdMfbWT6^y>w$bTYHPq#>EWW0S#PB8oXH4O>dq)e^Z`g^Cj+o zs_)$xw-oJJ{`>v;|HlP(dfMnQ2>6}&cxOdO--OF8GN*kXt-EqO+`?ElGNM_w)#o|4 ze!z)?+A=?Tg~KhLNx%Pd>+$>73Qvp}3YN@R?_;s+(8TzeRavc;8~>;RLJ@J^KWEz9Q-zk&No&OQ$yjCZ}fkDK9-N-?3 z1(WXr?w$t84J_LZaPDBvf57i_!0iCzMg`6fj%p_ucRSc=u&6#zSi!V)0i#J{SOHr} z)8_|9JJ|9XcPFseurV31#x+%b;L~vwXlXqmz&ojNibAOeyHV4P38qh2DxLNPaES07 zb+FNpJ=Iv|+!~-6!g|%w_k#Wf%NIr^%u-EqPQn*-zL1s<_R1!E%BRqtmtJ%vj*IjhsssQys*%fwIY_G6n z$$e$@bvwPd^nzH1d5M7)+uY7`?$Z}bUwr#w^$Wo-BEMwWniCTuB#e8s)mVi4PaYFV z6eM50-!MX5nP&PH_F8enhxTP>W-2 z%j%ZGL()nUS2&rd{}OoIVcjWurp`3r$_(TcprB@sj6n4|R{}9{is9CsH=C z-JB-l<){2!*?i*q3G*l2@4k5C%aJ=rb|hIJS#{LvNZZl4zz-s&U9zdls@*|;mfky^ zX9^$h&hD`8aPP<$UoU2_Zl|_S!Ev&|ln>K9CTUE{n6^XF(D`VP=?cFPJ=6ZGo~l+W zPv?wPChSt}+h$*L*zGlYQSu9&UDCGm;ynJ(wDXuheTkQpH=9@9#5L3QC}<`q@bI=t zD^CnOV{up_wPs4tgiVvXCf(A$s%5IPRYO-jS6fy!R^hIitlNC0{FAILw zspAzEea+o0_*=)D(3_T)yXGvFabM@~uIG+&Wkg)`y>Pqee>46x{Ap@h)YR>?$!X~! z(N;^>wnb}`_9V?r>VLFG$oFKFrr%1Rmy0fOFH^bPH}k}rgl~q=r#_t;JN5F^*HhT1 zP7jIDV$|BHm8<0+!nrEvYQ|Ngt8rH=O;t_xx5{i4+v@(RqI6r;nqP`v>%O}3PIH@Z zOs?0jS8|%k>E5YFvl4r=CzaFsU1li!Z z7IP0k_om$~}onwhgAcSQEyl$d=k?zmo3yt(`A+q2&r*ysN{c<74K*+)G`_yj1*38@zw6SZ$s?9TmT)%vGv z-+p1cmv@hS&-^vXYrP}C&*ndtKG%Qi`Qmuz`!e_I>}TCq+n=_-{NJ~KNB{LRn=oHu zu42|~Ol~`#PTcBwRlr?@s#4Sr#?BGZ-;G{y(PDEZ+ZKx zzCE(R*0E*t?zrBVy5V)%I>)@scen34?%w@b3=%!mVBW7 zvA-5O%D>(_wKtw?2dgDT3yWW4NER(x3VVpYg$ot1w=M59fEa^vrY zDaUW#p7zn;`-cyLx0Tm!<=Wc1Rlfh2Y;C~vpzDF_1LNy>igg~}_}q4&?cd`!k9~VL z^|toT_y6F>;rDCan{1=(tgLDIdU=h}m!i}BTj%cjz4`I^*tNUXmge?sJ9PO$$*-5< z`&<4SRULcm^FH$1&1>;j>(^#3-zr|>ARBG{%sSbcHC8d!`T3pmU(2G)w*O!D{dVW) zQ_olHd&FtHQ~dJet4{oxT{{Xie_p!tbjIn)duLb4$8+v0+JAm|{)bh^ufD!MXMOC; z?XUM&+Hh9}C-zu=y!Ipa{h?j0%imABr>iTr zXL@D*C+6SI|Bo-|zwAA8{)YKlcG

    {yqAbT4R}68To`sNnBuO!wFUwJ%u91iQFAA z4(LLEUpNJL3u zX-P(Y5vU3F*;nVJk4{*DpN_{_PhHKE>He{kMlDyu%>#tIEHu}-y0sCFYPMw z@7%jv(zkb?JNjkOl2@v}mnUsuU3iF@Kg7f1ODlU^g_F~xUi-uG4e|&0HH3n^SBYKf zT43he;I=TcxL^4A$zR*pI802`JK7IY&rz3~7 zdGfgB86VtL>SbQJ*d&f+4u8X+P_HE!(N>pIZM|D>O%}R(?%8Kg)9@Y6-xc>>7cmlF z@T%Uh&|KncWk;>kR?aPJ?H-3N3N73#npwqg;=+W9tp(TKKT*G58fGQo_FS`XK~}x; zy7P{f?#2TgP@zQBToLwwn9SmAkvz_MiQ(q+;G>apO{vS8Kalt;UWo z_u527^Y6EME}kS5vP#v*=gjJzJB|G2y*V~jo4H`qUxUxnx6YX;-L{1Lzif=IgQ;Ln zk8&5U#Jk8(r)JF7e)RCL>6&$6hL$^fT7N2Sou06(xkHKh;WOL4?@|NhCuOy+*vB!y zjrY6K;@k9nn8~W2h+KQE`cs}PSI0d3o5^TReJK5i@){XV~v_=ku0~3Ikx?4 zh~2?+c-2Pj)+G{t=PofU3S4H^@;GAG8kbj7qTP2H^enJBy45(!fAQI z>HnUI9QtLn>z_YPj zt9G}{px4$SF`iL}ezEOomG&r~-#6`Y&AC)6Ms%Xs?o-wbg!Kt6${PGj? zAc>2OEm|8cxh}bzSMk|Cv$jy?z4y=V2SF3BnAeGmhN?tc9NT0f1C?=i za$@h<&7U4~ZOX-maxc$CPEp)3Z{m@K245$=-1;+aQq)KDcL6)j_kB&;@_L1C@4=Vy zO`Z-5cOJ;_T(#};XC2YxCo$%3ZPkUDOZc~WatNgSc0cfSbwS^kgV8$=UWs=)C3)lJ ztYgIqF9l7ne0wybY2lQ&H@uoMRnJORJ>Ixrv8)ltnum_zwZA@cmVT`1HwxYJzS?P0 zz?+qN+fP=l(#n5n_VxFzGy4ySE)JaMTKX}4hdYB^XH z)80}%XMe9sQeyclx9=;nBj)|%+q7X}Z&{V^+aHT&NKCikQocSRN#4J2t-NRW;|+sTQSQJ0kN;+$zDxJQ84oit1_lNO MPgg&ebxsLQ0L+(v)Bpeg literal 0 HcmV?d00001 diff --git a/doc/html/index.html b/doc/html/index.html new file mode 100644 index 0000000..298875d --- /dev/null +++ b/doc/html/index.html @@ -0,0 +1,168 @@ + + + +Chapter 1. Boost.Optional + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +


    +
    Next
    +
    +
    +

    +Chapter 1. Boost.Optional

    +

    +Fernando Luis Cacciola Carballal +

    +
    +
    +

    + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +

    +
    +
    + +
    + +

    + Consider these functions which should return a value but which might not have + a value to return: +

    +
      +
    • + (A) double sqrt(double n + ); +
    • +
    • + (B) char get_async_input(); +
    • +
    • + (C) point polygon::get_any_point_effectively_inside(); +
    • +
    +

    + There are different approaches to the issue of not having a value to return. +

    +

    + A typical approach is to consider the existence of a valid return value as + a postcondition, so that if the function cannot compute the value to return, + it has either undefined behavior (and can use assert in a debug build) or uses + a runtime check and throws an exception if the postcondition is violated. This + is a reasonable choice for example, for function (A), because the lack of a + proper return value is directly related to an invalid parameter (out of domain + argument), so it is appropriate to require the callee to supply only parameters + in a valid domain for execution to continue normally. +

    +

    + However, function (B), because of its asynchronous nature, does not fail just + because it can't find a value to return; so it is incorrect to consider such + a situation an error and assert or throw an exception. This function must return, + and somehow, must tell the callee that it is not returning a meaningful value. +

    +

    + A similar situation occurs with function (C): it is conceptually an error to + ask a null-area polygon to return a point inside itself, + but in many applications, it is just impractical for performance reasons to + treat this as an error (because detecting that the polygon has no area might + be too expensive to be required to be tested previously), and either an arbitrary + point (typically at infinity) is returned, or some efficient way to tell the + callee that there is no such point is used. +

    +

    + There are various mechanisms to let functions communicate that the returned + value is not valid. One such mechanism, which is quite common since it has + zero or negligible overhead, is to use a special value which is reserved to + communicate this. Classical examples of such special values are EOF, string::npos, points + at infinity, etc... +

    +

    + When those values exist, i.e. the return type can hold all meaningful values + plus the signal value, this mechanism + is quite appropriate and well known. Unfortunately, there are cases when such + values do not exist. In these cases, the usual alternative is either to use + a wider type, such as int in place + of char; or a compound type, such + as std::pair<point,bool>. +

    +

    + Returning a std::pair<T,bool>, thus attaching a boolean flag to the result + which indicates if the result is meaningful, has the advantage that can be + turned into a consistent idiom since the first element of the pair can be whatever + the function would conceptually return. For example, the last two functions + could have the following interface: +

    +
    +std::pair<char,bool> get_async_input();
    +std::pair<point,bool> polygon::get_any_point_effectively_inside();
    +
    +

    + These functions use a consistent interface for dealing with possibly inexistent + results: +

    +
    +std::pair<point,bool> p = poly.get_any_point_effectively_inside();
    +if ( p.second )
    +    flood_fill(p.first);
    +
    +

    + However, not only is this quite a burden syntactically, it is also error prone + since the user can easily use the function result (first element of the pair) + without ever checking if it has a valid value. +

    +

    + Clearly, we need a better idiom. +

    +
    +

    +

    +

    +

    +

    +

    +

    +

    +
    + + + +

    Last revised: May 29, 2007 at 06:31:03 GMT

    +
    +
    Next
    + + diff --git a/doc/implementation_notes.qbk b/doc/implementation_notes.qbk new file mode 100644 index 0000000..519b3ee --- /dev/null +++ b/doc/implementation_notes.qbk @@ -0,0 +1,28 @@ +[/ + Boost.Optional + + Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +] + + + +[#optional_implementation_notes] + +[section Implementation Notes] + +`optional` is currently implemented using a custom aligned storage facility +built from `alignment_of` and `type_with_alignment` (both from Type Traits). It +uses a separate boolean flag to indicate the initialization state. +Placement new with `T`'s copy constructor and `T`'s destructor are explicitly used +to initialize,copy and destroy optional values. +As a result, `T`'s default constructor is effectively by-passed, but the exception +guarantees are basic. +It is planned to replace the current implementation with another with stronger +exception safety, such as a future `boost::variant`. + +[endsect] + diff --git a/doc/optional.qbk b/doc/optional.qbk new file mode 100644 index 0000000..388f686 --- /dev/null +++ b/doc/optional.qbk @@ -0,0 +1,131 @@ +[library Boost.Optional + [quickbook 1.4] + [authors [Cacciola Carballal, Fernando Luis]] + [copyright 2003-2007 Fernando Luis Cacciola Carballal] + [category miscellaneous] + [id optional] + [dirname optional] + [purpose + Discriminated-union wrapper for optional values + ] + [source-mode c++] + [license +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +[@http://www.boost.org/LICENSE_1_0.txt]) + ] +] + +[/ Macros will be used for links so we have a central place to change them ] + + +[/ Cited Boost resources ] + +[def __BOOST_VARIANT__ [@../../../variant/index.html Boost.Variant]] +[def __BOOST_TRIBOOL__ [@../../../tribool/index.html boost::tribool]] + +[def __OPTIONAL_POINTEE__ [@../../../utility/OptionalPointee.html OptionalPointee]] +[def __COPY_CONSTRUCTIBLE__ [@../../../utility/CopyConstructible.html Copy Constructible]] +[def __FUNCTION_EQUAL_POINTEES__ [@../../../utility/OptionalPointee.html#equal `equal_pointees()`]] +[def __FUNCTION_LESS_POINTEES__ [@../../../utility/OptionalPointee.html#less `less_pointees()`]] + +[def __IN_PLACE_FACTORY_HPP__ [@../../../../boost/utility/in_place_factory.hpp in_place_factory.hpp]] +[def __TYPED_IN_PLACE_FACTORY_HPP__ [@../../../../boost/utility/typed_in_place_factory.hpp typed_in_place_factory.hpp]] + +[/ Other web resources ] + +[def __HASKELL__ [@http://www.haskell.org/ Haskell]] +[def __SGI_DEFAULT_CONSTRUCTIBLE__ [@http://www.sgi.com/tech/stl/DefaultConstructible.html Default Constructible]] + + +[/ Icons ] + +[def __NOTE__ [$images/note.png]] +[def __ALERT__ [$images/caution.png]] +[def __DETAIL__ [$images/note.png]] +[def __TIP__ [$images/tip.png]] +[def __QUESTION_MARK__ [$images/question.png]] +[def __SPACE__ [$images/space.png]] +[def __GO_TO__ [$images/callouts/R.png]] + + +[section Motivation] + +Consider these functions which should return a value but which might not have +a value to return: + +* (A) `double sqrt(double n );` +* (B) `char get_async_input();` +* (C) `point polygon::get_any_point_effectively_inside();` + +There are different approaches to the issue of not having a value to return. + +A typical approach is to consider the existence of a valid return value as a +postcondition, so that if the function cannot compute the value to return, it +has either undefined behavior (and can use assert in a debug build) or uses a +runtime check and throws an exception if the postcondition is violated. This +is a reasonable choice for example, for function (A), because the lack of a +proper return value is directly related to an invalid parameter (out of domain +argument), so it is appropriate to require the callee to supply only parameters +in a valid domain for execution to continue normally. + +However, function (B), because of its asynchronous nature, does not fail just +because it can't find a value to return; so it is incorrect to consider such +a situation an error and assert or throw an exception. This function must +return, and somehow, must tell the callee that it is not returning a meaningful +value. + +A similar situation occurs with function (C): it is conceptually an error to +ask a ['null-area] polygon to return a point inside itself, but in many +applications, it is just impractical for performance reasons to treat this as +an error (because detecting that the polygon has no area might be too expensive +to be required to be tested previously), and either an arbitrary point +(typically at infinity) is returned, or some efficient way to tell the callee +that there is no such point is used. + +There are various mechanisms to let functions communicate that the returned +value is not valid. One such mechanism, which is quite common since it has +zero or negligible overhead, is to use a special value which is reserved to +communicate this. Classical examples of such special values are `EOF`, +`string::npos`, points at infinity, etc... + +When those values exist, i.e. the return type can hold all meaningful values +['plus] the ['signal] value, this mechanism is quite appropriate and well known. +Unfortunately, there are cases when such values do not exist. In these cases, +the usual alternative is either to use a wider type, such as `int` in place of +`char`; or a compound type, such as `std::pair`. + +Returning a `std::pair`, thus attaching a boolean flag to the result +which indicates if the result is meaningful, has the advantage that can be +turned into a consistent idiom since the first element of the pair can be +whatever the function would conceptually return. For example, the last two +functions could have the following interface: + + std::pair get_async_input(); + std::pair polygon::get_any_point_effectively_inside(); + +These functions use a consistent interface for dealing with possibly inexistent +results: + + std::pair p = poly.get_any_point_effectively_inside(); + if ( p.second ) + flood_fill(p.first); + +However, not only is this quite a burden syntactically, it is also error prone +since the user can easily use the function result (first element of the pair) +without ever checking if it has a valid value. + +Clearly, we need a better idiom. + +[endsect] + + +[include development.qbk] +[include reference.qbk] +[include examples.qbk] +[include special_cases.qbk] +[include implementation_notes.qbk] +[include dependencies.qbk] +[include acknowledgments.qbk] + + diff --git a/doc/reference.qbk b/doc/reference.qbk new file mode 100644 index 0000000..73993b3 --- /dev/null +++ b/doc/reference.qbk @@ -0,0 +1,880 @@ +[/ + Boost.Optional + + Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal + + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +] + + +[section Synopsis] + + namespace boost { + + template + class optional + { + public : + + // (If T is of reference type, the parameters and results by reference are by value) + + optional () ; ``[link reference_optional_constructor __GO_TO__]`` + + optional ( none_t ) ; ``[link reference_optional_constructor_none_t __GO_TO__]`` + + optional ( T const& v ) ; ``[link reference_optional_constructor_value __GO_TO__]`` + + // [new in 1.34] + optional ( bool condition, T const& v ) ; ``[link reference_optional_constructor_bool_value __GO_TO__]`` + + optional ( optional const& rhs ) ; ``[link reference_optional_constructor_optional __GO_TO__]`` + + template explicit optional ( optional const& rhs ) ; ``[link reference_optional_constructor_other_optional __GO_TO__]`` + + template explicit optional ( InPlaceFactory const& f ) ; ``[link reference_optional_constructor_factory __GO_TO__]`` + + template explicit optional ( TypedInPlaceFactory const& f ) ; ``[link reference_optional_constructor_factory __GO_TO__]`` + + optional& operator = ( none_t ) ; ``[/[link reference_optional_operator_equal_none_t __GO_TO__]]`` + + optional& operator = ( T const& v ) ; ``[link reference_optional_operator_equal_value __GO_TO__]`` + + optional& operator = ( optional const& rhs ) ; ``[link reference_optional_operator_equal_optional __GO_TO__]`` + + template optional& operator = ( optional const& rhs ) ; ``[link reference_optional_operator_equal_other_optional __GO_TO__]`` + + template optional& operator = ( InPlaceFactory const& f ) ; ``[/[link reference_optional_operator_equal_factory __GO_TO__]]`` + + template optional& operator = ( TypedInPlaceFactory const& f ) ; ``[/[link reference_optional_operator_equal_factory __GO_TO__]]`` + + T const& get() const ; ``[link reference_optional_get __GO_TO__]`` + T& get() ; ``[link reference_optional_get __GO_TO__]`` + + // [new in 1.34] + T const& get_value_or( T const& default ) const ; ``[link reference_optional_get_value_or_value __GO_TO__]`` + + T const* operator ->() const ; ``[link reference_optional_operator_arrow __GO_TO__]`` + T* operator ->() ; ``[link reference_optional_operator_arrow __GO_TO__]`` + + T const& operator *() const ; ``[link reference_optional_get __GO_TO__]`` + T& operator *() ; ``[link reference_optional_get __GO_TO__]`` + + T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]`` + T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]`` + + operator unspecified-bool-type() const ; ``[link reference_optional_operator_bool __GO_TO__]`` + + bool operator!() const ; ``[link reference_optional_operator_not __GO_TO__]`` + + // deprecated methods + + // (deprecated) + void reset() ; ``[link reference_optional_reset __GO_TO__]`` + + // (deprecated) + void reset ( T const& ) ; ``[link reference_optional_reset_value __GO_TO__]`` + + // (deprecated) + bool is_initialized() const ; ``[link reference_optional_is_initialized __GO_TO__]`` + + }; + + template inline bool operator == ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_equal_optional_optional __GO_TO__]`` + + template inline bool operator != ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_not_equal_optional_optional __GO_TO__]`` + + template inline bool operator < ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_less_optional_optional __GO_TO__]`` + + template inline bool operator > ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_greater_optional_optional __GO_TO__]`` + + template inline bool operator <= ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_less_or_equal_optional_optional __GO_TO__]`` + + template inline bool operator >= ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_greater_or_equal_optional_optional __GO_TO__]`` + + // [new in 1.34] + template inline optional make_optional ( T const& v ) ; ``[link reference_make_optional_value __GO_TO__]`` + + // [new in 1.34] + template inline optional make_optional ( bool condition, T const& v ) ; ``[link reference_make_optional_bool_value __GO_TO__]`` + + // [new in 1.34] + template inline T const& get_optional_value_or ( optional const& opt, T const& default ) ; ``[link reference_optional_get_value_or_value __GO_TO__]`` + + template inline T const& get ( optional const& opt ) ; ``[link reference_optional_get __GO_TO__]`` + + template inline T& get ( optional & opt ) ; ``[link reference_optional_get __GO_TO__]`` + + template inline T const* get ( optional const* opt ) ; ``[link reference_optional_get __GO_TO__]`` + + template inline T* get ( optional* opt ) ; ``[link reference_optional_get __GO_TO__]`` + + template inline T const* get_pointer ( optional const& opt ) ; ``[link reference_optional_get_ptr __GO_TO__]`` + + template inline T* get_pointer ( optional & opt ) ; ``[link reference_optional_get_ptr __GO_TO__]`` + + template inline void swap( optional& x, optional& y ) ; ``[link reference_swap_optional_optional __GO_TO__]`` + + } // namespace boost + + +[endsect] + +[section Detailed Semantics] + +Because `T` might be of reference type, in the sequel, those entries whose +semantic depends on `T` being of reference type or not will be distinguished +using the following convention: +* If the entry reads: `optional`, the description +corresponds only to the case where `T` is not of reference type. +* If the entry reads: `optional`, the description corresponds only to +the case where `T` is of reference type. +* If the entry reads: `optional`, the description is the same for both +cases. + +[note +The following section contains various `assert()` which are used only to show +the postconditions as sample code. It is not implied that the type `T` must +support each particular expression but that if the expression is supported, +the implied condition holds. +] + +__SPACE__ + +[heading optional class member functions] + +__SPACE__ + +[#reference_optional_constructor] + +[: `optional::optional();`] + +* [*Effect:] Default-Constructs an `optional`. +* [*Postconditions:] `*this` is [_uninitialized]. +* [*Throws:] Nothing. +* Notes: T's default constructor [_is not] called. +* [*Example:] +`` +optional def ; +assert ( !def ) ; +`` + +__SPACE__ + +[#reference_optional_constructor_none_t] + +[: `optional::optional( none_t );`] + +* [*Effect:] Constructs an `optional` uninitialized. +* [*Postconditions:] `*this` is [_uninitialized]. +* [*Throws:] Nothing. +* [*Notes:] `T`'s default constructor [_is not] called. The expression +`boost::none` denotes an instance of `boost::none_t` that can be used as +the parameter. +* [*Example:] +`` +#include +optional n(none) ; +assert ( !n ) ; +`` + +__SPACE__ + +[#reference_optional_constructor_value] + +[: `optional::optional( T const& v )`] + +* [*Effect:] Directly-Constructs an `optional`. +* [*Postconditions:] `*this` is [_initialized] and its value is a['copy] +of `v`. +* [*Throws:] Whatever `T::T( T const& )` throws. +* [*Notes: ] `T::T( T const& )` is called. +* [*Exception Safety:] Exceptions can only be thrown during +`T::T( T const& );` in that case, this constructor has no effect. +* [*Example:] +`` +T v; +optional opt(v); +assert ( *opt == v ) ; +`` + +__SPACE__ + +[: `optional::optional( T& ref )`] + +* [*Effect:] Directly-Constructs an `optional`. +* [*Postconditions:] `*this` is [_initialized] and its value is an instance +of an internal type wrapping the reference `ref`. +* [*Throws:] Nothing. +* [*Example:] +`` +T v; +T& vref = v ; +optional opt(vref); +assert ( *opt == v ) ; +++ v ; // mutate referee +assert (*opt == v); +`` + +__SPACE__ + +[#reference_optional_constructor_bool_value] + +[: `optional::optional( bool condition, T const& v ) ;` ] +[: `optional ::optional( bool condition, T& v ) ;` ] + +* If condition is true, same as: + +[: `optional::optional( T const& v )`] +[: `optional ::optional( T& v )`] + +* otherwise, same as: + +[: `optional::optional()`] +[: `optional ::optional()`] + +__SPACE__ + +[#reference_optional_constructor_optional] + +[: `optional::optional( optional const& rhs );`] + +* [*Effect:] Copy-Constructs an `optional`. +* [*Postconditions:] If rhs is initialized, `*this` is initialized and +its value is a ['copy] of the value of `rhs`; else `*this` is uninitialized. +* [*Throws:] Whatever `T::T( T const& )` throws. +* [*Notes:] If rhs is initialized, `T::T(T const& )` is called. +* [*Exception Safety:] Exceptions can only be thrown during +`T::T( T const& );` in that case, this constructor has no effect. +* [*Example:] +`` +optional uninit ; +assert (!uninit); + +optional uinit2 ( uninit ) ; +assert ( uninit2 == uninit ); + +optional init( T(2) ); +assert ( *init == T(2) ) ; + +optional init2 ( init ) ; +assert ( init2 == init ) ; +`` + +__SPACE__ + +[: `optional::optional( optional const& rhs );`] + +* [*Effect:] Copy-Constructs an `optional`. +* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and its +value is another reference to the same object referenced by `*rhs`; else +`*this` is uninitialized. +* [*Throws:] Nothing. +* [*Notes:] If `rhs` is initialized, both `*this` and `*rhs` will reefer to the +same object (they alias). +* [*Example:] +`` +optional uninit ; +assert (!uninit); + +optional uinit2 ( uninit ) ; +assert ( uninit2 == uninit ); + +T v = 2 ; T& ref = v ; +optional init(ref); +assert ( *init == v ) ; + +optional init2 ( init ) ; +assert ( *init2 == v ) ; + +v = 3 ; + +assert ( *init == 3 ) ; +assert ( *init2 == 3 ) ; +`` + +__SPACE__ + +[#reference_optional_constructor_other_optional] + +[: `template explicit optional::optional( optional const& rhs );`] + +* [*Effect:] Copy-Constructs an `optional`. +* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and its +value is a ['copy] of the value of rhs converted to type `T`; else `*this` is +uninitialized. +* [*Throws:] Whatever `T::T( U const& )` throws. +* [*Notes: ] `T::T( U const& )` is called if `rhs` is initialized, which requires a +valid conversion from `U` to `T`. +* [*Exception Safety:] Exceptions can only be thrown during `T::T( U const& );` +in that case, this constructor has no effect. +* [*Example:] +`` +optional x(123.4); +assert ( *x == 123.4 ) ; + +optional y(x) ; +assert( *y == 123 ) ; +`` + +__SPACE__ + +[#reference_optional_constructor_factory] + +[: `template explicit optional::optional( InPlaceFactory const& f );`] +[: `template explicit optional::optional( TypedInPlaceFactory const& f );`] + +* [*Effect:] Constructs an `optional` with a value of `T` obtained from the +factory. +* [*Postconditions: ] `*this` is [_initialized] and its value is ['directly given] +from the factory `f` (i.e., the value [_is not copied]). +* [*Throws:] Whatever the `T` constructor called by the factory throws. +* [*Notes:] See [link optional_in_place_factories In-Place Factories] +* [*Exception Safety:] Exceptions can only be thrown during the call to +the `T` constructor used by the factory; in that case, this constructor has +no effect. +* [*Example:] +`` +class C { C ( char, double, std::string ) ; } ; + +C v('A',123.4,"hello"); + +optional x( in_place ('A', 123.4, "hello") ); // InPlaceFactory used +optional y( in_place('A', 123.4, "hello") ); // TypedInPlaceFactory used + +assert ( *x == v ) ; +assert ( *y == v ) ; +`` + +__SPACE__ + +[#reference_optional_operator_equal_value] + +[: `optional& optional::operator= ( T const& rhs ) ;`] + +* [*Effect:] Assigns the value `rhs` to an `optional`. +* [*Postconditions: ] `*this` is initialized and its value is a ['copy] of `rhs`. +* [*Throws:] Whatever `T::operator=( T const& )` or `T::T(T const&)` throws. +* [*Notes:] If `*this` was initialized, `T`'s assignment operator is used, +otherwise, its copy-constructor is used. +* [*Exception Safety:] In the event of an exception, the initialization +state of `*this` is unchanged and its value unspecified as far as `optional` +is concerned (it is up to `T`'s `operator=()`). If `*this` is initially +uninitialized and `T`'s ['copy constructor] fails, `*this` is left properly +uninitialized. +* [*Example:] +`` +T x; +optional def ; +optional opt(x) ; + +T y; +def = y ; +assert ( *def == y ) ; +opt = y ; +assert ( *opt == y ) ; +`` + +__SPACE__ + +[: `optional& optional::operator= ( T& const& rhs ) ;`] + +* [*Effect:] (Re)binds thee wrapped reference. +* [*Postconditions: ] `*this` is initialized and it references the same +object referenced by `rhs`. +* [*Notes:] If `*this` was initialized, is is ['rebound] to the new object. +See [link optional_refassign here] for details on this behavior. +* [*Example:] +`` +int a = 1 ; +int b = 2 ; +T& ra = a ; +T& rb = b ; +optional def ; +optional opt(ra) ; + +def = rb ; // binds 'def' to 'b' through 'rb' +assert ( *def == b ) ; +*def = a ; // changes the value of 'b' to a copy of the value of 'a' +assert ( b == a ) ; +int c = 3; +int& rc = c ; +opt = rc ; // REBINDS to 'c' through 'rc' +c = 4 ; +assert ( *opt == 4 ) ; +`` + +__SPACE__ + +[#reference_optional_operator_equal_optional] + +[: `optional& optional::operator= ( optional const& rhs ) ;`] + +* [*Effect:] Assigns another `optional` to an `optional`. +* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and +its value is a ['copy] of the value of `rhs`; else `*this` is uninitialized. +* [*Throws:] Whatever `T::operator( T const&)` or `T::T( T const& )` throws. +* [*Notes:] If both `*this` and `rhs` are initially initialized, `T`'s +['assignment operator] is used. If `*this` is initially initialized but `rhs` is +uninitialized, `T`'s [destructor] is called. If `*this` is initially uninitialized +but `rhs` is initialized, `T`'s ['copy constructor] is called. +* [*Exception Safety:] In the event of an exception, the initialization state of +`*this` is unchanged and its value unspecified as far as optional is concerned +(it is up to `T`'s `operator=()`). If `*this` is initially uninitialized and +`T`'s ['copy constructor] fails, `*this` is left properly uninitialized. +* [*Example:] +`` +T v; +optional opt(v); +optional def ; + +opt = def ; +assert ( !def ) ; +// previous value (copy of 'v') destroyed from within 'opt'. +`` + +__SPACE__ + +[: `optional & optional::operator= ( optional const& rhs ) ;`] + +* [*Effect:] (Re)binds thee wrapped reference. +* [*Postconditions:] If `*rhs` is initialized, `*this` is initialized and it +references the same object referenced by `*rhs`; otherwise, `*this` is +uninitialized (and references no object). +* [*Notes:] If `*this` was initialized and so is *rhs, this is is ['rebound] to +the new object. See [link optional_refassign here] for details on this behavior. +* [*Example:] +`` +int a = 1 ; +int b = 2 ; +T& ra = a ; +T& rb = b ; +optional def ; +optional ora(ra) ; +optional orb(rb) ; + +def = orb ; // binds 'def' to 'b' through 'rb' wrapped within 'orb' +assert ( *def == b ) ; +*def = ora ; // changes the value of 'b' to a copy of the value of 'a' +assert ( b == a ) ; +int c = 3; +int& rc = c ; +optional orc(rc) ; +ora = orc ; // REBINDS ora to 'c' through 'rc' +c = 4 ; +assert ( *ora == 4 ) ; +`` + +__SPACE__ + +[#reference_optional_operator_equal_other_optional] + +[: `template optional& optional::operator= ( optional const& rhs ) ;`] + +* [*Effect:] Assigns another convertible optional to an optional. +* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and +its value is a ['copy] of the value of `rhs` ['converted] to type `T`; else +`*this` is uninitialized. +* [*Throws:] Whatever `T::operator=( U const& )` or `T::T( U const& )` throws. +* [*Notes:] If both `*this` and rhs are initially initialized, `T`'s +['assignment operator] (from `U`) is used. If `*this` is initially initialized +but `rhs` is uninitialized, `T`'s ['destructor] is called. If `*this` is +initially uninitialized but rhs is initialized, `T`'s ['converting constructor] +(from `U`) is called. +* [*Exception Safety:] In the event of an exception, the initialization state +of `*this` is unchanged and its value unspecified as far as optional is +concerned (it is up to `T`'s `operator=()`). If `*this` is initially +uninitialized and `T`'s converting constructor fails, `*this` is left properly +uninitialized. +* [*Example:] +`` +T v; +optional opt0(v); +optional opt1; + +opt1 = opt0 ; +assert ( *opt1 == static_cast(v) ) ; +`` + +__SPACE__ + +[#reference_optional_reset_value] + +[: `void optional::reset( T const& v ) ;`] +* [*Deprecated:] same as `operator= ( T const& v) ;` + +__SPACE__ + +[#reference_optional_reset] + +[: `void optional::reset() ;`] +* [*Deprecated:] Same as `operator=( detail::none_t );` + +__SPACE__ + +[#reference_optional_get] + +[: `T const& optional::operator*() const ;`] +[: `T& optional::operator*();`] +[: `T const& optional::get() const ;`] +[: `T& optional::get() ;`] + +[: `inline T const& get ( optional const& ) ;`] +[: `inline T& get ( optional &) ;`] + +* [*Requirements:] `*this` is initialized +* [*Returns:] A reference to the contained value +* [*Throws:] Nothing. +* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. +* [*Example:] +`` +T v ; +optional opt ( v ); +T const& u = *opt; +assert ( u == v ) ; +T w ; +*opt = w ; +assert ( *opt == w ) ; +`` + +__SPACE__ + +[#reference_optional_get_value_or_value] + +[: `T const& optional::get_value_or( T const& default) const ;`] +[: `T& optional::get_value_or( T& default ) ;`] + +[: `inline T const& get_optional_value_or ( optional const& o, T const& default ) ;`] +[: `inline T& get_optional_value_or ( optional& o, T& default ) ;`] + +* [*Returns:] A reference to the contained value, if any, or `default`. +* [*Throws:] Nothing. +* [*Example:] +`` +T v, z ; +optional def; +T const& y = def.get_value_or(z); +assert ( y == z ) ; + +optional opt ( v ); +T const& u = get_optional_value_or(opt,z); +assert ( u == v ) ; +assert ( u != z ) ; +`` + +__SPACE__ + +[: `T const& optional::operator*() const ;`] +[: `T & optional::operator*();`] +[: `T const& optional::get() const ;`] +[: `T& optional::get() ;`] + +[: `inline T const& get ( optional const& ) ;`] +[: `inline T& get ( optional &) ;`] + +* [*Requirements: ] `*this` is initialized +* [*Returns:] [_The] reference contained. +* [*Throws:] Nothing. +* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. +* [*Example:] +`` +T v ; +T& vref = v ; +optional opt ( vref ); +T const& vref2 = *opt; +assert ( vref2 == v ) ; +++ v ; +assert ( *opt == v ) ; +`` + +__SPACE__ + +[#reference_optional_get_ptr] + +[: `T const* optional::get_ptr() const ;`] +[: `T* optional::get_ptr() ;`] + +[: `inline T const* get_pointer ( optional const& ) ;`] +[: `inline T* get_pointer ( optional &) ;`] + +* [*Returns:] If `*this` is initialized, a pointer to the contained value; +else `0` (['null]). +* [*Throws:] Nothing. +* [*Notes:] The contained value is permanently stored within `*this`, so you +should not hold nor delete this pointer +* [*Example:] +`` +T v; +optional opt(v); +optional const copt(v); +T* p = opt.get_ptr() ; +T const* cp = copt.get_ptr(); +assert ( p == get_pointer(opt) ); +assert ( cp == get_pointer(copt) ) ; +`` + +__SPACE__ + +[#reference_optional_operator_arrow] + +[: `T const* optional::operator ->() const ;`] +[: `T* optional::operator ->() ;`] + +* [*Requirements: ] `*this` is initialized. +* [*Returns:] A pointer to the contained value. +* [*Throws:] Nothing. +* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. +* [*Example:] +`` +struct X { int mdata ; } ; +X x ; +optional opt (x); +opt->mdata = 2 ; +`` + +__SPACE__ + +[#reference_optional_operator_bool] + +[: `optional::operator `['unspecified-bool-type]`() const ;`] + +* [*Returns:] An unspecified value which if used on a boolean context +is equivalent to (`get() != 0`) +* [*Throws:] Nothing. +* [*Example:] +`` +optional def ; +assert ( def == 0 ); +optional opt ( v ) ; +assert ( opt ); +assert ( opt != 0 ); +`` + +__SPACE__ + +[#reference_optional_operator_not] + +[: `bool optional::operator!() ;`] + +* [*Returns:] If `*this` is uninitialized, `true`; else `false`. +* [*Throws:] Nothing. +* [*Notes:] This operator is provided for those compilers which can't +use the ['unspecified-bool-type operator] in certain boolean contexts. +* [*Example:] +`` +optional opt ; +assert ( !opt ); +*opt = some_T ; + +// Notice the "double-bang" idiom here. +assert ( !!opt ) ; +`` + +__SPACE__ + +[#reference_optional_is_initialized] + +[: `bool optional::is_initialized() const ;`] + +* [*Returns: ] `true` if the `optional` is initialized, `false` otherwise. +* [*Throws:] Nothing. +* [*Example:] +`` +optional def ; +assert ( !def.is_initialized() ); +optional opt ( v ) ; +assert ( opt.is_initialized() ); +`` + +__SPACE__ + +[heading Free functions] + +__SPACE__ + +[#reference_make_optional_value] + +[: `optional make_optional( T const& v )`] + +* [*Returns: ] `optional(v)` for the ['deduced] type `T` of `v`. +* [*Example:] +`` +template void foo ( optional const& opt ) ; + +foo ( make_optional(1+1) ) ; // Creates an optional +`` + +__SPACE__ + +[#reference_make_optional_bool_value] + +[: `optional make_optional( bool condition, T const& v )`] + +* [*Returns: ] `optional(condition,v)` for the ['deduced] type `T` of `v`. +* [*Example:] +`` +optional calculate_foo() +{ + double val = compute_foo(); + return make_optional(is_not_nan_and_finite(val),val); +} + +optional v = calculate_foo(); +if ( !v ) + error("foo wasn't computed"); +`` + +__SPACE__ + +[#reference_operator_compare_equal_optional_optional] + +[: `bool operator == ( optional const& x, optional const& y );`] + +* [*Returns:] If both `x` and `y` are initialized, `(*x == *y)`. If only +`x` or `y` is initialized, `false`. If both are uninitialized, `true`. +* [*Throws:] Nothing. +* [*Notes:] Pointers have shallow relational operators while `optional` has +deep relational operators. Do not use `operator ==` directly in generic +code which expect to be given either an `optional` or a pointer; use +__FUNCTION_EQUAL_POINTEES__ instead +* [*Example:] +`` +T x(12); +T y(12); +T z(21); +optional def0 ; +optional def1 ; +optional optX(x); +optional optY(y); +optional optZ(z); + +// Identity always hold +assert ( def0 == def0 ); +assert ( optX == optX ); + +// Both uninitialized compare equal +assert ( def0 == def1 ); + +// Only one initialized compare unequal. +assert ( def0 != optX ); + +// Both initialized compare as (*lhs == *rhs) +assert ( optX == optY ) ; +assert ( optX != optZ ) ; +`` + +__SPACE__ + +[#reference_operator_compare_less_optional_optional] + +[: `bool operator < ( optional const& x, optional const& y );`] + +* [*Returns:] If `y` is not initialized, `false`. If `y` is initialized +and `x` is not initialized, `true`. If both `x` and `y` are initialized, +`(*x < *y)`. +* [*Throws:] Nothing. +* [*Notes:] Pointers have shallow relational operators while `optional` has +deep relational operators. Do not use `operator <` directly in generic code +which expect to be given either an `optional` or a pointer; use __FUNCTION_LESS_POINTEES__ instead. +* [*Example:] +`` +T x(12); +T y(34); +optional def ; +optional optX(x); +optional optY(y); + +// Identity always hold +assert ( !(def < def) ); +assert ( optX == optX ); + +// Both uninitialized compare equal +assert ( def0 == def1 ); + +// Only one initialized compare unequal. +assert ( def0 != optX ); + +// Both initialized compare as (*lhs == *rhs) +assert ( optX == optY ) ; +assert ( optX != optZ ) ; +`` + +__SPACE__ + +[#reference_operator_compare_not_equal_optional_optional] + +[: `bool operator != ( optional const& x, optional const& y );`] + +* [*Returns: ] `!( x == y );` +* [*Throws:] Nothing. + +__SPACE__ + +[#reference_operator_compare_greater_optional_optional] + +[: `bool operator > ( optional const& x, optional const& y );`] + +* [*Returns: ] `( y < x );` +* [*Throws:] Nothing. + +__SPACE__ + +[#reference_operator_compare_less_or_equal_optional_optional] + +[: `bool operator <= ( optional const& x, optional const& y );`] + +* [*Returns: ] `!( y= ( optional const& x, optional const& y );`] + +* [*Returns: ] `!( x& x, optional& y );`] + +* [*Effect:] If both `x` and `y` are initialized, calls `swap(*x,*y)` +using `std::swap`. If only one is initialized, say `x`, calls: +`y.reset(*x); x.reset();` If none is initialized, does nothing. +* [*Postconditions:] The states of `x` and `y` interchanged. +* [*Throws:] If both are initialized, whatever `swap(T&,T&)` throws. If only +one is initialized, whatever `T::T ( T const& )` throws. +* [*Notes:] If both are initialized, `swap(T&,T&)` is used unqualified but +with `std::swap` introduced in scope. +If only one is initialized, `T::~T()` and `T::T( T const& )` is called. +* [*Exception Safety:] If both are initialized, this operation has the +exception safety guarantees of `swap(T&,T&)`. +If only one is initialized, it has the same basic guarantee as +`optional::reset( T const& )`. +* [*Example:] +`` +T x(12); +T y(21); +optional def0 ; +optional def1 ; +optional optX(x); +optional optY(y); + +boost::swap(def0,def1); // no-op + +boost::swap(def0,optX); +assert ( *def0 == x ); +assert ( !optX ); + +boost::swap(def0,optX); // Get back to original values + +boost::swap(optX,optY); +assert ( *optX == y ); +assert ( *optY == x ); +`` + +[endsect] diff --git a/doc/special_cases.qbk b/doc/special_cases.qbk new file mode 100644 index 0000000..be65f6b --- /dev/null +++ b/doc/special_cases.qbk @@ -0,0 +1,376 @@ + +[section Optional references] + +This library allows the template parameter `T` to be of reference type: +`T&`, and to some extent, `T const&`. + +However, since references are not real objects some restrictions apply and +some operations are not available in this case: + +* Converting constructors +* Converting assignment +* InPlace construction +* InPlace assignment +* Value-access via pointer + +Also, even though `optional` treats it wrapped pseudo-object much as +a real value, a true real reference is stored so aliasing will ocurr: + +* Copies of `optional` will copy the references but all these references +will nonetheless reefer to the same object. +* Value-access will actually provide access to the referenced object +rather than the reference itself. + +[endsect] + +[#optional_refassign] + +[section Rebinding semantics for assignment of optional references] + +If you assign to an ['uninitialized ] `optional` the effect is to bind (for +the first time) to the object. Clearly, there is no other choice. + + int x = 1 ; + int& rx = x ; + optional ora ; + optional orb(x) ; + ora = orb ; // now 'ora' is bound to 'x' through 'rx' + *ora = 2 ; // Changes value of 'x' through 'ora' + assert(x==2); + +If you assign to a bare C++ reference, the assignment is forwarded to the +referenced object; it's value changes but the reference is never rebound. + + int a = 1 ; + int& ra = a ; + int b = 2 ; + int& rb = b ; + ra = rb ; // Changes the value of 'a' to 'b' + assert(a==b); + b = 3 ; + assert(ra!=b); // 'ra' is not rebound to 'b' + +Now, if you assign to an ['initialized ] `optional`, the effect is to +[*rebind] to the new object instead of assigning the referee. This is unlike +bare C++ references. + + int a = 1 ; + int b = 2 ; + int& ra = a ; + int& rb = b ; + optional ora(ra) ; + optional orb(rb) ; + ora = orb ; // 'ora' is rebound to 'b' + *ora = 3 ; // Changes value of 'b' (not 'a') + assert(a==1); + assert(b==3); + +[heading Rationale] + +Rebinding semantics for the assignment of ['initialized ] `optional` references has +been chosen to provide [*consistency among initialization states] even at the +expense of lack of consistency with the semantics of bare C++ references. +It is true that `optional` 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` forwarding assignment to the referenced object (thus +changing the referenced object value but not rebinding), and consider the +following code: + + optional a = get(); + int x = 1 ; + int& rx = x ; + optional b(rx); + a = b ; + +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` 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` 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; + +[endsect] + +[#optional_in_place_factories] + +[section In-Place Factories] + +One of the typical problems with wrappers and containers is that their +interfaces usually provide an operation to initialize or assign the +contained object as a copy of some other object. This not only requires the +underlying type to be __COPY_CONSTRUCTIBLE__, but also requires the existence of +a fully constructed object, often temporary, just to follow the copy from: + + struct X + { + X ( int, std:::string ) ; + } ; + + class W + { + X wrapped_ ; + + public: + + W ( X const& x ) : wrapped_(x) {} + } ; + + void foo() + { + // Temporary object created. + W ( X(123,"hello") ) ; + } + +A solution to this problem is to support direct construction of the +contained object right in the container's storage. +In this scheme, the user only needs to supply the arguments to the +constructor to use in the wrapped object construction. + + class W + { + X wrapped_ ; + + public: + + W ( X const& x ) : wrapped_(x) {} + W ( int a0, std::string a1) : wrapped_(a0,a1) {} + } ; + + void foo() + { + // Wrapped object constructed in-place + // No temporary created. + W (123,"hello") ; + } + +A limitation of this method is that it doesn't scale well to wrapped +objects with multiple constructors nor to generic code were the constructor +overloads are unknown. + +The solution presented in this library is the family of [*InPlaceFactories] +and [*TypedInPlaceFactories]. +These factories are a family of classes which encapsulate an increasing +number of arbitrary constructor parameters and supply a method to construct +an object of a given type using those parameters at an address specified by +the user via placement new. + +For example, one member of this family looks like: + + template + class TypedInPlaceFactory2 + { + A0 m_a0 ; A1 m_a1 ; + + public: + + TypedInPlaceFactory2( A0 const& a0, A1 const& a1 ) : m_a0(a0), m_a1(a1) {} + + void construct ( void* p ) { new (p) T(m_a0,m_a1) ; } + } ; + +A wrapper class aware of this can use it as: + + class W + { + X wrapped_ ; + + public: + + W ( X const& x ) : wrapped_(x) {} + W ( TypedInPlaceFactory2 const& fac ) { fac.construct(&wrapped_) ; } + } ; + + void foo() + { + // Wrapped object constructed in-place via a TypedInPlaceFactory. + // No temporary created. + W ( TypedInPlaceFactory2 + InPlaceFactoryN in_place ( A0 const& a0, ..., AN const& aN) ; + + template + TypedInPlaceFactoryN in_place ( T const& a0, A0 const& a0, ..., AN const& aN) ; + +In-place factories can be used generically by the wrapper and user as follows: + + class W + { + X wrapped_ ; + + public: + + W ( X const& x ) : wrapped_(x) {} + + template< class InPlaceFactory > + W ( InPlaceFactory const& fac ) { fac.template construct(&wrapped_) ; } + + } ; + + void foo() + { + // Wrapped object constructed in-place via a InPlaceFactory. + // No temporary created. + W ( in_place(123,"hello") ) ; + } + +The factories are implemented in the headers: __IN_PLACE_FACTORY_HPP__ and __TYPED_IN_PLACE_FACTORY_HPP__ + +[endsect] + +[section A note about optional] + +`optional` should be used with special caution and consideration. + +First, it is functionally similar to a tristate boolean (false,maybe,true) +—such as __BOOST_TRIBOOL__— except that in a tristate boolean, the maybe state +[_represents a valid value], unlike the corresponding state of an uninitialized +`optional`. +It should be carefully considered if an `optional` instead of a `tribool` +is really needed. + +Second, `optional<>` provides an implicit conversion to `bool`. This +conversion refers to the initialization state and not to the contained value. +Using `optional` can lead to subtle errors due to the implicit `bool` +conversion: + + void foo ( bool v ) ; + void bar() + { + optional v = try(); + + // The following intended to pass the value of 'v' to foo(): + foo(v); + // But instead, the initialization state is passed + // due to a typo: it should have been foo(*v). + } + +The only implicit conversion is to `bool`, and it is safe in the sense that +typical integral promotions don't apply (i.e. if `foo()` takes an `int` +instead, it won't compile). + +[endsect] + +[section Exception Safety Guarantees] + +Because of the current implementation (see [link optional_implementation_notes Implementation Notes]), all of the assignment methods: + +* `optional::operator= ( optional const& )` +* `optional::operator= ( T const& )` +* `template optional::operator= ( optional const& )` +* `template optional::operator= ( InPlaceFactory const& )` +* `template optional::operator= ( TypedInPlaceFactory const& ) ` +* `optional:::reset ( T const&)` + +Can only ['guarantee] the [_basic exception safety]: The lvalue optional is +left [_uninitialized] if an exception is thrown (any previous value is ['first] +destroyed using `T::~T()`) + +On the other hand, the ['uninitializing] methods: + +* `optional::operator= ( detail::none_t )` +* `optional::reset()` + +Provide the no-throw guarantee (assuming a no-throw `T::~T()`) + +However, since `optional<>` itself doesn't throw any exceptions, the only +source for exceptions here are `T`'s constructor, so if you know the exception +guarantees for `T::T ( T const& )`, you know that `optional`'s assignment and +reset has the same guarantees. + + // + // Case 1: Exception thrown during assignment. + // + T v0(123); + optional opt0(v0); + try + { + T v1(456); + optional opt1(v1); + opt0 = opt1 ; + + // If no exception was thrown, assignment succeeded. + assert( *opt0 == v1 ) ; + } + catch(...) + { + // If any exception was thrown, 'opt0' is reset to uninitialized. + assert( !opt0 ) ; + } + + // + // Case 2: Exception thrown during reset(v) + // + T v0(123); + optional opt(v0); + try + { + T v1(456); + opt.reset ( v1 ) ; + + // If no exception was thrown, reset succeeded. + assert( *opt == v1 ) ; + } + catch(...) + { + // If any exception was thrown, 'opt' is reset to uninitialized. + assert( !opt ) ; + } + +[heading Swap] + +`void swap( optional&, optional& )` has the same exception guarantee +as `swap(T&,T&)` when both optionals are initialized. +If only one of the optionals is initialized, it gives the same ['basic] +exception guarantee as `optional::reset( T const& )` (since +`optional::reset()` doesn't throw). +If none of the optionals is initialized, it has no-throw guarantee +since it is a no-op. + +[endsect] + +[section Type requirements] + +In general, `T` must be __COPY_CONSTRUCTIBLE__ and have a no-throw destructor. +The copy-constructible requirement is not needed if [*InPlaceFactories] are used. + +`T` [_is not] required to be __SGI_DEFAULT_CONSTRUCTIBLE__. + +[endsect] + + From c8e54ef488d9b2ed3d4d3ed13347d4f380a82f13 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Wed, 8 Aug 2007 19:02:26 +0000 Subject: [PATCH 08/15] Remove V1 Jamfiles [SVN r38516] --- test/Jamfile | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 test/Jamfile diff --git a/test/Jamfile b/test/Jamfile deleted file mode 100644 index 1f8b84a..0000000 --- a/test/Jamfile +++ /dev/null @@ -1,37 +0,0 @@ -# Boost.Optional Library test Jamfile -# -# Copyright (C) 2003, Fernando Luis Cacciola Carballal. -# -# Use, modification, and distribution is subject to the Boost Software -# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -# - -subproject libs/optional/test ; - -# bring in rules for testing -SEARCH on testing.jam = $(BOOST_BUILD_PATH) ; -include testing.jam ; - -# Make tests run by default. -DEPENDS all : test ; - -{ - test-suite optional : - [ run optional_test.cpp ] - [ run optional_test_tie.cpp ] - [ run optional_test_ref.cpp ] - [ run optional_test_inplace.cpp ] - [ run optional_test_io.cpp ] - [ compile-fail optional_test_fail1.cpp ] - [ compile-fail optional_test_fail2.cpp ] - [ compile-fail optional_test_fail3a.cpp ] - [ compile-fail optional_test_fail3b.cpp ] - [ compile-fail optional_test_ref_fail1.cpp ] - [ compile-fail optional_test_ref_fail2.cpp ] - [ compile-fail optional_test_ref_fail3.cpp ] - [ compile-fail optional_test_ref_fail4.cpp ] - [ compile-fail optional_test_inplace_fail.cpp ] - [ compile-fail optional_test_inplace_fail2.cpp ] - ; -} From a690c8e7a2e92be336a8cb243f27f1f91f799416 Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Fri, 2 Nov 2007 22:55:49 +0000 Subject: [PATCH 09/15] Merged changests from RC_1_34_0 - base rev 33417 [SVN r40704] --- doc/optional.html | 451 ++++++++++++++++++++----------- test/Jamfile.v2 | 2 - test/optional_test.cpp | 58 +++- test/optional_test_ref.cpp | 18 ++ test/optional_test_ref_fail2.cpp | 23 -- 5 files changed, 361 insertions(+), 191 deletions(-) delete mode 100644 test/optional_test_ref_fail2.cpp diff --git a/doc/optional.html b/doc/optional.html index fedf8d9..e216db5 100644 --- a/doc/optional.html +++ b/doc/optional.html @@ -3,6 +3,7 @@ + @@ -23,6 +24,7 @@ HREF="../../../boost/optional/optional.hpp">boost/optional/optional.hpp>
    Examples
    Optional references
    Rebinding semantics for assignment of optional references
    +
    none_t and none
    In-Place Factories
    A note about optional<bool>
    Exception Safety Guarantees
    @@ -138,7 +140,7 @@ necessary in order to do so.

    purpose of optional<T> suggests an alternative model: a container that either has a value of T or nothing.

    -

    As of this writing I don't know of any precedence for a variable-size fixed-capacity (of 1) +

    As of this writing I don't know of any precedent for a variable-size fixed-capacity (of 1) stack-based container model for optional values, yet I believe this is the consequence of the lack of practical implementations of such a container rather than an inherent shortcoming of the container model.

    @@ -348,7 +350,7 @@ class optional T const& get() const ; T& get() ; - T const& get_value_or( T const& default ) const ; [new in 1.34] + T const& get_value_or( T const& default ) const ; [new in 1.34] T const* operator ->() const ; T* operator ->() ; @@ -383,11 +385,59 @@ 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] + +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] + +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] + +template<class T> inline bool operator == ( none_t n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator != ( none_t n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator < ( none_t n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator > ( none_t n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator <= ( none_t n, optional<T> const& y ) ; [new in 1.34] + +template<class T> inline bool operator >= ( none_t n, optional<T> const& y ) ; [new in 1.34] + template<class T> inline optional<T> make_optional ( T const& v ) ; [new in 1.34] template<class T> inline optional<T> make_optional ( bool condition, T const& v ) ; [new in 1.34] -template<class T> inline T const& get_optional_value_or ( optional<T> const& opt, T const& default ) ; [new in 1.34] +template<class T> inline T const& get_optional_value_or ( optional<T> const& opt, T const& default ) ; [new in 1.34] template<class T> inline T const& get ( optional<T> const& opt ) ; @@ -457,9 +507,11 @@ used as the parameter.

    Example:

    -
    #include <boost/none.hpp>
    -
    optional<T> n(none) ;
    -assert ( !n ) ;
    +
    +#include <boost/none.hpp>
    +optional<int> n(boost::none) ;
    +assert ( !n ) ;
    +
    @@ -476,9 +528,11 @@ in that case, this constructor has no effect.

    Example:

    -
    T v;
    +
    +T v;
     optional<T> opt(v);
    -assert ( *opt == v ) ;
    +assert ( *opt == v ) ; +
    @@ -492,29 +546,32 @@ instance of an internal type wrapping the reference 'ref'.

    Throws: Nothing.

    Example:

    -
    T v;
    +
    +T v;
     T& vref = v ;
     optional<T&> opt(vref);
     assert ( *opt == v ) ;
     ++ v ; // mutate referee
    -assert (*opt == v); 
    +assert (*opt == v); +

    optional<T (not a ref)>::optional( bool condition, T const& v ) ;
    -optional<T&>           ::optional( bool condition, T&       v ) ;
    +optional<T&>           ::optional( bool condition, T&       v ) ;
     

    If condition is true, same as:

    optional<T (not a ref)>::optional( T const& v )
    -optional<T&>           ::optional( T&       v )
    +optional<T&>           ::optional( T&       v )
     

    otherwise, same as:

    -
    optional<T (not a ref)>::optional()
    -optional<T&>           ::optional()
    +
    +optional<T (not a ref)>::optional()
    +optional<T&>           ::optional()
     
    @@ -533,7 +590,8 @@ in that case, this constructor has no effect.

    Example:

    -
    optional<T> uninit ;
    +
    +optional<T> uninit ;
     assert (!uninit);
     
     optional<T> uinit2 ( uninit ) ;
    @@ -562,7 +620,8 @@ is uninitialized.

    reefer to the same object (they alias).

    Example:

    -
    optional<T&> uninit ;
    +
    +optional<T&> uninit ;
     assert (!uninit);
     
     optional<T&> uinit2 ( uninit ) ;
    @@ -605,7 +664,8 @@ in that case, this constructor has no effect.
     

    Example:

    -
    optional<double> x(123.4);
    +
    +optional<double> x(123.4);
     assert ( *x == 123.4 ) ;
     
     optional<int> y(x) ;
    @@ -633,7 +693,8 @@ in that case, this constructor has no effect.
     

    Example:

    -
    class C { C ( char, double, std::string ) ; } ;
    +
    +class C { C ( char, double, std::string ) ; } ;
     
     C v('A',123.4,"hello");
     
    @@ -649,6 +710,27 @@ assert ( *y == v ) ;
     
     
    +
    optional& optional<T>::operator= ( none_t n ) ;
    +
    +

    Effect: Same as opeator=(optional const& rhs), when rhs is default-constructed (uninitialized).

    +

    Postconditions: *this is uninitialized

    +

    Example:

    +
    +
    +#include <boost/none.hpp>
    +
    +optional<int> def ;
    +optional<int> opt(123) ;
    +
    +opt = boost::none ;
    +
    +assert ( opt == def ) ;
    +
    +
    +
    + +
    +
    optional& optional<T (not a ref)>::operator= ( T const& rhs ) ;

    Effect: Assigns the value 'rhs' to an optional.

    @@ -664,7 +746,8 @@ uninitialized and T's copy constructor fails, *this is left properly uninitialized]

    Example:

    -
    T x;
    +
    +T x;
     optional<T> def ;
     optional<T> opt(x) ;
     
    @@ -687,7 +770,8 @@ and it references the same object referenced by rhs.

    new object. See here for details on this behavior.

    Example:

    -
    int a = 1 ;
    +
    +int a = 1 ;
     int b = 2 ;
     T& ra = a ;
     T& rb = b ;
    @@ -817,7 +901,7 @@ assert ( *opt1 == static_cast<U>(v) ) ;
     
    void optional<T>::reset() ;
    -

    Deprecated: Same as operator=( detail::none_t );

    +

    Deprecated: Same as operator=( none_t n);


    @@ -852,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*();
    @@ -907,29 +965,66 @@ assert ( *opt == v ) ;

    -
    T const* optional<T (not a ref)>::get_ptr() const ;
    -T*       optional<T (not a ref)>::get_ptr() ;
    +
    T const& optional<T>::get_value_or( T const& default) const ;
    +T&       optional<T>::get_value_or( T&       default ) ;
     
    -inline T const* get_pointer ( optional<T (not a ref)> const& ) ;
    -inline T*       get_pointer ( optional<T (not a ref)> &) ;
    +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() ;
    +
    +inline T const* get_pointer ( optional<T> const& ) ;
    +inline T*       get_pointer ( optional<T> &) ;
     

    Returns: If *this is initialized, a pointer to the contained value; else 0 (null).

    Throws: Nothing.

    +

    Notes: If T is a reference type, the pointer is to the referenced object

    Notes: The contained value is permanently stored within *this, so -you should not hold nor delete this pointer +you should not hold nor delete this pointer.

    Example:

    -
    T v;
    -optional<T> opt(v);
    -optional<T> const copt(v);
    -T* p = opt.get_ptr() ;
    -T const* cp = copt.get_ptr();
    +    
    int v=123;
    +optional<int> opt(v);
    +optional<int> const copt(v);
    +int* p = opt.get_ptr() ;
    +int const* cp = copt.get_ptr();
     assert ( p == get_pointer(opt) );
     assert ( cp == get_pointer(copt) ) ;
    +
    +int& rv = v ;
    +optional<int&> optr(rv);
    +
    +*(optr.get_ptr()) = 456 ;
    +
    +assert ( v == 456 );
    +
    +
     
    @@ -938,13 +1033,14 @@ assert ( cp == get_pointer(copt) ) ;
    -
    T const* optional<T (not a ref)>::operator ->() const ;
    -T*       optional<T (not a ref)>::operator ->()       ;
    +
    T const* optional<T>::operator ->() const ;
    +T*       optional<T>::operator ->()       ;
     

    Requirements: *this is initialized.

    Returns: A pointer to the contained value.

    Throws: Nothing.

    +

    Notes: If T is a reference type, the pointer is to the referenced object

    Notes: The requirement is asserted via BOOST_ASSERT().

    Example:

    @@ -952,6 +1048,14 @@ T* optional<T (not a ref)>::operator ->() ; X x ; optional<X> opt (x); opt->mdata = 2 ; + +X& rx = x ; + +optional<X&> optr (rx); +optr->mdata = 4 ; + +assert ( x.mdata = 4 ) +
    @@ -1154,13 +1258,50 @@ assert ( optX != optZ ) ;

    Throws: Nothing.

    +
    +
    +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>().

    +

    void swap ( optional<T>& x, optional<T>& y );

    Effect: If both x and y are initialized, calls swap(*x,*y) using std::swap.
    -If only one is initialized, say x, calls: y.reset(*x); x.reset();
    +If only one is initialized, say x, calls: y = *x; x = boost:none;
    If none is initialized, does nothing.

    Postconditions: The states of x and y interchanged.

    Throws: If both are initialized, whatever swap(T&,T&) throws. @@ -1169,7 +1310,7 @@ If only one is initialized, whatever T::T ( T const& ) throws.

    If only one is initialized, T::~T() and T::T( T const& ) is called.

    Exception Safety: If both are initialized, this operation has the exception safety guarantees of swap(T&,T&).
    -If only one is initialized, it has the same basic guarantee as optional<T>::reset( T const& ).

    +If only one is initialized, it has the same basic guarantee as optional<T>::operator=( T const& ).

    Example:

    T x(12);
    @@ -1219,12 +1360,12 @@ void receive_async_message()
     
    optional<string> name ;
     if ( database.open() )
     {
    -  name.reset ( database.lookup(employer_name) ) ;
    +  name = database.lookup(employer_name) ;
     }
     else
     {
       if ( can_ask_user )
    -    name.reset ( user.ask(employer_name) ) ;
    +    name = user.ask(employer_name) ;
     }
     
     if ( name )
    @@ -1245,7 +1386,7 @@ else print("employer's name not found!");
         void clip_in_rect ( rect const& rect )
           {
              ....
    -         m_clipping_rect.reset ( rect ) ; // initialized here.
    +         m_clipping_rect = rect ; // initialized here.
           }
     
         void draw ( canvas& cvs )
    @@ -1289,16 +1430,17 @@ some operations are not available in this case:

  • Converting assignment
  • InPlace construction
  • InPlace assignment
  • -
  • Value-access via pointer
  • 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&> will copy the references but all these references +
    • Copies of optional<T&> copies the reference, but all copied references will nonetheless reefer to the same object.
    • -
    • Value-access will actually provide access to the referenced object rather +
    • Value-access provides access to the referenced object rather than the reference itself.
    • +
    • Pointer-access provides a pointer to the referenced object rather + than a pointer to the reference itself.

    @@ -1309,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); 
    @@ -1320,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' @@ -1346,38 +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 
    +
    + +
    + +

    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 ;
    +
     
    -

    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;  

    @@ -1506,9 +1678,8 @@ public: the maybe state represents a valid value, unlike the corresponding state of an uninitialized optional<bool>.
    It should be carefully considered if an optional<bool> instead of a tribool is really needed

    -

    Second, optional<> provides an implicit conversion to bool. This conversion - refers to the initialization state and not to the contained value.
    -Using optional<bool> can lead to subtle errors due to the implicit bool conversion:

    +

    Second, optional<> provides a simple way to test initialization state: an implicit conversion to a type that evaluates as a 'bool' in a boolean context.
    +Using optional<bool> can lead to subtle errors due to this implicit conversion:

    void foo ( bool v ) ;
     void bar()
     {
    @@ -1524,7 +1695,9 @@ void bar()
     integral promotions don't apply (i.e. if foo() takes an 'int' instead, it won't compile). 

    Exception Safety Guarantees

    -

    Assignment and Reset:

    + +

    Assignment:

    +

    IMPORTANT NOTE: This changed in 1.33.1 with respect to previous versions

    Because of the current implementation (see Implementation Notes), all of the assignment methods:

      @@ -1537,60 +1710,17 @@ of the assignment methods:

      InPlaceFactory const& )
    • template<class TypedInPlaceFactory> optional<T>::operator= ( TypedInPlaceFactory const& )
    • -
    • optional<T>:::reset ( T const&)
    -

    Can only guarantee the basic exception safety: The lvalue optional is left uninitialized if an exception is thrown (any previous value is first destroyed using T::~T())

    +

    cannot offer any exception safety guarantee beyond that provided by T::operator=( T const& )

    On the other hand, the uninitializing methods:

    • optional<T>::operator= ( detail::none_t )
    • -
    • optional<T>::reset()
    -

    Provide the no-throw guarantee (assuming a no-throw T::~T())

    -

    However, since optional<> itself doesn't throw any exceptions, -the only source for exceptions here are T's constructor, so if you know the exception guarantees -for T::T ( T const& ), you know that optional's assignment and reset has the same guarantees.

    -
    //
    -// Case 1: Exception thrown during assignment.
    -//
    -T v0(123);
    -optional<T> opt0(v0);
    -try
    -{
    -  T v1(456);
    -  optional<T> opt1(v1);
    -  opt0 = opt1 ;
    +

    Provides the no-throw guarantee (assuming a no-throw T::~T()) becuse it only destroys the stored object.

    -  // If no exception was thrown, assignment succeeded. -  assert( *opt0 == v1 ) ; -} -catch(...) -{ -  // If any exception was thrown, 'opt0' is reset to uninitialized. -  assert( !opt0 ) ; -} - -// -// Case 2: Exception thrown during reset(v) -// -T v0(123); -optional<T> opt(v0); -try -{ -  T v1(456); -  opt.reset ( v1 ) ; - -  // If no exception was thrown, reset succeeded. -  assert( *opt == v1 ) ; -} -catch(...) -{ -  // If any exception was thrown, 'opt' is reset to uninitialized. -  assert( !opt ) ; -} -

    Swap:

    void swap( optional<T>&, optional<T>& ) has the same exception guarantee as swap(T&,T&) when both optionals are initialized.
    -If only one of the optionals is initialized, it gives the same basic exception guarantee as optional<T>::reset( T const& ) (since optional<T>::reset() doesn't throw).
    +If only one of the optionals is initialized, it gives the same exception guarantee as T::operator=( T const& ) (since optional<T>::operator=( none_t ) doesn't throw).
    If none of the optionals is initialized, it has no-throw guarantee since it is a no-op.


    @@ -1604,14 +1734,11 @@ T is not required to be Implementation Notes

    optional<T> is currently implemented - using a custom aligned storage facility built from alignment_of and type_with_alignment (both from Type Traits). - It uses a separate boolean flag to indicate the initialization state.
    - Placement new with T's copy constructor and T's destructor - are explicitly used to initialize,copy and destroy optional values.
    - As a result, T's default constructor is effectively by-passed, but the exception - guarantees are basic.
    - It is planned to replace the current implementation with another with - stronger exception safety, such as a future boost::variant.

    + using a custom aligned storage facility built from alignment_of and type_with_alignment (both from Type Traits). + It uses a separate boolean flag to indicate the initialization state.

    +

    Placement new with T's copy constructor and T's destructor + is explicitly used to initialize and destroy optional values. This allows T's default constructor to be effectively by-passed.

    +

    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


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

    Developed by Fernando Cacciola, the latest version of this file can be found at www.boost.org, and the boost discussion lists

    - + \ No newline at end of file diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d20cd84..16d4f3c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -22,11 +22,9 @@ import testing ; [ run optional_test_inplace.cpp ] [ run optional_test_io.cpp ] [ compile-fail optional_test_fail1.cpp ] - [ compile-fail optional_test_fail2.cpp ] [ compile-fail optional_test_fail3a.cpp ] [ compile-fail optional_test_fail3b.cpp ] [ compile-fail optional_test_ref_fail1.cpp ] - [ compile-fail optional_test_ref_fail2.cpp ] [ compile-fail optional_test_ref_fail3.cpp ] [ compile-fail optional_test_ref_fail4.cpp ] [ compile-fail optional_test_inplace_fail.cpp ] diff --git a/test/optional_test.cpp b/test/optional_test.cpp index 5c10eed..02ed181 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -704,16 +704,16 @@ void test_relops( T const* ) { TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - T v0(18); - T v1(19); - T v2(19); + T v0(0); + T v1(1); + T v2(1); optional def0 ; optional def1 ; optional opt0(v0); optional opt1(v1); optional opt2(v2); - + // Check identity BOOST_CHECK ( def0 == def0 ) ; BOOST_CHECK ( opt0 == opt0 ) ; @@ -751,6 +751,33 @@ void test_relops( T const* ) BOOST_CHECK ( opt1 > opt0 ) ; BOOST_CHECK ( opt1 <= opt2 ) ; BOOST_CHECK ( opt1 >= opt0 ) ; + + // Compare against a value directly + BOOST_CHECK ( opt0 == v0 ) ; + BOOST_CHECK ( opt0 != v1 ) ; + BOOST_CHECK ( opt1 == v2 ) ; + BOOST_CHECK ( opt0 < v1 ) ; + BOOST_CHECK ( opt1 > v0 ) ; + BOOST_CHECK ( opt1 <= v2 ) ; + BOOST_CHECK ( opt1 >= v0 ) ; + BOOST_CHECK ( v0 != opt1 ) ; + BOOST_CHECK ( v1 == opt2 ) ; + BOOST_CHECK ( v0 < opt1 ) ; + BOOST_CHECK ( v1 > opt0 ) ; + BOOST_CHECK ( v1 <= opt2 ) ; + BOOST_CHECK ( v1 >= opt0 ) ; + BOOST_CHECK ( def0 != v0 ) ; + BOOST_CHECK ( !(def0 == v0) ) ; + BOOST_CHECK ( def0 < v0 ) ; + BOOST_CHECK ( !(def0 > v0) ) ; + BOOST_CHECK ( def0 <= v0 ) ; + BOOST_CHECK ( !(def0 >= v0) ) ; + BOOST_CHECK ( v0 != def0 ) ; + BOOST_CHECK ( !(v0 == def0) ) ; + BOOST_CHECK ( !(v0 < def0) ) ; + BOOST_CHECK ( v0 > def0 ) ; + BOOST_CHECK ( !(v0 <= def0) ) ; + BOOST_CHECK ( v0 >= opt0 ) ; } template @@ -767,6 +794,10 @@ void test_none( T const* ) BOOST_CHECK ( def0 == none ) ; BOOST_CHECK ( non_def != none ) ; BOOST_CHECK ( !def1 ) ; + BOOST_CHECK ( !(non_def < none) ) ; + BOOST_CHECK ( non_def > none ) ; + BOOST_CHECK ( !(non_def <= none) ) ; + BOOST_CHECK ( non_def >= none ) ; non_def = none ; BOOST_CHECK ( !non_def ) ; @@ -774,6 +805,24 @@ void test_none( T const* ) test_default_implicit_construction(T(1),none); } +template +void test_arrow( T const* ) +{ + TRACE( std::endl << BOOST_CURRENT_FUNCTION ); + + T a(1234); + + optional oa(a) ; + optional const coa(a) ; + + BOOST_CHECK ( coa->V() == 1234 ) ; + + oa->V() = 4321 ; + + BOOST_CHECK ( a.V() = 1234 ) ; + BOOST_CHECK ( (*oa).V() = 4321 ) ; +} + void test_with_builtin_types() { TRACE( std::endl << BOOST_CURRENT_FUNCTION ); @@ -804,6 +853,7 @@ void test_with_class_type() test_throwing_swap( ARG(X) ); test_relops( ARG(X) ) ; test_none( ARG(X) ) ; + test_arrow( ARG(X) ) ; BOOST_CHECK ( X::count == 0 ) ; } diff --git a/test/optional_test_ref.cpp b/test/optional_test_ref.cpp index 1ccaeb4..91149ba 100644 --- a/test/optional_test_ref.cpp +++ b/test/optional_test_ref.cpp @@ -299,6 +299,23 @@ void test_none( T const* ) BOOST_CHECK ( !non_def ) ; } +template +void test_arrow( T const* ) +{ + TRACE( std::endl << BOOST_CURRENT_FUNCTION ); + + T a(1234); + + optional oa(a) ; + optional const coa(a) ; + + BOOST_CHECK ( coa->V() == 1234 ) ; + + oa->V() = 4321 ; + + BOOST_CHECK ( a.V() = 4321 ) ; +} + void test_with_builtin_types() { TRACE( std::endl << BOOST_CURRENT_FUNCTION ); @@ -315,6 +332,7 @@ void test_with_class_type() test_basics( ARG(X) ); test_relops( ARG(X) ) ; test_none ( ARG(X) ) ; + test_arrow ( ARG(X) ) ; BOOST_CHECK ( X::count == 0 ) ; } diff --git a/test/optional_test_ref_fail2.cpp b/test/optional_test_ref_fail2.cpp deleted file mode 100644 index 732c995..0000000 --- a/test/optional_test_ref_fail2.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void optional_reference__test_no_ptr_access() -{ - boost::optional opt ; - opt.get_ptr(); -} - - From 3499d477dcce68d7b055c9a7e4a162336b57029a Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Fri, 2 Nov 2007 22:56:23 +0000 Subject: [PATCH 10/15] Merged changests from RC_1_34_0 - base rev 33417 [SVN r40705] --- include/boost/optional/optional.hpp | 133 ++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 18 deletions(-) diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 8a78a40..42277ba 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -26,7 +26,7 @@ #include "boost/mpl/bool.hpp" #include "boost/mpl/not.hpp" #include "boost/detail/reference_content.hpp" -#include "boost/none_t.hpp" +#include "boost/none.hpp" #include "boost/utility/compare_pointees.hpp" #include "boost/optional/optional_fwd.hpp" @@ -76,6 +76,19 @@ #define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION #endif +// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<> +// member template of a factory as used in the optional<> implementation. +// He proposed this simple fix which is to move the call to apply<> outside +// namespace boost. +namespace boost_optional_detail +{ + template + void construct(Factory const& factory, void* address) + { + factory.BOOST_NESTED_TEMPLATE apply(address); + } +} + namespace boost { @@ -173,7 +186,7 @@ class optional_base : public optional_tag // Creates an optional uninitialized. // No-throw - optional_base ( none_t const& ) + optional_base ( none_t ) : m_initialized(false) {} @@ -266,7 +279,7 @@ class optional_base : public optional_tag // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED // No-throw (assuming T::~T() doesn't) - void assign ( none_t const& ) { destroy(); } + void assign ( none_t ) { destroy(); } #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT template @@ -309,7 +322,7 @@ class optional_base : public optional_tag void construct ( Expr const& factory, in_place_factory_base const* ) { BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ; - factory.BOOST_NESTED_TEMPLATE apply(m_storage.address()) ; + boost_optional_detail::construct(factory, m_storage.address()); m_initialized = true ; } @@ -428,6 +441,8 @@ class optional_base : public optional_tag // the following olverloads are used to filter out the case and guarantee an error in case of T being a reference. pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; } pointer_type cast_ptr( internal_type * p, is_not_reference_tag ) { return p ; } + pointer_const_type cast_ptr( internal_type const* p, is_reference_tag ) const { return &p->get() ; } + pointer_type cast_ptr( internal_type * p, is_reference_tag ) { return &p->get() ; } bool m_initialized ; storage_type m_storage ; @@ -459,7 +474,7 @@ class optional : public optional_detail::optional_base // Creates an optional uninitialized. // No-throw - optional( none_t const& none_ ) : base(none_) {} + optional( none_t none_ ) : base(none_) {} // Creates an optional initialized with 'val'. // Can throw if T::T(T const&) does @@ -550,7 +565,7 @@ class optional : public optional_detail::optional_base // Assigns from a "none" // Which destroys the current value, if any, leaving this UNINITIALIZED // No-throw (assuming T::~T() doesn't) - optional& operator= ( none_t const& none_ ) + optional& operator= ( none_t none_ ) { this->assign( none_ ) ; return *this ; @@ -678,6 +693,11 @@ get_pointer ( optional& opt ) // optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values). // WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead. + +// +// optional vs optional cases +// + template inline bool operator == ( optional const& x, optional const& y ) @@ -708,64 +728,141 @@ inline bool operator >= ( optional const& x, optional const& y ) { return !( x < y ) ; } + +// +// optional vs T cases +// template inline -bool operator == ( optional const& x, none_t const& ) +bool operator == ( optional const& x, T const& y ) +{ return equal_pointees(x, optional(y)); } + +template +inline +bool operator < ( optional const& x, T const& y ) +{ return less_pointees(x, optional(y)); } + +template +inline +bool operator != ( optional const& x, T const& y ) +{ return !( x == y ) ; } + +template +inline +bool operator > ( optional const& x, T const& y ) +{ return y < x ; } + +template +inline +bool operator <= ( optional const& x, T const& y ) +{ return !( y < x ) ; } + +template +inline +bool operator >= ( optional const& x, T const& y ) +{ return !( x < y ) ; } + +// +// T vs optional cases +// + +template +inline +bool operator == ( T const& x, optional const& y ) +{ return equal_pointees( optional(x), y ); } + +template +inline +bool operator < ( T const& x, optional const& y ) +{ return less_pointees( optional(x), y ); } + +template +inline +bool operator != ( T const& x, optional const& y ) +{ return !( x == y ) ; } + +template +inline +bool operator > ( T const& x, optional const& y ) +{ return y < x ; } + +template +inline +bool operator <= ( T const& x, optional const& y ) +{ return !( y < x ) ; } + +template +inline +bool operator >= ( T const& x, optional const& y ) +{ return !( x < y ) ; } + + +// +// optional vs none cases +// + +template +inline +bool operator == ( optional const& x, none_t ) { return equal_pointees(x, optional() ); } template inline -bool operator < ( optional const& x, none_t const& ) +bool operator < ( optional const& x, none_t ) { return less_pointees(x,optional() ); } template inline -bool operator != ( optional const& x, none_t const& y ) +bool operator != ( optional const& x, none_t y ) { return !( x == y ) ; } template inline -bool operator > ( optional const& x, none_t const& y ) +bool operator > ( optional const& x, none_t y ) { return y < x ; } template inline -bool operator <= ( optional const& x, none_t const& y ) +bool operator <= ( optional const& x, none_t y ) { return !( y < x ) ; } template inline -bool operator >= ( optional const& x, none_t const& y ) +bool operator >= ( optional const& x, none_t y ) { return !( x < y ) ; } +// +// none vs optional cases +// + template inline -bool operator == ( none_t const& x, optional const& y ) +bool operator == ( none_t x, optional const& y ) { return equal_pointees(optional() ,y); } template inline -bool operator < ( none_t const& x, optional const& y ) +bool operator < ( none_t x, optional const& y ) { return less_pointees(optional() ,y); } template inline -bool operator != ( none_t const& x, optional const& y ) +bool operator != ( none_t x, optional const& y ) { return !( x == y ) ; } template inline -bool operator > ( none_t const& x, optional const& y ) +bool operator > ( none_t x, optional const& y ) { return y < x ; } template inline -bool operator <= ( none_t const& x, optional const& y ) +bool operator <= ( none_t x, optional const& y ) { return !( y < x ) ; } template inline -bool operator >= ( none_t const& x, optional const& y ) +bool operator >= ( none_t x, optional const& y ) { return !( x < y ) ; } // From 06ba35cd42e87475a57a8d0290060f1b27248401 Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Fri, 2 Nov 2007 23:06:42 +0000 Subject: [PATCH 11/15] Fixed error reported by Edward Diener [SVN r40706] --- doc/optional.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/optional.html b/doc/optional.html index e216db5..b9ef36b 100644 --- a/doc/optional.html +++ b/doc/optional.html @@ -331,9 +331,9 @@ class optional template<class U> explicit optional ( optional<U> const& rhs ) ; - template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ; + template<InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ; - template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ; + template<TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ; optional& operator = ( none_t ) ; @@ -343,9 +343,9 @@ class optional template<class U> optional& operator = ( optional<U> const& rhs ) ; - template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ; + template<InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ; - template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ; + template<TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ; T const& get() const ; T& get() ; From 3b5b5d82a02f14feef7bb970c0728aa56d41f3de Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Fri, 2 Nov 2007 23:41:37 +0000 Subject: [PATCH 12/15] Added test to ensure proper binding of optional references (in reference to Ticket 1301) [SVN r40707] --- test/optional_test_ref.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/optional_test_ref.cpp b/test/optional_test_ref.cpp index 91149ba..2e7f3bf 100644 --- a/test/optional_test_ref.cpp +++ b/test/optional_test_ref.cpp @@ -337,12 +337,30 @@ void test_with_class_type() BOOST_CHECK ( X::count == 0 ) ; } +void test_binding() +{ + int i = 0 ; + optional ori1 = i ; + BOOST_CHECK( &(*ori1) == &i ) ; + + optional ori2(i) ; + BOOST_CHECK( &(*ori2) == &i ) ; + + int const ci = 0 ; + optional orci1 = ci ; + BOOST_CHECK( &(*orci1) == &ci ) ; + + optional orci2 = ci ; + BOOST_CHECK( &(*orci2) == &ci ) ; +} + int test_main( int, char* [] ) { try { test_with_class_type(); test_with_builtin_types(); + test_binding(); } catch ( ... ) { From 05a685b035159a0649187a26bd323deed623ebd6 Mon Sep 17 00:00:00 2001 From: Fernando Cacciola Date: Tue, 6 Nov 2007 22:21:43 +0000 Subject: [PATCH 13/15] Fixed intention in the added binding test [SVN r40860] --- test/optional_test_ref.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/optional_test_ref.cpp b/test/optional_test_ref.cpp index 2e7f3bf..08ee87e 100644 --- a/test/optional_test_ref.cpp +++ b/test/optional_test_ref.cpp @@ -350,7 +350,7 @@ void test_binding() optional orci1 = ci ; BOOST_CHECK( &(*orci1) == &ci ) ; - optional orci2 = ci ; + optional orci2(ci) ; BOOST_CHECK( &(*orci2) == &ci ) ; } From f6518df0c4fe924f73761d579f0fba23a449a6b2 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Thu, 15 Nov 2007 15:20:27 +0000 Subject: [PATCH 14/15] Get rid of .cvsignore files [SVN r41107] --- test/.cvsignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 test/.cvsignore diff --git a/test/.cvsignore b/test/.cvsignore deleted file mode 100644 index ba077a4..0000000 --- a/test/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -bin From 9afdbe65e70e2d0308abe0575d6585885769b62c Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sat, 17 Nov 2007 20:13:16 +0000 Subject: [PATCH 15/15] // Add or correct comment identifying Boost library this header is associated with. [SVN r41173] --- include/boost/none.hpp | 2 +- include/boost/none_t.hpp | 2 +- include/boost/optional.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/none.hpp b/include/boost/none.hpp index b0e94a2..bd342da 100644 --- a/include/boost/none.hpp +++ b/include/boost/none.hpp @@ -4,7 +4,7 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional/ for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com diff --git a/include/boost/none_t.hpp b/include/boost/none_t.hpp index 4b97e20..63ad926 100644 --- a/include/boost/none_t.hpp +++ b/include/boost/none_t.hpp @@ -4,7 +4,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com diff --git a/include/boost/optional.hpp b/include/boost/optional.hpp index bc5c5d3..40cf12e 100644 --- a/include/boost/optional.hpp +++ b/include/boost/optional.hpp @@ -4,7 +4,7 @@ // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// See http://www.boost.org/lib/optional for documentation. +// See http://www.boost.org/libs/optional for documentation. // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com