From 4cbb67e5059b8771768dd6598670fe723ca50475 Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Fri, 20 Jun 2014 11:38:57 +0200
Subject: [PATCH 1/3] Cleaner handling of explicit U to T conversions
---
doc/20_reference.qbk | 28 ++++-----
.../reference/detailed_semantics.html | 58 ++++++++----------
doc/html/index.html | 2 +-
include/boost/optional/optional.hpp | 59 +++++++++----------
test/optional_test_value_access.cpp | 4 +-
5 files changed, 68 insertions(+), 83 deletions(-)
diff --git a/doc/20_reference.qbk b/doc/20_reference.qbk
index fea6a37..32f58dd 100644
--- a/doc/20_reference.qbk
+++ b/doc/20_reference.qbk
@@ -326,7 +326,7 @@ __SPACE__
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
+* [*Notes:] If `rhs` is initialized, both `*this` and `*rhs` will refer to the
same object (they alias).
* [*Example:]
``
@@ -360,7 +360,8 @@ __SPACE__
* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and
its value is move constructed from `rhs`; else `*this` is uninitialized.
* [*Throws:] Whatever `T::T( T&& )` throws.
-* [*Notes:] If `rhs` is initialized, `T::T( T && )` is called. The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value`.
+* [*Remarks:] The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value`.
+* [*Notes:] If `rhs` is initialized, `T::T( T && )` is called.
* [*Exception Safety:] Exceptions can only be thrown during
`T::T( T&& );` in that case, `rhs` remains initialized and the value of `*rhs` is determined by exception safety of `T::T(T&&)`.
* [*Example:]
@@ -390,7 +391,7 @@ __SPACE__
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
+* [*Notes:] If `rhs` is initialized, both `*this` and `*rhs` will refer to the
same object (they alias).
* [*Example:]
``
@@ -663,11 +664,12 @@ __SPACE__
* [*Effect:] Move-assigns another `optional` to an `optional`.
* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and
its value is moved from `*rhs`, `rhs` remains initialized; else `*this` is uninitialized.
-* [*Throws:] Whatever `T::operator( T&& )` or `T::T( T && )` throws.
+* [*Throws:] Whatever `T::operator( T&& )` or `T::T( T && )` throws.
+* [*Remarks:] The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value && is_nothrow_move_assignable::value`.
* [*Notes:] If both `*this` and `rhs` are initially initialized, `T`'s
['move 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 ['move constructor] is called. The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value && is_nothrow_move_assignable::value`.
+but `rhs` is initialized, `T`'s ['move 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
@@ -932,8 +934,7 @@ __SPACE__
[: `template T optional::value_or(U && v) const& ;`]
* [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `U &&` is convertible to `T`.
-* [*Returns:] `bool(*this) ? **this : static_cast(std::forward(v))`.
-* [*Throws:] Any exception thrown by the selected constructor of `T`.
+* [*Effects:] `if (*this) return **this; else return std::forward(v);`.
* [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is replaced with the `const`-qualified member function. On compilers without rvalue reference support the type of `v` becomes `U const&`.
__SPACE__
@@ -943,8 +944,7 @@ __SPACE__
[: `template T optional::value_or(U && v) && ;`]
* [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `U &&` is convertible to `T`.
-* [*Returns:] `bool(*this) ? std::move(**this) : static_cast(std::forward(v))`.
-* [*Throws:] Any exception thrown by the selected constructor of `T`.
+* [*Effects:] `if (*this) return std::move(**this); else return std::forward(v);`.
* [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is not present.
__SPACE__
@@ -954,9 +954,8 @@ __SPACE__
[: `template T optional::value_or_eval(F f) const& ;`]
* [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `F` models a __SGI_GENERATOR__ whose result type is convertible to `T`.
-* [*Returns:] `bool(*this) ? **this : static_cast(f())`.
-* [*Throws:] Any exception thrown by the selected constructor of `T` or by `f`.
-* [*Notes:] Function `f` is only evaluated if `bool(*this) == false`. On compilers that do not support ref-qualifiers on member functions this overload is replaced with the `const`-qualified member function.
+* [*Effects:] `if (*this) return **this; else return f();`.
+* [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is replaced with the `const`-qualified member function.
* [*Example:]
``
int complain_and_0()
@@ -982,9 +981,8 @@ __SPACE__
[: `template T optional::value_or_eval(F f) && ;`]
* [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `F` models a __SGI_GENERATOR__ whose result type is convertible to `T`.
-* [*Returns:] `bool(*this) ? std::move(**this) : static_cast(f())`.
-* [*Throws:] Any exception thrown by the selected constructor of `T` or by `f`.
-* [*Notes:] Function `f` is only evaluated if `bool(*this) == false`. On compilers that do not support ref-qualifiers on member functions this overload is not present.
+* [*Effects:] `if (*this) return std::move(**this); else return f();`.
+* [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is not present.
__SPACE__
diff --git a/doc/html/boost_optional/reference/detailed_semantics.html b/doc/html/boost_optional/reference/detailed_semantics.html
index 78e75c8..e428dbf 100644
--- a/doc/html/boost_optional/reference/detailed_semantics.html
+++ b/doc/html/boost_optional/reference/detailed_semantics.html
@@ -352,7 +352,7 @@
Notes: If rhs
is initialized, both *this
and *rhs
- will reefer to the same object (they alias).
+ will refer to the same object (they alias).
Example:
@@ -402,12 +402,13 @@
Throws: Whatever T::T( T&& )
throws.
+
+ Remarks: The expression inside noexcept
is equivalent to is_nothrow_move_constructible<T>::value
.
+
Notes: If rhs
is initialized, T::T( T &&
- )
is called. The expression inside
- noexcept
is equivalent to
- is_nothrow_move_constructible<T>::value
.
+ ) is called.
Exception Safety: Exceptions can only
@@ -461,7 +462,7 @@
Notes: If rhs
is initialized, both *this
and *rhs
- will reefer to the same object (they alias).
+ will refer to the same object (they alias).
Example:
@@ -914,6 +915,10 @@
or T::T( T &&
)
throws.
+
+ Remarks: The expression inside noexcept
is equivalent to is_nothrow_move_constructible<T>::value &&
+ is_nothrow_move_assignable<T>::value
.
+
Notes: If both *this
and rhs
are initially initialized, T
's
@@ -921,10 +926,7 @@
is initially initialized but rhs
is uninitialized, T
's
[destructor] is called. If *this
is initially uninitialized but rhs
is initialized, T
's
- move constructor is called. The expression inside
- noexcept
is equivalent to
- is_nothrow_move_constructible<T>::value
- && is_nothrow_move_assignable<T>::value
.
+ move constructor is called.
Exception Safety: In the event of an
@@ -1455,11 +1457,8 @@
is convertible to T
.
- Returns: bool(*this) ? **this : static_cast<T>(std::forward<U>(v))
.
-
-
- Throws: Any exception thrown by the
- selected constructor of T
.
+ Effects: if
+ (*this) return **this; else return std::forward<U>(v);
.
Notes: On compilers that do not support
@@ -1485,11 +1484,9 @@
is convertible to T
.
- Returns: bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v))
.
-
-
- Throws: Any exception thrown by the
- selected constructor of T
.
+ Effects: if
+ (*this) return std::move(**this); else return
+ std::forward<U>(v);
.
Notes: On compilers that do not support
@@ -1509,16 +1506,11 @@
is convertible to T
.
- Returns: bool(*this) ? **this : static_cast<T>(f())
.
+ Effects: if
+ (*this) return **this; else return f();
.
- Throws: Any exception thrown by the
- selected constructor of T
- or by f
.
-
-
- Notes: Function f
- is only evaluated if bool(*this) == false
. On compilers that do not support
+ Notes: On compilers that do not support
ref-qualifiers on member functions this overload is replaced with the
const
-qualified member function.
@@ -1555,16 +1547,12 @@
whose result type is convertible to T
.
- Returns: bool(*this) ? std::move(**this) : static_cast<T>(f())
.
+ Effects: if
+ (*this) return std::move(**this); else return
+ f();
.
- Throws: Any exception thrown by the
- selected constructor of T
- or by f
.
-
-
- Notes: Function f
- is only evaluated if bool(*this) == false
. On compilers that do not support
+ Notes: On compilers that do not support
ref-qualifiers on member functions this overload is not present.
diff --git a/doc/html/index.html b/doc/html/index.html
index b1c713c..0380423 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -133,7 +133,7 @@
-Last revised: June 18, 2014 at 14:36:35 GMT |
+Last revised: June 20, 2014 at 09:06:52 GMT |
|
diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp
index 8e3a5dd..5d08606 100644
--- a/include/boost/optional/optional.hpp
+++ b/include/boost/optional/optional.hpp
@@ -112,28 +112,6 @@ class typed_in_place_factory_base ;
template void swap ( optional& x, optional& y );
namespace optional_detail {
-
-// converts type U to type T using only implicit conversions/constructors
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- template
- TT convert(UU && u)
- {
- return forward(u);
- }
-#else
- template
- TT convert(const UU& u)
- {
- return u;
- }
-
- template
- TT convert(UU& u)
- {
- return u;
- }
-#endif
-
// This local class is used instead of that in "aligned_storage.hpp"
// because I've found the 'official' class to ICE BCB5.5
// when some types are used with optional<>
@@ -1082,25 +1060,37 @@ class optional : public optional_detail::optional_base
template
value_type value_or ( U&& v ) const&
{
- return this->is_initialized() ? get() : optional_detail::convert(boost::forward(v));
+ if (this->is_initialized())
+ return get();
+ else
+ return boost::forward(v);
}
template
value_type value_or ( U&& v ) &&
{
- return this->is_initialized() ? boost::move(get()) : optional_detail::convert(boost::forward(v));
+ if (this->is_initialized())
+ return boost::move(get());
+ else
+ return boost::forward(v);
}
#elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES
template
value_type value_or ( U&& v ) const
- {
- return this->is_initialized() ? get() : optional_detail::convert(boost::forward(v));
+ {
+ if (this->is_initialized())
+ return get();
+ else
+ return boost::forward(v);
}
#else
template
value_type value_or ( U const& v ) const
{
- return this->is_initialized() ? get() : optional_detail::convert(v);
+ if (this->is_initialized())
+ return get();
+ else
+ return v;
}
#endif
@@ -1109,19 +1099,28 @@ class optional : public optional_detail::optional_base
template
value_type value_or_eval ( F f ) const&
{
- return this->is_initialized() ? get() : optional_detail::convert(f());
+ if (this->is_initialized())
+ return get();
+ else
+ return f();
}
template
value_type value_or_eval ( F f ) &&
{
- return this->is_initialized() ? boost::move(get()) : optional_detail::convert(f());
+ if (this->is_initialized())
+ return boost::move(get());
+ else
+ return f();
}
#else
template
value_type value_or_eval ( F f ) const
{
- return this->is_initialized() ? get() : optional_detail::convert(f());
+ if (this->is_initialized())
+ return get();
+ else
+ return f();
}
#endif
diff --git a/test/optional_test_value_access.cpp b/test/optional_test_value_access.cpp
index bc4ed4a..c83326a 100644
--- a/test/optional_test_value_access.cpp
+++ b/test/optional_test_value_access.cpp
@@ -149,7 +149,7 @@ int throw_()
throw int();
}
-void test_function_value_or_call()
+void test_function_value_or_eval()
{
optional o1 = 1;
optional oN;
@@ -237,7 +237,7 @@ int test_main( int, char* [] )
{
test_function_value();
test_function_value_or();
- test_function_value_or_call();
+ test_function_value_or_eval();
}
catch ( ... )
{
From 599c75a6d37768b7d9dbacb921b5e35a1535e453 Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Fri, 20 Jun 2014 16:25:57 +0200
Subject: [PATCH 2/3] various documentation fixes
---
doc/01_quick_start.qbk | 25 +-
doc/20_reference.qbk | 122 ++++-----
doc/Jamfile.v2 | 4 +-
doc/html/boost_optional/quick_start.html | 21 +-
.../optional_automatic_variables.html | 4 +-
.../reference/detailed_semantics.html | 255 +++++++++---------
doc/html/index.html | 2 +-
7 files changed, 211 insertions(+), 222 deletions(-)
diff --git a/doc/01_quick_start.qbk b/doc/01_quick_start.qbk
index 71053e1..4a94429 100644
--- a/doc/01_quick_start.qbk
+++ b/doc/01_quick_start.qbk
@@ -17,18 +17,18 @@
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::optionl convert(const std::string& text);
+ boost::optional convert(const std::string& text);
All necessary functionality can be included with one header ``. 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 oi = convert(text); // move-construct
- if (oi) // contextual conversion to bool
- int i = *oi; // operator*
+ boost::optional 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:
- if (boost::optionl oi = convert(text))
+ if (boost::optional 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:
@@ -50,16 +50,19 @@ This version throws an exception upon an attempt to access a non-existent contai
This uses the `atoi`-like approach to conversions: if `text` does not represent an integral number just return `0`. Finally, you can provide a callback to be called when trying to access the contained value fails:
- int l = convert(text).value_or_eval([]() -> int {
- cout << "could not convert; using -1 instead" << endl;
+ int fallback_to_default()
+ {
+ cerr << "could not convert; using -1 instead" << endl;
return -1;
- });
+ }
+
+ int l = convert(text).value_or_eval(fallback_to_default);
This will call the provided callback and return whatever the callback returns. The callback can have side effects: they will only be observed when the optional object does not contain a value.
Now, let's consider how function `convert` can be implemented.
- boost::optionl convert(const std::string& text)
+ boost::optional convert(const std::string& text)
{
std::stringstream s(text);
int i;
@@ -77,9 +80,9 @@ Observe the two return statements. `return i` uses the converting constructor th
We could write function `convert` in a slightly different manner, so that it has a single `return`-statement:
- boost::optionl convert(const std::string& text)
+ boost::optional convert(const std::string& text)
{
- boost::optionl ans;
+ boost::optional ans;
std::stringstream s(text);
int i;
if ((s >> i) && s.get() == std::char_traits::eof())
diff --git a/doc/20_reference.qbk b/doc/20_reference.qbk
index 32f58dd..513a72c 100644
--- a/doc/20_reference.qbk
+++ b/doc/20_reference.qbk
@@ -661,19 +661,17 @@ __SPACE__
[: `optional& optional::operator= ( optional&& rhs ) noexcept(`['see below]`);`]
-* [*Effect:] Move-assigns another `optional` to an `optional`.
-* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and
-its value is moved from `*rhs`, `rhs` remains initialized; else `*this` is uninitialized.
-* [*Throws:] Whatever `T::operator( T&& )` or `T::T( T && )` throws.
+* [*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.
+* [*Postconditions:] `bool(rhs) == bool(*this)`.
* [*Remarks:] The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value && is_nothrow_move_assignable::value`.
-* [*Notes:] If both `*this` and `rhs` are initially initialized, `T`'s
-['move 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 ['move 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 ['move constructor] fails, `*this` is left properly uninitialized.
+* [*Exception Safety:] If any exception is thrown, the initialization state of `*this` and `rhs` remain unchanged. If an exception is
+thrown during the call to `T`'s move constructor, the state of `*rhs` is determined by the exception safety guarantee
+of `T`'s move constructor. If an exception is thrown during the call to T's move-assignment, the state of `**this` and `*rhs` is determined by the exception safety guarantee of T's move assignment.
* [*Example:]
``
optional opt(T(2)) ;
@@ -751,6 +749,8 @@ optional opt0(v);
optional opt1;
opt1 = std::move(opt0) ;
+assert ( opt0 );
+assert ( opt1 )
assert ( *opt1 == static_cast(v) ) ;
``
@@ -1144,38 +1144,28 @@ __SPACE__
[: `bool operator == ( optional const& x, optional const& y );`]
-* [*Requires:] `T` shall meet requirements of `EqualityComparable`.
+* [*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`.
-* [*Throws:] Nothing.
* [*Notes:] Pointers have shallow relational operators while `optional` has
-deep relational operators. Do not use `operator ==` directly in generic
+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);
+optional oN, oN_;
+optional o1(T(1)), o1_(T(1));
+optional o2(T(2));
-// Identity always hold
-assert ( def0 == def0 );
-assert ( optX == optX );
+assert ( oN == oN ); // Identity implies equality
+assert ( o1 == o1 ); //
-// Both uninitialized compare equal
-assert ( def0 == def1 );
+assert ( oN == oN_ ); // Both uninitialized compare equal
-// Only one initialized compare unequal.
-assert ( def0 != optX );
+assert ( oN != o1 ); // Initialized unequal to initialized.
-// Both initialized compare as (*lhs == *rhs)
-assert ( optX == optY ) ;
-assert ( optX != optZ ) ;
+assert ( o1 == o1_ ); // Both initialized compare as (*lhs == *rhs)
+assert ( o1 != o2 ); //
``
__SPACE__
@@ -1184,35 +1174,29 @@ __SPACE__
[: `bool operator < ( optional const& x, optional const& y );`]
-* [*Requires:] `T` shall meet requirements of `LessThanComparable`.
-* [*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.
+* [*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
-which expect to be given either an `optional` or a pointer; use __FUNCTION_LESS_POINTEES__ instead.
+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:]
``
-T x(12);
-T y(34);
-optional def ;
-optional optX(x);
-optional optY(y);
+optional oN, oN_;
+optional o0(T(0));
+optional o1(T(1));
-// Identity always hold
-assert ( !(def < def) );
-assert ( optX == optX );
+assert ( !(oN < oN) ); // Identity implies equivalence
+assert ( !(o1 < o1) );
-// Both uninitialized compare equal
-assert ( def0 == def1 );
+assert ( !(oN < oN_) ); // Two uninitialized are equivalent
+assert ( !(oN_ < oN) );
-// Only one initialized compare unequal.
-assert ( def0 != optX );
+assert ( oN < o0 ); // Uninitialized is less than initialized
+assert ( !(o0 < oN) );
-// Both initialized compare as (*lhs == *rhs)
-assert ( optX == optY ) ;
-assert ( optX != optZ ) ;
+assert ( o1 < o2 ) ; // Two initialized compare as (*lhs < *rhs)
+assert ( !(o2 < o1) ) ;
+assert ( !(o2 < o2) ) ;
``
__SPACE__
@@ -1222,7 +1206,6 @@ __SPACE__
[: `bool operator != ( optional const& x, optional const& y );`]
* [*Returns: ] `!( x == y );`
-* [*Throws:] Nothing.
__SPACE__
@@ -1231,7 +1214,6 @@ __SPACE__
[: `bool operator > ( optional const& x, optional const& y );`]
* [*Returns: ] `( y < x );`
-* [*Throws:] Nothing.
__SPACE__
@@ -1240,7 +1222,6 @@ __SPACE__
[: `bool operator <= ( optional const& x, optional const& y );`]
* [*Returns: ] `!( y < x );`
-* [*Throws:] Nothing.
__SPACE__
@@ -1248,15 +1229,17 @@ __SPACE__
[: `bool operator >= ( optional const& x, optional const& y );`]
-* [*Returns: ] `!( x const& x, none_t ) noexcept;`]
+[: `bool operator == ( none_t, optional const& x ) noexcept;`]
* [*Returns:] `!x`.
-* [*Notes:] `T` need not meet requirements of `EqualityComparable`.
+* [*Notes:] `T` need not meet requirements of __SGI_EQUALITY_COMPARABLE__.
__SPACE__
@@ -1264,6 +1247,7 @@ __SPACE__
[#reference_operator_compare_not_equal_optional_none]
[: `bool operator != ( optional const& x, none_t ) noexcept;`]
+[: `bool operator != ( none_t, optional const& x ) noexcept;`]
* [*Returns: ] `!( x == y );`
@@ -1274,19 +1258,15 @@ __SPACE__
[: `void swap ( optional& 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.
+* [*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)`.
* [*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.
-* [*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&& )` 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::operator= ( T&& )`.
* [*Example:]
``
T x(12);
diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
index b6f4a79..debb1b4 100644
--- a/doc/Jamfile.v2
+++ b/doc/Jamfile.v2
@@ -24,7 +24,8 @@ boostbook standalone
:
optional
:
- boost.root=../../../..
+ html:boost.root=../../../..
+ html:boost.libraries=../../../../libs/libraries.htm
chapter.autolabel=0
chunk.section.depth=8
toc.section.depth=2
@@ -32,6 +33,7 @@ boostbook standalone
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
+ docbook:on
;
diff --git a/doc/html/boost_optional/quick_start.html b/doc/html/boost_optional/quick_start.html
index adee769..1c781f2 100644
--- a/doc/html/boost_optional/quick_start.html
+++ b/doc/html/boost_optional/quick_start.html
@@ -53,7 +53,7 @@
is possible. A natural signature for this function can be:
#include <boost/optional.hpp>
-boost::optionl<int> convert(const std::string& text);
+boost::optional<int> convert(const std::string& text);
All necessary functionality can be included with one header <boost/optional.hpp>
.
@@ -65,16 +65,16 @@
can use our function:
const std::string& text = ;
-boost::optionl<int> oi = convert(text);
-if (oi)
- int i = *oi;
+boost::optional<int> oi = convert(text);
+if (oi)
+ int i = *oi;
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))
+if (boost::optional<int> oi = convert(text))
int i = *oi;
@@ -114,10 +114,13 @@
Finally, you can provide a callback to be called when trying to access the
contained value fails:
-int l = convert(text).value_or_eval([]() -> int {
- cout << "could not convert; using -1 instead" << endl;
+int fallback_to_default()
+{
+ cerr << "could not convert; using -1 instead" << endl;
return -1;
-});
+}
+
+int l = convert(text).value_or_eval(fallback_to_default);
This will call the provided callback and return whatever the callback returns.
@@ -128,7 +131,7 @@
Now, let's consider how function convert
can be implemented.
-boost::optionl<int> convert(const std::string& text)
+boost::optional<int> convert(const std::string& text)
{
std::stringstream s(text);
int i;
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 f577e11..bcf6b37 100644
--- a/doc/html/boost_optional/quick_start/optional_automatic_variables.html
+++ b/doc/html/boost_optional/quick_start/optional_automatic_variables.html
@@ -31,9 +31,9 @@
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::optional<int> convert(const std::string& text)
{
- boost::optionl<int> ans;
+ boost::optional<int> ans;
std::stringstream s(text);
int i;
if ((s >> i) && s.get() == std::char_traits<char>::eof())
diff --git a/doc/html/boost_optional/reference/detailed_semantics.html b/doc/html/boost_optional/reference/detailed_semantics.html
index e428dbf..6dc0456 100644
--- a/doc/html/boost_optional/reference/detailed_semantics.html
+++ b/doc/html/boost_optional/reference/detailed_semantics.html
@@ -902,40 +902,52 @@
-
- Effect: Move-assigns another
optional
to an optional
.
+ Requires: T
+ is MoveConstructible
+ and MoveAssignable
.
-
- Postconditions: If
rhs
- is initialized, *this
- is initialized and its value is moved from *rhs
, rhs
- remains initialized; else *this
is uninitialized.
+ 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.
+
+
-
- Throws: Whatever
T::operator( T&& )
- or T::T( T &&
- )
throws.
+ Postconditions: bool(rhs) == bool(*this)
.
-
Remarks: The expression inside
noexcept
is equivalent to is_nothrow_move_constructible<T>::value &&
is_nothrow_move_assignable<T>::value
.
-
- Notes: If both
*this
and rhs
- are initially initialized, T
's
- move 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
- move 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
- move constructor fails, *this
is left properly uninitialized.
+ Exception Safety: If any exception is
+ thrown, the initialization state of *this
and rhs
+ remain unchanged. If an exception is thrown during the call to T
's move constructor, the state of
+ *rhs
+ is determined by the exception safety guarantee of T
's
+ move constructor. If an exception is thrown during the call to T's move-assignment,
+ the state of **this
+ and *rhs
+ is determined by the exception safety guarantee of T's move assignment.
-
Example:
@@ -1064,6 +1076,8 @@
optional<U> opt1;
opt1 = std::move(opt0) ;
+assert ( opt0 );
+assert ( opt1 )
assert ( *opt1 == static_cast<U>(v) ) ;
@@ -1823,7 +1837,7 @@
-
Requires:
T
- shall meet requirements of EqualityComparable
.
+ shall meet requirements of EqualityComparable
.
-
Returns: If both
x
@@ -1833,41 +1847,28 @@
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()
+ 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);
+optional<T> oN, oN_;
+optional<T> o1(T(1)), o1_(T(1));
+optional<T> o2(T(2));
-
-assert ( def0 == def0 );
-assert ( optX == optX );
+assert ( oN == oN );
+assert ( o1 == o1 );
-
-assert ( def0 == def1 );
+assert ( oN == oN_ );
-
-assert ( def0 != optX );
+assert ( oN != o1 );
-
-assert ( optX == optY ) ;
-assert ( optX != optZ ) ;
+assert ( o1 == o1_ );
+assert ( o1 != o2 );
@@ -1881,50 +1882,44 @@
-
- Requires:
T
- shall meet requirements of LessThanComparable
.
+ Requires: Expression *x < *y
+ shall be well-formed and its result shall be convertible to bool
.
-
- 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.
+ 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
- which expect to be given either an optional<T>
or a pointer; use less_pointees()
- instead.
+ 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
+ LessThanComparable
. Only single
+ operator<
+ is required. Other relational operations are defined in terms of this
+ one. If T
's operator<
+ satisfies the axioms of LessThanComparable
(transitivity,
+ antisymmetry and irreflexivity), optinal<T>
is LessThanComparable
.
-
Example:
-
T x(12);
-T y(34);
-optional<T> def ;
-optional<T> optX(x);
-optional<T> optY(y);
+optional<T> oN, oN_;
+optional<T> o0(T(0));
+optional<T> o1(T(1));
-
-assert ( !(def < def) );
-assert ( optX == optX );
+assert ( !(oN < oN) );
+assert ( !(o1 < o1) );
-
-assert ( def0 == def1 );
+assert ( !(oN < oN_) );
+assert ( !(oN_ < oN) );
-
-assert ( def0 != optX );
+assert ( oN < o0 );
+assert ( !(o0 < oN) );
-
-assert ( optX == optY ) ;
-assert ( optX != optZ ) ;
+assert ( o1 < o2 ) ;
+assert ( !(o2 < o1) ) ;
+assert ( !(o2 < o2) ) ;
@@ -1935,16 +1930,11 @@
bool operator
!= ( optional<T> const& x, optional<T> const& y );
-
--
+
-
Returns:
!(
x ==
y );
-
--
- Throws: Nothing.
-
-
+
@@ -1953,16 +1943,11 @@
> (
optional<T> const& x, optional<T> const& y );
-
--
+
-
Returns:
(
y <
x );
-
--
- Throws: Nothing.
-
-
+
@@ -1971,16 +1956,11 @@
<= (
optional<T> const& x, optional<T> const& y );
-
--
+
-
Returns:
!(
y <
x );
-
--
- Throws: Nothing.
-
-
+
@@ -1989,27 +1969,30 @@
>= (
optional<T> const& x, optional<T> const& y );
-
--
+
-
Returns:
!(
- x<y );
-
--
- Throws: Nothing.
-
-
+ x <
+ y );
+
+
+
+
bool operator
== ( optional<T> const& x, none_t
) noexcept;
+
+ bool operator
+ == ( none_t, optional<T> const& x ) noexcept;
+
-
Returns:
!x
.
-
Notes:
T
- need not meet requirements of EqualityComparable
.
+ need not meet requirements of EqualityComparable
.
@@ -2020,6 +2003,10 @@
!= ( optional<T> const& x, none_t
) noexcept;
+
+ bool operator
+ != ( none_t, optional<T> const& x ) noexcept;
+
-
Returns:
!(
x ==
@@ -2035,12 +2022,37 @@
-Last revised: June 20, 2014 at 09:06:52 GMT |
+Last revised: June 20, 2014 at 16:17:17 GMT |
|
From c7200c4aed33438583b5e2e4abf59dbd41b658af Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Fri, 20 Jun 2014 22:30:12 +0200
Subject: [PATCH 3/3] Minor docs fixes (operator=)
---
doc/20_reference.qbk | 26 ++++----
.../reference/detailed_semantics.html | 61 ++++++++++++-------
doc/html/index.html | 2 +-
3 files changed, 52 insertions(+), 37 deletions(-)
diff --git a/doc/20_reference.qbk b/doc/20_reference.qbk
index 513a72c..069789a 100644
--- a/doc/20_reference.qbk
+++ b/doc/20_reference.qbk
@@ -600,18 +600,17 @@ __SPACE__
[: `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.
+* [*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.
+* [*Returns:] `*this`;
+* [*Postconditions:] `bool(rhs) == bool(*this)`.
+* [*Exception Safety:] If any exception is thrown, the initialization state of `*this` and `rhs` remains unchanged.
+If an exception is thrown during the call to `T`'s copy constructor, no effect.
+If an exception is thrown during the call to `T`'s copy assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment.
* [*Example:]
``
T v;
@@ -667,9 +666,10 @@ __SPACE__
* 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.
+* [*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`.
-* [*Exception Safety:] If any exception is thrown, the initialization state of `*this` and `rhs` remain unchanged. If an exception is
+* [*Exception Safety:] If any exception is thrown, the initialization state of `*this` and `rhs` remains unchanged. If an exception is
thrown during the call to `T`'s move constructor, the state of `*rhs` is determined by the exception safety guarantee
of `T`'s move constructor. If an exception is thrown during the call to T's move-assignment, the state of `**this` and `*rhs` is determined by the exception safety guarantee of T's move assignment.
* [*Example:]
diff --git a/doc/html/boost_optional/reference/detailed_semantics.html b/doc/html/boost_optional/reference/detailed_semantics.html
index 6dc0456..8f83d55 100644
--- a/doc/html/boost_optional/reference/detailed_semantics.html
+++ b/doc/html/boost_optional/reference/detailed_semantics.html
@@ -804,36 +804,48 @@
-
- Effect: Assigns another
optional
to an optional
.
+ Requires: T
+ is CopyConstructible
and CopyAssignable
.
-
- Postconditions: If
rhs
- is initialized, *this
- is initialized and its value is a copy of the value
- of rhs
; else *this
- is uninitialized.
+ 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.
+
+
-
- Throws: Whatever
T::operator( T const&)
- or T::T( T const& )
- throws.
+ Returns: *this
;
-
- 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.
+ Postconditions: bool(rhs) == bool(*this)
.
-
- 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.
+ Exception Safety: If any exception is
+ thrown, the initialization state of *this
and rhs
+ remains unchanged. If an exception is thrown during the call to T
's copy constructor, no effect. If
+ an exception is thrown during the call to T
's
+ copy assignment, the state of its contained value is as defined by the
+ exception safety guarantee of T
's
+ copy assignment.
-
Example:
@@ -931,6 +943,9 @@
+
+ Returns: *this
;
+
Postconditions: bool(rhs) == bool(*this)
.
@@ -941,7 +956,7 @@
Exception Safety: If any exception is
thrown, the initialization state of *this
and rhs
- remain unchanged. If an exception is thrown during the call to T
's move constructor, the state of
+ remains unchanged. If an exception is thrown during the call to T
's move constructor, the state of
*rhs
is determined by the exception safety guarantee of T
's
move constructor. If an exception is thrown during the call to T's move-assignment,
diff --git a/doc/html/index.html b/doc/html/index.html
index f217eaa..c840a4f 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -133,7 +133,7 @@
-Last revised: June 20, 2014 at 16:17:17 GMT |
+Last revised: June 20, 2014 at 20:25:26 GMT |
|