diff --git a/doc/00_optional.qbk b/doc/00_optional.qbk index 7a63714..9cceee1 100644 --- a/doc/00_optional.qbk +++ b/doc/00_optional.qbk @@ -45,7 +45,7 @@ Distributed under the Boost Software License, Version 1.0. [def __GO_TO__ [$images/callouts/R.png]] -[heading Introduction] +[section Introduction] Class template `optional` is a wrapper for representing 'optional' (or 'nullable') objects who may not (yet) contain a valid value. Optional objects offer full value semantics; they are good for passing by value and usage inside STL containers. This is a header-only library. [heading Problem] @@ -67,7 +67,7 @@ This is how you solve it with `boost::optional`: runWithNoMax(); } - +[endsect] [include 01_quick_start.qbk] [section Tutorial] diff --git a/doc/01_quick_start.qbk b/doc/01_quick_start.qbk index 53a8e67..2b642df 100644 --- a/doc/01_quick_start.qbk +++ b/doc/01_quick_start.qbk @@ -12,7 +12,7 @@ [section Quick Start] -[heading Optional return values] +[section Optional return values] Let's write and use a converter function that converts an a `std::string` to an `int`. It is possible that for a given string (e.g. `"cat"`) there exist no value of type `int` capable of representing the conversion result. We do not consider such situation an error. We expect that the converter can be used only to check if the conversion is possible. A natural signature for this function can be: @@ -62,9 +62,9 @@ This uses the `atoi`-like approach to conversions: if `text` does not represent Observe the two return statements. `return i` uses the converting constructor that can create `optional` from `T`. Thus constructed optional object is initialized and its value is a copy of `i`. The other return statement uses another converting constructor from a special tag `boost::none`. It is used to indicate that we want to create an uninitialized optional object. -[/endsect] +[endsect] -[heading Optional automatic variables] +[section Optional automatic variables] We could write function `convert` in a slightly different manner, so that it has a single `return`-statement: @@ -80,9 +80,9 @@ We could write function `convert` in a slightly different manner, so that it has } The default constructor of `optional` creates an unitialized optional object. Unlike with `int`s you cannot have an `optional` in an indeterminate state. Its state is always well defined. Instruction `ans = i` initializes the optional object. It uses the assignment from `int`. In general, for `optional`, when an assignment from `T` is invoked, it can do two things. If the optional object is not initialized our case here), it initializes it with `T`'s copy constructor. If the optional object is already initialized, it assigns the new value to it using `T`'s copy assignment. -[/endsect] +[endsect] -[heading Optional data members] +[section Optional data members] Suppose we want to implement a ['lazy load] optimization. This is because we do not want to perform an expensive initialization of our `Resource` until (if at all) it is really used. We can do it this way: @@ -106,9 +106,9 @@ Suppose we want to implement a ['lazy load] optimization. This is because we do [note Function `emplace` is only available on compilers that support rvalue references and variadic templates. If your compiler does not support these features and you still need to avoid any move-constructions, use [link boost_optional.tutorial.in_place_factories In-Place Factories].] -[/endsect] +[endsect] -[heading Bypassing unnecessary default construction] +[section Bypassing unnecessary default construction] Suppose we have class `Date`, which does not have a default constructor: there is no good candidate for a default date. We have a function that returns two dates in form of a `boost::tuple`: @@ -125,9 +125,9 @@ The second line works already, this is the capability of Boost.Tuple library, bu boost::tie(begin, end) = getPeriod(); It works because inside `boost::tie` a move-assignment from `T` is invoked on `optional`, which internally calls a move-constructor of `T`. -[/endsect] +[endsect] -[heading Storage in containers] +[section Storage in containers] Suppose you want to ask users to choose some number (an `int`). One of the valid responses is to choose nothing, which is represented by an uninitialized `optional`. You want to make a histogram showing how many times each choice was made. You can use an `std::map`: @@ -139,7 +139,7 @@ Suppose you want to ask users to choose some number (an `int`). One of the valid } This works because `optional` is `LessThanComparable` whenever `T` is `LessThanComparable`. In this case the state of being uninitialized is treated as a yet another value of `T`, which is compared less than any value of `T`. So the set of values that type `optional` can assume is {`boost::none`, -2147483648, -2147483647, ..., -1, 0, 1, ..., 2147483647} (assuming a 32-bit `int`). -[/endsect] +[endsect] [endsect] diff --git a/doc/90_dependencies.qbk b/doc/90_dependencies.qbk index fce4ca8..cf678dc 100644 --- a/doc/90_dependencies.qbk +++ b/doc/90_dependencies.qbk @@ -11,8 +11,22 @@ [section Dependencies and Portability] -The implementation uses `type_traits/alignment_of.hpp` and -`type_traits/type_with_alignment.hpp` +[section Dependencies] +The implementation uses the following other Boost modules: + +# assert +# config +# core +# detail +# move +# mpl +# static_assert +# throw_exception +# type_traits +# utility + +[endsect] + [section Optional Reference Binding] diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 2a8b727..b6f4a79 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -25,10 +25,11 @@ boostbook standalone optional : boost.root=../../../.. - toc.max.depth=2 + chapter.autolabel=0 + chunk.section.depth=8 toc.section.depth=2 - chunk.first.sections=2 - chunk.section.depth=2 + toc.max.depth=2 + generate.section.toc.level=1 pdf:img.src.path=$(images)/ pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/optional/doc/html ; diff --git a/doc/html/boost_optional/acknowledgments.html b/doc/html/boost_optional/acknowledgments.html index 19d24d9..b09cf6e 100644 --- a/doc/html/boost_optional/acknowledgments.html +++ b/doc/html/boost_optional/acknowledgments.html @@ -4,8 +4,8 @@ Acknowledgments - - + + diff --git a/doc/html/boost_optional/dependencies_and_portability.html b/doc/html/boost_optional/dependencies_and_portability.html index d9f62c1..b99d3b1 100644 --- a/doc/html/boost_optional/dependencies_and_portability.html +++ b/doc/html/boost_optional/dependencies_and_portability.html @@ -4,8 +4,8 @@ Dependencies and Portability - - + + @@ -27,12 +27,51 @@ Dependencies and Portability - + +
+

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

+ The implementation uses the following other Boost modules: +

+
    +
  1. + assert +
  2. +
  3. + config +
  4. +
  5. + core +
  6. +
  7. + detail +
  8. +
  9. + move +
  10. +
  11. + mpl +
  12. +
  13. + static_assert +
  14. +
  15. + throw_exception +
  16. +
  17. + type_traits +
  18. +
  19. + utility +
  20. +
+
diff --git a/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html b/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html index 70316bc..991a0cf 100644 --- a/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html +++ b/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html @@ -4,7 +4,7 @@ Optional Reference Binding - + diff --git a/doc/html/boost_optional/quick_start.html b/doc/html/boost_optional/quick_start.html index 5434009..e8cc11b 100644 --- a/doc/html/boost_optional/quick_start.html +++ b/doc/html/boost_optional/quick_start.html @@ -4,10 +4,10 @@ Quick Start - - - - + + + +
@@ -20,65 +20,78 @@

-PrevUpHomeNext +PrevUpHomeNext

- Let's write and use a converter function that converts an a std::string - to an int. It is possible that - for a given string (e.g. "cat") - there exist no value of type int - capable of representing the conversion result. We do not consider such situation - an error. We expect that the converter can be used only to check if the conversion - is possible. A natural signature for this function can be: -

+ Let's write and use a converter function that converts an a std::string + to an int. It is possible that + for a given string (e.g. "cat") + there exist no value of type int + capable of representing the conversion result. We do not consider such situation + an error. We expect that the converter can be used only to check if the conversion + is possible. A natural signature for this function can be: +

#include <boost/optional.hpp>
 boost::optionl<int> convert(const std::string& text);
 

- All necessary functionality can be included with one header <boost/optional.hpp>. - The above function signature means that the function can either return a value - of type int or a flag indicating - that no value of int is available. - This does not indicate an error. It is like one additional value of int. This is how we can use our function: -

+ All necessary functionality can be included with one header <boost/optional.hpp>. + The above function signature means that the function can either return a + value of type int or a flag + indicating that no value of int + is available. This does not indicate an error. It is like one additional + value of int. This is how we + can use our function: +

const std::string& text = /*... */;
 boost::optionl<int> oi = convert(text); // move-construct
 if (oi)                                 // contextual conversion to bool
   int i = *oi;                          // operator*
 

- In order to test if optional - contains a value, we use the contextual conversion to type bool. - Because of this we can combine the initialization of the optional object and - the test into one instruction: -

+ In order to test if optional + contains a value, we use the contextual conversion to type bool. Because of this we can combine the initialization + of the optional object and the test into one instruction: +

if (boost::optionl<int> oi = convert(text))
   int i = *oi;
 

- We extract the contained value with operator* (and with operator-> where it makes sense). An attempt to extract - the contained value of an uninitialized optional object is an undefined - behaviour (UB). This implementation guards the call with BOOST_ASSERT. Therefore you should be sure - that the contained value is there before extracting. For instance, the following - code is reasonably UB-safe: -

+ We extract the contained value with operator* (and with operator-> where it makes sense). An attempt to + extract the contained value of an uninitialized optional object is an undefined + behaviour (UB). This implementation guards the call with BOOST_ASSERT. Therefore you should be sure + that the contained value is there before extracting. For instance, the following + code is reasonably UB-safe: +

int i = *convert("100");
 

- This is because we know that string value "100" - converts to a valid value of int. - If you do not like this potential UB, you can use an alternative way of extracting - the contained value: -

+ This is because we know that string value "100" + converts to a valid value of int. + If you do not like this potential UB, you can use an alternative way of extracting + the contained value: +

try {
   int j = convert(text).value();
 }
@@ -87,20 +100,20 @@
 }
 

- This version throws an exception upon an attempt to access a non-existent contained - value. If your way of dealing with the missing value is to use some default, - like 0, there exists a yet another - alternative: -

+ This version throws an exception upon an attempt to access a non-existent + contained value. If your way of dealing with the missing value is to use + some default, like 0, there exists + a yet another alternative: +

int k = convert(text).value_or(0);
 

- This uses the atoi-like approach - to conversions: if text does - not represent an integral number just return 0. - Now, let's consider how function convert - can be implemented. -

+ This uses the atoi-like approach + to conversions: if text does + not represent an integral number just return 0. + Now, let's consider how function convert + can be implemented. +

boost::optionl<int> convert(const std::string& text)
 {
   std::stringstream s(text);
@@ -112,168 +125,16 @@
 }
 

- Observe the two return statements. return - i uses the converting constructor - that can create optional<T> from - T. Thus constructed optional - object is initialized and its value is a copy of i. - The other return statement uses another converting constructor from a special - tag boost::none. It is used to indicate that we want - to create an uninitialized optional object. -

-

- - Optional - automatic variables -

-

- We could write function convert - in a slightly different manner, so that it has a single return-statement: -

-
boost::optionl<int> convert(const std::string& text)
-{
-  boost::optionl<int> ans;
-  std::stringstream s(text);
-  int i;
-  if ((s >> i) && s.get() == std::char_traits<char>::eof())
-    ans = i;
-
-  return ans;
-}
-
-

- The default constructor of optional - creates an unitialized optional object. Unlike with ints - you cannot have an optional<int> - in an indeterminate state. Its state is always well defined. Instruction ans = i - initializes the optional object. It uses the assignment from int. In general, for optional<T>, - when an assignment from T is - invoked, it can do two things. If the optional object is not initialized our - case here), it initializes it with T's - copy constructor. If the optional object is already initialized, it assigns - the new value to it using T's - copy assignment. -

-

- - Optional - data members -

-

- Suppose we want to implement a lazy load optimization. - This is because we do not want to perform an expensive initialization of our - Resource until (if at all) - it is really used. We can do it this way: -

-
class Widget
-{
-  boost::optional<Resource> resource_;
-
-public:
-  Widget() {}
-
-  Resource& getResource() // not thread-safe
-  {
-    if (resource_ == boost::none)
-        resource_.emplace("resource", "arguments");
-
-    return *resource_;
-  }
-};
-
-

- optional's default constructor - creates an uninitialized optional. No call to Resource's - default constructor is attempted. Resource - doesn't have to be Default - Constructible. In function getResource - we first check if resource_ - is initialized. This time we do not use the contextual conversion to bool, but a comparison with boost::none. These - two ways are equivalent. Function emplace - initializes the optional in-place by perfect-forwarding the arguments to the - constructor of Resource. No - copy- or move-construction is involved here. Resource - doesn't even have to be MoveConstructible. -

-
- - - - - -
[Note]Note

- Function emplace is only - available on compilers that support rvalue references and variadic templates. - If your compiler does not support these features and you still need to avoid - any move-constructions, use In-Place - Factories. -

-

- - Bypassing - unnecessary default construction -

-

- Suppose we have class Date, - which does not have a default constructor: there is no good candidate for a - default date. We have a function that returns two dates in form of a boost::tuple: -

-
boost::tuple<Date, Date> getPeriod();
-
-

- In other place we want to use the result of getPeriod, - but want the two dates to be named: begin - and end. We want to implement - something like 'multiple return values': -

-
Date begin, end; // Error: no default ctor!
-boost::tie(begin, end) = getPeriod();
-
-

- The second line works already, this is the capability of Boost.Tuple library, - but the first line won't work. We could set some invented initial dates, but - it is confusing and may be an unacceptable cost, given that these values will - be overwritten in the next line anyway. This is where optional - can help: -

-
boost::optional<Date> begin, end;
-boost::tie(begin, end) = getPeriod();
-
-

- It works because inside boost::tie a move-assignment - from T is invoked on optional<T>, which - internally calls a move-constructor of T. -

-

- - Storage - in containers -

-

- Suppose you want to ask users to choose some number (an int). - One of the valid responses is to choose nothing, which is represented by an - uninitialized optional<int>. You - want to make a histogram showing how many times each choice was made. You can - use an std::map: -

-
std::map<boost::optional<int>, int> choices;
-
-for (int i = 0; i < LIMIT; ++i) {
-  boost::optional<int> choice = readChoice();
-  ++choices[choice];
-}
-
-

- This works because optional<T> - is LessThanComparable whenever - T is LessThanComparable. - In this case the state of being uninitialized is treated as a yet another value - of T, which is compared less - than any value of T. So the - set of values that type optional<T> - can assume is {boost::none, -2147483648, -2147483647, ..., -1, - 0, 1, ..., 2147483647} (assuming a 32-bit int). -

+ Observe the two return statements. return + i uses the converting constructor + that can create optional<T> + from T. Thus constructed + optional object is initialized and its value is a copy of i. + The other return statement uses another converting constructor from a special + tag boost::none. It is used to indicate that we want + to create an uninitialized optional object. +

+ @@ -285,7 +146,7 @@

-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html b/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html index 33ac25d..844742b 100644 --- a/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html +++ b/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html @@ -4,10 +4,10 @@ Bypassing unnecessary default construction - + - + @@ -20,7 +20,7 @@

-PrevUpHomeNext +PrevUpHomeNext

@@ -69,7 +69,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_optional/quick_start/optional_automatic_variables.html b/doc/html/boost_optional/quick_start/optional_automatic_variables.html index 34c9ac7..f577e11 100644 --- a/doc/html/boost_optional/quick_start/optional_automatic_variables.html +++ b/doc/html/boost_optional/quick_start/optional_automatic_variables.html @@ -4,9 +4,9 @@ Optional automatic variables - + - + @@ -20,7 +20,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -69,7 +69,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_optional/quick_start/optional_data_members.html b/doc/html/boost_optional/quick_start/optional_data_members.html index 00f5457..fe7fd78 100644 --- a/doc/html/boost_optional/quick_start/optional_data_members.html +++ b/doc/html/boost_optional/quick_start/optional_data_members.html @@ -4,7 +4,7 @@ Optional data members - + diff --git a/doc/html/boost_optional/quick_start/storage_in_containers.html b/doc/html/boost_optional/quick_start/storage_in_containers.html new file mode 100644 index 0000000..1715431 --- /dev/null +++ b/doc/html/boost_optional/quick_start/storage_in_containers.html @@ -0,0 +1,69 @@ + + + +Storage in containers + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ Suppose you want to ask users to choose some number (an int). + One of the valid responses is to choose nothing, which is represented by + an uninitialized optional<int>. + You want to make a histogram showing how many times each choice was made. + You can use an std::map: +

+
std::map<boost::optional<int>, int> choices;
+
+for (int i = 0; i < LIMIT; ++i) {
+  boost::optional<int> choice = readChoice();
+  ++choices[choice];
+}
+
+

+ This works because optional<T> + is LessThanComparable whenever + T is LessThanComparable. + In this case the state of being uninitialized is treated as a yet another + value of T, which is compared + less than any value of T. + So the set of values that type optional<T> + can assume is {boost::none, -2147483648, -2147483647, ..., -1, + 0, 1, ..., 2147483647} (assuming a 32-bit int). +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_optional/reference/detailed_semantics.html b/doc/html/boost_optional/reference/detailed_semantics.html index c5e5d9e..2bf9023 100644 --- a/doc/html/boost_optional/reference/detailed_semantics.html +++ b/doc/html/boost_optional/reference/detailed_semantics.html @@ -4,9 +4,9 @@ Detailed Semantics - + - + @@ -20,7 +20,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -1957,7 +1957,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_optional/tutorial/a_note_about_optional_bool_.html b/doc/html/boost_optional/tutorial/a_note_about_optional_bool_.html index 706bf49..ea3618b 100644 --- a/doc/html/boost_optional/tutorial/a_note_about_optional_bool_.html +++ b/doc/html/boost_optional/tutorial/a_note_about_optional_bool_.html @@ -4,7 +4,7 @@ A note about optional<bool> - + diff --git a/doc/html/boost_optional/tutorial/design_overview.html b/doc/html/boost_optional/tutorial/design_overview.html index d2493ce..d6598bc 100644 --- a/doc/html/boost_optional/tutorial/design_overview.html +++ b/doc/html/boost_optional/tutorial/design_overview.html @@ -4,10 +4,10 @@ Design Overview - + - - + + @@ -20,20 +20,12 @@

-PrevUpHomeNext +PrevUpHomeNext
-
-
- -

- 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 nonexistent - 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 nonexistent) 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 contextual 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. -

-
@@ -417,7 +178,7 @@

-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_optional/tutorial/design_overview/the_interface.html b/doc/html/boost_optional/tutorial/design_overview/the_interface.html new file mode 100644 index 0000000..e0c3a31 --- /dev/null +++ b/doc/html/boost_optional/tutorial/design_overview/the_interface.html @@ -0,0 +1,186 @@ + + + +The Interface + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ 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 nonexistent + 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 nonexistent) 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 contextual 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. +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_optional/tutorial/design_overview/the_semantics.html b/doc/html/boost_optional/tutorial/design_overview/the_semantics.html new file mode 100644 index 0000000..5dbc63b --- /dev/null +++ b/doc/html/boost_optional/tutorial/design_overview/the_semantics.html @@ -0,0 +1,121 @@ + + + +The semantics + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

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

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_optional/tutorial/exception_safety_guarantees.html b/doc/html/boost_optional/tutorial/exception_safety_guarantees.html index ede593d..ea3fa8f 100644 --- a/doc/html/boost_optional/tutorial/exception_safety_guarantees.html +++ b/doc/html/boost_optional/tutorial/exception_safety_guarantees.html @@ -4,7 +4,7 @@ Exception Safety Guarantees - + diff --git a/doc/html/boost_optional/tutorial/in_place_factories.html b/doc/html/boost_optional/tutorial/in_place_factories.html index 3d7500a..3c26b05 100644 --- a/doc/html/boost_optional/tutorial/in_place_factories.html +++ b/doc/html/boost_optional/tutorial/in_place_factories.html @@ -4,7 +4,7 @@ In-Place Factories - + diff --git a/doc/html/boost_optional/tutorial/optional_references.html b/doc/html/boost_optional/tutorial/optional_references.html index 77d73f5..0ca70b6 100644 --- a/doc/html/boost_optional/tutorial/optional_references.html +++ b/doc/html/boost_optional/tutorial/optional_references.html @@ -4,9 +4,9 @@ Optional references - + - + @@ -20,7 +20,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -109,7 +109,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html b/doc/html/boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html index b2bd32d..26bbf66 100644 --- a/doc/html/boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html +++ b/doc/html/boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html @@ -4,7 +4,7 @@ Rebinding semantics for assignment of optional references - + diff --git a/doc/html/boost_optional/tutorial/type_requirements.html b/doc/html/boost_optional/tutorial/type_requirements.html index 84959d2..f8501dd 100644 --- a/doc/html/boost_optional/tutorial/type_requirements.html +++ b/doc/html/boost_optional/tutorial/type_requirements.html @@ -4,7 +4,7 @@ Type requirements - + diff --git a/doc/html/index.html b/doc/html/index.html index 0ae3385..30310e9 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -1,10 +1,10 @@ -Chapter 1. Boost.Optional +Boost.Optional - + @@ -21,7 +21,7 @@

-Chapter 1. Boost.Optional

+Boost.Optional

Fernando Luis Cacciola Carballal

@@ -37,10 +37,23 @@ -

- - Introduction -

+
+

- Class template optional is a - wrapper for representing 'optional' (or 'nullable') objects who may not (yet) - contain a valid value. Optional objects offer full value semantics; they are - good for passing by value and usage inside STL containers. This is a header-only - library. -

-

- - Problem -

+ Class template optional is + a wrapper for representing 'optional' (or 'nullable') objects who may not (yet) + contain a valid value. Optional objects offer full value semantics; they are + good for passing by value and usage inside STL containers. This is a header-only + library. +

+

+ + Problem +

- Suppose we want to read a parameter form a config file which represents some - integral value, let's call it "MaxValue". - It is possible that this parameter is not specified; such situation is no error. - It is valid to not specify the parameter and in that case the program is supposed - to behave slightly different. Also suppose that any possible value of type int is a valid value for "MaxValue", - so we cannot jut use -1 - to represent the absence of the parameter in the config file. -

-

- - Solution -

+ Suppose we want to read a parameter form a config file which represents some + integral value, let's call it "MaxValue". + It is possible that this parameter is not specified; such situation is no error. + It is valid to not specify the parameter and in that case the program is supposed + to behave slightly different. Also suppose that any possible value of type + int is a valid value for "MaxValue", so we cannot jut use -1 to represent + the absence of the parameter in the config file. +

+

+ + Solution +

- This is how you solve it with boost::optional: -

+ This is how you solve it with boost::optional: +

#include <boost/optional.hpp>
 
 boost::optional<int> getConfigParam(std::string name);  // return either an int or a `not-an-int`
@@ -111,8 +127,9 @@
 }
 
+
- +

Last revised: June 04, 2014 at 21:00:26 GMT

Last revised: June 05, 2014 at 22:46:34 GMT


diff --git a/doc/html/optional/introduction.html b/doc/html/optional/introduction.html deleted file mode 100644 index 8f63804..0000000 --- a/doc/html/optional/introduction.html +++ /dev/null @@ -1,82 +0,0 @@ - - - -Introduction - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Class template optional is - a wrapper for representing 'optional' (or 'nullable') objects who may not (yet) - contain a valid value. Optional objects offer full value semantics; they are - good for passing by value and usage inside STL containers. This is a header-only - library. -

-

- - Problem -

-

- Suppose we want to read a parameter form a config file which represents some - integral value, let's call it "MaxValue". - It is possible that this parameter is not specified; such situation is no error. - It is valid to not specify the parameter and in that case the program is supposed - to behave slightly different. Also suppose that any possible value of type - int is a valid value for "MaxValue", so we cannot jut use -1 to represent - the absence of the parameter in the config file. -

-

- - Solution -

-

- This is how you solve it with boost::optional: -

-
#include <boost/optional.hpp>
-
-boost::optional<int> getConfigParam(std::string name);  // return either an int or a `not-an-int`
-
-int main()
-{
-  if (boost::optional<int> oi = getConfigParam("MaxValue")) // did I get a real int?
-    runWithMax(*oi);                                        // use my int
-  else
-    runWithNoMax();
-}
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/optional/introduction/problem.html b/doc/html/optional/introduction/problem.html deleted file mode 100644 index 126a786..0000000 --- a/doc/html/optional/introduction/problem.html +++ /dev/null @@ -1,54 +0,0 @@ - - - -Problem - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Suppose we want to read a parameter form a config file which represents some - integral value, let's call it "MaxValue". - It is possible that this parameter is not specified; such situation is no - error. It is valid to not specify the parameter and in that case the program - is supposed to behave slightly different. Also suppose that any possible - value of type int is a valid - value for "MaxValue", - so we cannot jut use -1 - to represent the absence of the parameter in the config file. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/optional/introduction/solution.html b/doc/html/optional/introduction/solution.html deleted file mode 100644 index 01b95ba..0000000 --- a/doc/html/optional/introduction/solution.html +++ /dev/null @@ -1,58 +0,0 @@ - - - -Solution - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- This is how you solve it with boost::optional: -

-
#include <boost/optional.hpp>
-
-boost::optional<int> getConfigParam(std::string name);  // return either an int or a `not-an-int`
-
-int main()
-{
-  if (boost::optional<int> oi = getConfigParam("MaxValue")) // did I get a real int?
-    runWithMax(*oi);                                        // use my int
-  else
-    runWithNoMax();
-}
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/optional/reference.html b/doc/html/optional/reference.html deleted file mode 100644 index 57d96f2..0000000 --- a/doc/html/optional/reference.html +++ /dev/null @@ -1,48 +0,0 @@ - - - -Reference - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
- - - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/optional/tutorial.html b/doc/html/optional/tutorial.html deleted file mode 100644 index 35fd387..0000000 --- a/doc/html/optional/tutorial.html +++ /dev/null @@ -1,58 +0,0 @@ - - - -Tutorial - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
- - - - -
-
-
-PrevUpHomeNext -
- -