From 07ce2fc860c7302f548a9186e9064b22f6e31cd0 Mon Sep 17 00:00:00 2001 From: Matias Capeletto Date: Tue, 29 May 2007 06:40:25 +0000 Subject: [PATCH] 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] + +