From 59266a26301e6add265601841687b44306ba8c82 Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Fri, 6 Mar 2015 19:20:45 +0100
Subject: [PATCH 1/5] More restrictive assignment from optional
---
doc/20_reference.qbk | 79 ++-
doc/91_relnotes.qbk | 1 +
.../reference/detailed_semantics.html | 492 +++++++++++++-----
doc/html/boost_optional/relnotes.html | 4 +
doc/html/index.html | 2 +-
include/boost/optional/optional.hpp | 13 +-
test/Jamfile.v2 | 1 +
...onal_test_fail_convert_assign_of_enums.cpp | 27 +
8 files changed, 444 insertions(+), 175 deletions(-)
create mode 100644 test/optional_test_fail_convert_assign_of_enums.cpp
diff --git a/doc/20_reference.qbk b/doc/20_reference.qbk
index cba3bac..8afc43b 100644
--- a/doc/20_reference.qbk
+++ b/doc/20_reference.qbk
@@ -602,10 +602,11 @@ __SPACE__
* [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `CopyAssignable`.
* [*Effects:]
- * If `!*this && !rhs` no effect, otherwise
- * if `bool(*this) && !rhs`, destroys the contained value by calling `val->T::~T()`, otherwise
- * if `!*this && bool(rhs)`, initializes the contained value as if direct-initializing an object of type `T` with `*rhs`, otherwise
- * (if `bool(*this) && bool(rhs)`) assigns `*rhs` to the contained value.
+[table
+ [[][`*this` contains a value][`*this` does not contain a value]]
+ [[`rhs` contains a value][assigns `*rhs` to the contained value][initializes the contained value as if direct-initializing an object of type `T` with `*rhs`]]
+ [[`rhs` does not contain a value][destroys the contained value by calling `val->T::~T()`][no effect]]
+]
* [*Returns:] `*this`;
* [*Postconditions:] `bool(rhs) == bool(*this)`.
* [*Exception Safety:] If any exception is thrown, the initialization state of `*this` and `rhs` remains unchanged.
@@ -662,10 +663,11 @@ __SPACE__
* [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `MoveAssignable`.
* [*Effects:]
- * If `!*this && !rhs` no effect, otherwise
- * if `bool(*this) && !rhs`, destroys the contained value by calling `val->T::~T()`, otherwise
- * if `!*this && bool(rhs)`, initializes the contained value as if direct-initializing an object of type `T` with `std::move(*rhs)`, otherwise
- * (if `bool(*this) && bool(rhs)`) assigns `std::move(*rhs)` to the contained value.
+[table
+ [[][`*this` contains a value][`*this` does not contain a value]]
+ [[`rhs` contains a value][assigns `std::move(*rhs)` to the contained value][initializes the contained value as if direct-initializing an object of type `T` with `std::move(*rhs)`]]
+ [[`rhs` does not contain a value][destroys the contained value by calling `val->T::~T()`][no effect]]
+]
* [*Returns:] `*this`;
* [*Postconditions:] `bool(rhs) == bool(*this)`.
* [*Remarks:] The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value && is_nothrow_move_assignable::value`.
@@ -696,21 +698,17 @@ __SPACE__
[: `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.
+* [*Effect:]
+[table
+ [[][`*this` contains a value][`*this` does not contain a value]]
+ [[`rhs` contains a value][assigns `*rhs` to the contained value][initializes the contained value as if direct-initializing an object of type `T` with `*rhs`]]
+ [[`rhs` does not contain a value][destroys the contained value by calling `val->T::~T()`][no effect]]
+]
+* [*Returns:] `*this`.
+* [*Postconditions:] `bool(rhs) == bool(*this)`.
+* [*Exception Safety:] If any exception is thrown, the result of the expression `bool(*this)` remains unchanged.
+If an exception is thrown during the call to `T`'s constructor, no effect.
+If an exception is thrown during the call to `T`'s assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment.
* [*Example:]
``
T v;
@@ -727,21 +725,17 @@ __SPACE__
[: `template optional& optional::operator= ( optional&& rhs ) ;`]
-* [*Effect:] Move-assigns another convertible optional to an optional.
-* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and
-its value is moved from the value of `rhs`; else
-`*this` is uninitialized.
-* [*Throws:] Whatever `T::operator=( U&& )` or `T::T( U&& )` 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.
+* [*Effect:]
+[table
+ [[][`*this` contains a value][`*this` does not contain a value]]
+ [[`rhs` contains a value][assigns `std::move(*rhs)` to the contained value][initializes the contained value as if direct-initializing an object of type `T` with `std::move(*rhs)`]]
+ [[`rhs` does not contain a value][destroys the contained value by calling `val->T::~T()`][no effect]]
+]
+* [*Returns:] `*this`.
+* [*Postconditions:] `bool(rhs) == bool(*this)`.
+* [*Exception Safety:] If any exception is thrown, the result of the expression `bool(*this)` remains unchanged.
+If an exception is thrown during the call to `T`'s constructor, no effect.
+If an exception is thrown during the call to `T`'s assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment.
* [*Example:]
``
T v;
@@ -1256,10 +1250,11 @@ __SPACE__
* [*Requires:] Lvalues of type `T` shall be swappable and `T` shall be __MOVE_CONSTRUCTIBLE__.
* [*Effects:]
- * If `!*this && !rhs`, no effect, otherwise
- * if `bool(*this) && !rhs`, initializes the contained value of `rhs` as if direct-initializing an object of type `T` with the expression `std::move(*(*this))`, followed by `val->T::~T()`, `*this` does not contain a value and `rhs` contains a value, otherwise
- * if `!*this && bool(rhs)`, initializes the contained value of `*this` as if direct-initializing an object of type `T` with the expression `std::move(*rhs)`, followed by `rhs.val->T::~T()`, `*this` contains a value and `rhs` does not contain a value, otherwise
- * (if `bool(*this) && bool(rhs)`) calls `swap(*(*this), *rhs)`.
+[table
+ [[][`*this` contains a value][`*this` does not contain a value]]
+ [[`rhs` contains a value][calls `swap(*(*this), *rhs)`][initializes the contained value of `*this` as if direct-initializing an object of type `T` with the expression `std::move(*rhs)`, followed by `rhs.val->T::~T()`, `*this` contains a value and `rhs` does not contain a value]]
+ [[`rhs` does not contain a value][initializes the contained value of `rhs` as if direct-initializing an object of type `T` with the expression `std::move(*(*this))`, followed by `val->T::~T()`, `*this` does not contain a value and `rhs` contains a value][no effect]]
+]
* [*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&& )` throws.
diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk
index 3cffa97..ea400c7 100644
--- a/doc/91_relnotes.qbk
+++ b/doc/91_relnotes.qbk
@@ -17,6 +17,7 @@
* Improved the trick that prevents streaming out `optional` without header `optional_io.hpp` by using safe-bool idiom. This addresses [@https://svn.boost.org/trac/boost/ticket/10825 Trac #10825]
* IOStream operators are now mentioned in documentation.
* Added a way to manually disable move semantics: just define macro `BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES`. This can be used to work around [@https://svn.boost.org/trac/boost/ticket/10399 Trac #10399]
+* It is no longer possible to assign `optional` to `optional` when `U` is not assignable or convertible to `T`.
[heading Boost Release 1.57]
diff --git a/doc/html/boost_optional/reference/detailed_semantics.html b/doc/html/boost_optional/reference/detailed_semantics.html
index 2e017d2..8bff973 100644
--- a/doc/html/boost_optional/reference/detailed_semantics.html
+++ b/doc/html/boost_optional/reference/detailed_semantics.html
@@ -808,30 +808,74 @@
is CopyConstructible and CopyAssignable.
+
Effects:
-
-
- If !*this
- &&!rhs no effect, otherwise
-
-
- if bool(*this)
- &&!rhs, destroys the contained value
- by calling val->T::~T(), otherwise
-
-
- if !*this
- &&bool(rhs), initializes the contained value
- as if direct-initializing an object of type T
- with *rhs,
- otherwise
-
-
- (if bool(*this)
- &&bool(rhs)) assigns *rhs to the contained value.
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ *this
+ contains a value
+
+
+
+
+ *this
+ does not contain a value
+
+
+
+
+
+
+
+ rhs contains
+ a value
+
+
+
+
+ assigns *rhs
+ to the contained value
+
+
+
+
+ initializes the contained value as if direct-initializing an
+ object of type T
+ with *rhs
+
+
+
+
+
+
+ rhs does not
+ contain a value
+
+
+
+
+ destroys the contained value by calling val->T::~T()
+
+
+
+
+ no effect
+
+
+
+
+
+
Returns:*this;
@@ -919,30 +963,73 @@
and MoveAssignable.
+
Effects:
-
-
- If !*this
- &&!rhs no effect, otherwise
-
-
- if bool(*this)
- &&!rhs, destroys the contained value
- by calling val->T::~T(), otherwise
-
-
- if !*this
- &&bool(rhs), initializes the contained value
- as if direct-initializing an object of type T
- with std::move(*rhs),
- otherwise
-
-
- (if bool(*this)
- &&bool(rhs)) assigns std::move(*rhs) to the contained value.
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ *this
+ contains a value
+
+
+
+
+ *this
+ does not contain a value
+
+
+
+
+
+
+
+ rhs contains
+ a value
+
+
+
+
+ assigns std::move(*rhs) to the contained value
+
+
+
+
+ initializes the contained value as if direct-initializing an
+ object of type T
+ with std::move(*rhs)
+
+
+
+
+
+
+ rhs does not
+ contain a value
+
+
+
+
+ destroys the contained value by calling val->T::~T()
+
+
+
+
+ no effect
+
+
+
+
+
+
Returns:*this;
@@ -997,40 +1084,88 @@
- Effect: Assigns another convertible
- optional to an optional.
+
+ Effect:
+
+
+
+
+
+
+
+
+
+
+
+
+ *this
+ contains a value
+
+
+
+
+ *this
+ does not contain a value
+
+
+
+
+
+
+
+ rhs contains
+ a value
+
+
+
+
+ assigns *rhs
+ to the contained value
+
+
+
+
+ initializes the contained value as if direct-initializing an
+ object of type T
+ with *rhs
+
+
+
+
+
+
+ rhs does not
+ contain a value
+
+
+
+
+ destroys the contained value by calling val->T::~T()
+
+
+
+
+ no effect
+
+
+
+
+
+
+
+ Returns:*this.
- 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.
+ Postconditions:bool(rhs)==bool(*this).
- Throws: Whatever T::operator=(Uconst&) or T::T(Uconst&) 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.
+ Exception Safety: If any exception is
+ thrown, the result of the expression bool(*this) remains unchanged. If an exception is
+ thrown during the call to T's
+ constructor, no effect. If an exception is thrown during the call to
+ T's assignment, the state
+ of its contained value is as defined by the exception safety guarantee
+ of T's copy assignment.
Example:
@@ -1053,36 +1188,87 @@
- Effect: Move-assigns another convertible
- optional to an optional.
+
+ Effect:
+
+
+
+
+
+
+
+
+
+
+
+
+ *this
+ contains a value
+
+
+
+
+ *this
+ does not contain a value
+
+
+
+
+
+
+
+ rhs contains
+ a value
+
+
+
+
+ assigns std::move(*rhs) to the contained value
+
+
+
+
+ initializes the contained value as if direct-initializing an
+ object of type T
+ with std::move(*rhs)
+
+
+
+
+
+
+ rhs does not
+ contain a value
+
+
+
+
+ destroys the contained value by calling val->T::~T()
+
+
+
+
+ no effect
+
+
+
+
+
+
+
+ Returns:*this.
- Postconditions: If rhs
- is initialized, *this
- is initialized and its value is moved from the value of rhs; else *this is uninitialized.
+ Postconditions:bool(rhs)==bool(*this).
- 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.
+ Exception Safety: If any exception is
+ thrown, the result of the expression bool(*this) remains unchanged. If an exception is
+ thrown during the call to T's
+ constructor, no effect. If an exception is thrown during the call to
+ T's assignment, the state
+ of its contained value is as defined by the exception safety guarantee
+ of T's copy assignment.
Example:
@@ -2019,35 +2205,81 @@
Requires: Lvalues of type T shall be swappable and T shall be MoveConstructible.
+
Effects:
-
-
- If !*this
- &&!rhs, no effect, otherwise
-
-
- if bool(*this)
- &&!rhs, initializes the contained
- value of rhs as
- if direct-initializing an object of type T
- with the expression std::move(*(*this)), followed by val->T::~T(), *this does not contain a value and
- rhs contains a
- value, otherwise
-
-
- if !*this
- &&bool(rhs), initializes the contained value
- of *this
- as if direct-initializing an object of type T
- with the expression std::move(*rhs), followed by rhs.val->T::~T(), *this contains a value and rhs does not contain a value,
- otherwise
-
+ initializes the contained value of *this as if direct-initializing
+ an object of type T
+ with the expression std::move(*rhs), followed by rhs.val->T::~T(),
+ *this
+ contains a value and rhs
+ does not contain a value
+
+
+
+
+
+
+ rhs does not
+ contain a value
+
+
+
+
+ initializes the contained value of rhs
+ as if direct-initializing an object of type T
+ with the expression std::move(*(*this)), followed by val->T::~T(),
+ *this
+ does not contain a value and rhs
+ contains a value
+
+
+
+
+ no effect
+
+
+
+
+
+
Postconditions: The states of x and y
interchanged.
diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html
index 02fcd41..1d476e3 100644
--- a/doc/html/boost_optional/relnotes.html
+++ b/doc/html/boost_optional/relnotes.html
@@ -52,6 +52,10 @@
This can be used to work around Trac
#10399
+
+ It is no longer possible to assign optional<U> to optional<T> when U
+ is not assignable or convertible to T.
+
diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp
index f8d631d..56f5096 100644
--- a/include/boost/optional/optional.hpp
+++ b/include/boost/optional/optional.hpp
@@ -188,7 +188,7 @@ struct types_when_is_ref
template
void prevent_binding_rvalue_ref_to_optional_lvalue_ref()
{
-#ifndef BOOST_OPTIONAL_ALLOW_BINDING_TO_RVALUES
+#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
BOOST_STATIC_ASSERT_MSG(
!boost::is_lvalue_reference::value || !boost::is_rvalue_reference::value,
"binding rvalue references to optional lvalue references is disallowed");
@@ -371,13 +371,22 @@ class optional_base : public optional_tag
if (is_initialized())
{
if ( rhs.is_initialized() )
- assign_value(static_cast(rhs.get()), is_reference_predicate() );
+#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
+ assign_value(rhs.get(), is_reference_predicate() );
+#else
+ assign_value(static_cast(rhs.get()), is_reference_predicate() );
+#endif
+
else destroy();
}
else
{
if ( rhs.is_initialized() )
+#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
+ construct(rhs.get());
+#else
construct(static_cast(rhs.get()));
+#endif
}
}
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index 9db0c01..54535b7 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -56,5 +56,6 @@ import testing ;
[ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ]
[ compile-fail optional_test_fail_io_without_io.cpp ]
+ [ compile-fail optional_test_fail_convert_assign_of_enums.cpp ]
;
}
diff --git a/test/optional_test_fail_convert_assign_of_enums.cpp b/test/optional_test_fail_convert_assign_of_enums.cpp
new file mode 100644
index 0000000..184e282
--- /dev/null
+++ b/test/optional_test_fail_convert_assign_of_enums.cpp
@@ -0,0 +1,27 @@
+// Copyright (C) 2015, Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/lib/optional for documentation.
+//
+// You are welcome to contact the author at:
+// akrzemi1@gmail.com
+
+#include
+#include "boost/optional.hpp"
+
+// THIS TEST SHOULD FAIL TO COMPILE
+
+enum E1 {e1};
+enum E2 {e2};
+
+void test_converitng_assignment_of_different_enums()
+{
+ boost::optional o2(e2);
+ boost::optional o1;
+ o1 = o2;
+}
+
+int main() {}
From 0a8a798c3a57ab608b6e88fd9f2aa97e4bc3af8a Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Mon, 9 Mar 2015 11:50:10 +0100
Subject: [PATCH 2/5] Fixed Trac #10839
---
doc/20_reference.qbk | 15 ++--
doc/91_relnotes.qbk | 3 +-
.../reference/detailed_semantics.html | 17 +++--
doc/html/boost_optional/relnotes.html | 7 +-
doc/html/index.html | 2 +-
doc/html/optional/reference.html | 6 +-
include/boost/optional/optional.hpp | 8 +--
test/Jamfile.v2 | 1 +
...onal_test_fail_convert_assign_of_enums.cpp | 1 -
test/optional_test_ref_move.cpp | 69 +++++++++++++++++++
10 files changed, 107 insertions(+), 22 deletions(-)
create mode 100644 test/optional_test_ref_move.cpp
diff --git a/doc/20_reference.qbk b/doc/20_reference.qbk
index 8afc43b..8ca21b8 100644
--- a/doc/20_reference.qbk
+++ b/doc/20_reference.qbk
@@ -15,11 +15,13 @@
namespace boost {
- template
+ template
class optional
{
- public :
+ public :
+ typedef T value_type;
+
// (If T is of reference type, the parameters and results by reference are by value)
optional () noexcept ; ``[link reference_optional_constructor __GO_TO__]``
@@ -1137,9 +1139,8 @@ __SPACE__
* [*Requires:] `T` shall meet requirements of __SGI_EQUALITY_COMPARABLE__.
* [*Returns:] If both `x` and `y` are initialized, `(*x == *y)`. If only
`x` or `y` is initialized, `false`. If both are uninitialized, `true`.
-* [*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
+* [*Notes:] This definition guarantees that `optional` not containing a value is compared unequal to any `optional` containing any value, and equal to any other `optional` not containing a value.
+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:]
``
@@ -1166,8 +1167,8 @@ __SPACE__
* [*Requires:] Expression `*x < *y` shall be well-formed and its result shall be convertible to `bool`.
* [*Returns:] `(!y) ? false : (!x) ? true : *x < *y`.
-* [*Notes:] Pointers have shallow relational operators while `optional` has
-deep relational operators. Do not use `operator<` directly in generic code
+* [*Notes:] This definition guarantees that `optional` not containing a value is ordered as less than any `optional` containing any value, and equivalent to any other `optional` not containing a value.
+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. `T` need not be __SGI_LESS_THAN_COMPARABLE__. Only single `operator<` is required. Other relational operations are defined in terms of this one. If `T`'s `operator<` satisfies the axioms of __SGI_LESS_THAN_COMPARABLE__ (transitivity, antisymmetry and irreflexivity), `optinal` is __SGI_LESS_THAN_COMPARABLE__.
* [*Example:]
``
diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk
index ea400c7..e75fef7 100644
--- a/doc/91_relnotes.qbk
+++ b/doc/91_relnotes.qbk
@@ -17,7 +17,8 @@
* Improved the trick that prevents streaming out `optional` without header `optional_io.hpp` by using safe-bool idiom. This addresses [@https://svn.boost.org/trac/boost/ticket/10825 Trac #10825]
* IOStream operators are now mentioned in documentation.
* Added a way to manually disable move semantics: just define macro `BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES`. This can be used to work around [@https://svn.boost.org/trac/boost/ticket/10399 Trac #10399]
-* It is no longer possible to assign `optional` to `optional` when `U` is not assignable or convertible to `T`.
+* It is no longer possible to assign `optional` to `optional` when `U` is not assignable or convertible to `T` ([@https://svn.boost.org/trac/boost/ticket/11087 Trac #11087]).
+* Value accessors now work correctly on rvalues of `optional` ([@https://svn.boost.org/trac/boost/ticket/10839 Trac #10839]).
[heading Boost Release 1.57]
diff --git a/doc/html/boost_optional/reference/detailed_semantics.html b/doc/html/boost_optional/reference/detailed_semantics.html
index 8bff973..3f4bd8d 100644
--- a/doc/html/boost_optional/reference/detailed_semantics.html
+++ b/doc/html/boost_optional/reference/detailed_semantics.html
@@ -2028,9 +2028,13 @@
If both are uninitialized, true.
- Notes: Pointers have shallow relational
- operators while optional
- has deep relational operators. Do not use operator== directly in generic code which expect
+ Notes: This definition guarantees that
+ optional<T>
+ not containing a value is compared unequal to any optional<T> containing any value, and equal to
+ any other optional<T>
+ not containing a value. 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
@@ -2070,8 +2074,11 @@
:*x<*y.
- Notes: Pointers have shallow relational
- operators while optional
+ Notes: This definition guarantees that
+ optional<T>
+ not containing a value is ordered as less than any optional<T> containing any value, and equivalent
+ to any other optional<T> not containing a value. 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. T need not be
diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html
index 1d476e3..3fb495b 100644
--- a/doc/html/boost_optional/relnotes.html
+++ b/doc/html/boost_optional/relnotes.html
@@ -54,7 +54,12 @@
It is no longer possible to assign optional<U> to optional<T> when U
- is not assignable or convertible to T.
+ is not assignable or convertible to T
+ (Trac #11087).
+
+
+ Value accessors now work correctly on rvalues of optional<T&> (Trac
+ #10839).