diff --git a/doc/00_optional.qbk b/doc/00_optional.qbk
index 14f4d4a..e6ebc4c 100644
--- a/doc/00_optional.qbk
+++ b/doc/00_optional.qbk
@@ -83,7 +83,7 @@ This is how you solve it with `boost::optional`:
[include 14_io.qbk]
[include 15_optional_references.qbk]
[include 16_in_place_factories.qbk]
-[include 17_optional_bool.qbk]
+[include 17_gotchas.qbk]
[include 18_exception_safety.qbk]
[include 19_type_requirements.qbk]
[include 1A_on_performance.qbk]
diff --git a/doc/17_gotchas.qbk b/doc/17_gotchas.qbk
new file mode 100644
index 0000000..743c5bf
--- /dev/null
+++ b/doc/17_gotchas.qbk
@@ -0,0 +1,111 @@
+[section Gotchas]
+
+[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, although `optional<>` provides a contextual conversion to `bool` in C++11,
+ this falls back to an implicit conversion on older compilers. 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).
+
+Third, mixed comparisons with `bool` work differently than similar mixed comparisons between pointers and `bool`, so the results might surprise you:
+
+ optional oEmpty(none), oTrue(true), oFalse(false);
+
+ if (oEmpty == none); // renders true
+ if (oEmpty == false); // renders false!
+ if (oEmpty == true); // renders false!
+
+ if (oFalse == none); // renders false
+ if (oFalse == false); // renders true!
+ if (oFalse == true); // renders false
+
+ if (oTrue == none); // renders false
+ if (oTrue == false); // renders false
+ if (oTrue == true); // renders true
+
+In other words, for `optional<>`, the following assertion does not hold:
+
+ assert((opt == false) == (!opt));
+[endsect]
+
+[section Moved-from `optional`]
+
+When an optional object that contains a value is moved from (is a source of move constructor or assignment) it still contains a value and its contained value is left in a moved-from state. This can be illustrated with the following example.
+
+ optional> opi {std::make_unique(1)};
+ optional> opj = std::move(opi);
+ assert (opi);
+ assert (*opi == nullptr);
+
+Quite a lot of people expect that when an object that contains a value is moved from, its contained value should be destroyed. This is not so, for performance reasons. Current semantics allow the implementation of `boost::opiotnal` to be trivially copyable when `T` is trivial.
+[endsect]
+
+[section Mixed relational comparisons]
+
+Because `T` is convertible to `optional` and because `opiotnal` is __SGI_LESS_THAN_COMPARABLE__ when `T` is __SGI_LESS_THAN_COMPARABLE__,
+you can sometimes get an unexpected runtime result where you would rather expect a compiler error:
+
+ optional Flight_plan::weight(); // sometimes no weight can be returned
+
+ bool is_aircraft_too_heavy(Flight_plan const& p)
+ {
+ return p.weight() > p.aircraft().max_weight(); // compiles!
+ } // returns false when the optional contains no value
+
+[endsect]
+
+[section False positive with -Wmaybe-uninitialized]
+
+Sometimes on GCC compilers below version 5.1 you may get an -Wmaybe-uninitialized warning when copiling with option -02 on a perfectly valid `boost::optional` usage. For instance in this program:
+
+ #include
+
+ boost::optional getitem();
+
+ int main(int argc, const char *[])
+ {
+ boost::optional a = getitem();
+ boost::optional b;
+
+ if (argc > 0)
+ b = argc;
+
+ if (a != b)
+ return 1;
+
+ return 0;
+ }
+
+This is a bug in the compiler. As a workaround (provided in [@http://stackoverflow.com/questions/21755206/how-to-get-around-gcc-void-b-4-may-be-used-uninitialized-in-this-funct this Stack Overflow question]) use the following way of initializing an optional containing no value:
+
+ boost::optional b = std::make_optional(false, int());
+
+This is obviously redundant, but makes the warning disappear.
+
+[endsect]
+
+[endsect]
\ No newline at end of file
diff --git a/doc/17_optional_bool.qbk b/doc/17_optional_bool.qbk
deleted file mode 100644
index 6f3664f..0000000
--- a/doc/17_optional_bool.qbk
+++ /dev/null
@@ -1,52 +0,0 @@
-
-[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, although `optional<>` provides a contextual conversion to `bool` in C++11,
- this falls back to an implicit conversion on older compilers. 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).
-
-Third, mixed comparisons with `bool` work differently than similar mixed comparisons between pointers and `bool`, so the results might surprise you:
-
- optional oEmpty(none), oTrue(true), oFalse(false);
-
- if (oEmpty == none); // renders true
- if (oEmpty == false); // renders false!
- if (oEmpty == true); // renders false!
-
- if (oFalse == none); // renders false
- if (oFalse == false); // renders true!
- if (oFalse == true); // renders false
-
- if (oTrue == none); // renders false
- if (oTrue == false); // renders false
- if (oTrue == true); // renders true
-
-In other words, for `optional<>`, the following assertion does not hold:
-
- assert((opt == false) == (!opt));
-[endsect]
diff --git a/doc/1A_on_performance.qbk b/doc/1A_on_performance.qbk
index 841190f..5fd749a 100644
--- a/doc/1A_on_performance.qbk
+++ b/doc/1A_on_performance.qbk
@@ -23,7 +23,7 @@ Given type `optional`, and assuming that `sizeof(int) == 4`, we will get `s
[$images/opt_align1.png]
-This means you can fit twice as many `int`s as `optional`s into the same space of memory. Therefore, if the size of the objects is critical for your application (e.g., because you want to utilize your CPU cache in order to gain performance) and you have determined you are willing to trade the code clarity, it is recommended that you simply go with type `int` and use some 'magic value' to represent ['not-an-int].
+This means you can fit twice as many `int`s as `optional`s into the same space of memory. Therefore, if the size of the objects is critical for your application (e.g., because you want to utilize your CPU cache in order to gain performance) and you have determined you are willing to trade the code clarity, it is recommended that you simply go with type `int` and use some 'magic value' to represent ['not-an-int], or use something like [@https://github.com/akrzemi1/markable `markable`] library.
Even if you cannot spare any value of `int` to represent ['not-an-int] (e.g., because every value is useful, or you do want to signal ['not-an-int] explicitly), at least for `Trivial` types you should consider storing the value and the `bool` flag representing the ['null-state] separately. Consider the following class:
diff --git a/doc/28_ref_optional_semantics.qbk b/doc/28_ref_optional_semantics.qbk
index 803b244..e643a9f 100644
--- a/doc/28_ref_optional_semantics.qbk
+++ b/doc/28_ref_optional_semantics.qbk
@@ -770,6 +770,7 @@ __SPACE__
[: `template optional::optional(R&& r) noexcept;`]
* [*Postconditions:] `bool(*this) == true`; `addressof(**this) == addressof(r)`.
* [*Remarks:] Unless `R` is an lvalue reference, the program is ill-formed. This constructor does not participate in overload resolution if `decay` is an instance of `boost::optional`.
+* [*Notes:] This constructor is declared `explicit` on compilers that do not correctly suport binding to const lvalues of integral types. For more details [link optional_reference_binding see here].
* [*Example:]
``
T v;
diff --git a/doc/90_dependencies.qbk b/doc/90_dependencies.qbk
index 80e1803..6d0cccc 100644
--- a/doc/90_dependencies.qbk
+++ b/doc/90_dependencies.qbk
@@ -28,7 +28,7 @@ The implementation uses the following other Boost modules:
[endsect]
-[section Optional Reference Binding]
+[section Optional Reference Binding][#optional_reference_binding]
A number of compilers incorrectly treat const lvalues of integral type as rvalues, and create an illegal temporary when binding to an lvalue reference to const in some expressions. This could result in creating an optional lvalue reference that is in fact bound to an unexpected temporary rather than to the intended object. In order to prevent hard to find run-time bugs, this library performs compile-time checks to prevent expressions that would otherwise bind an optional reference to an unexpected temporary. As a consequence, on certain compilers certain pieces of functionality in optional references are missing. In order to maintain a portability of your code across diferent compilers, it is recommended that you only stick to the minimum portable interface of optional references: prefer direct-initialization and copy assignment of optional references to copy-initialization and assignment from `T&`:
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 fbe4ba8..314bfe6 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
@@ -28,18 +28,19 @@
Reference Binding
- A number of compilers incorrectly treat const lvalues of integral type as
- rvalues, and create an illegal temporary when binding to an lvalue reference
- to const in some expressions. This could result in creating an optional lvalue
- reference that is in fact bound to an unexpected temporary rather than to
- the intended object. In order to prevent hard to find run-time bugs, this
- library performs compile-time checks to prevent expressions that would otherwise
- bind an optional reference to an unexpected temporary. As a consequence,
- on certain compilers certain pieces of functionality in optional references
- are missing. In order to maintain a portability of your code across diferent
- compilers, it is recommended that you only stick to the minimum portable
- interface of optional references: prefer direct-initialization and copy assignment
- of optional references to copy-initialization and assignment from T&:
+ A number of compilers incorrectly
+ treat const lvalues of integral type as rvalues, and create an illegal temporary
+ when binding to an lvalue reference to const in some expressions. This could
+ result in creating an optional lvalue reference that is in fact bound to
+ an unexpected temporary rather than to the intended object. In order to prevent
+ hard to find run-time bugs, this library performs compile-time checks to
+ prevent expressions that would otherwise bind an optional reference to an
+ unexpected temporary. As a consequence, on certain compilers certain pieces
+ of functionality in optional references are missing. In order to maintain
+ a portability of your code across diferent compilers, it is recommended that
+ you only stick to the minimum portable interface of optional references:
+ prefer direct-initialization and copy assignment of optional references to
+ copy-initialization and assignment from T&:
diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html
index 0bca093..71b01dd 100644
--- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html
+++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html
@@ -55,6 +55,12 @@
is an lvalue reference, the program is ill-formed. This constructor
does not participate in overload resolution if decay<R> is an instance of boost::optional.
+
+ Notes: This constructor is declared
+ explicit on compilers
+ that do not correctly suport binding to const lvalues of integral types.
+ For more details see here.
+