mirror of
https://github.com/boostorg/optional.git
synced 2025-07-16 22:02:07 +02:00
Fixed Trac #10839
This commit is contained in:
@ -15,11 +15,13 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
class optional
|
||||
{
|
||||
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<T>` or a pointer; use
|
||||
* [*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
|
||||
__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<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 __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<T>` is __SGI_LESS_THAN_COMPARABLE__.
|
||||
* [*Example:]
|
||||
``
|
||||
|
@ -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<U>` to `optional<T>` when `U` is not assignable or convertible to `T`.
|
||||
* It is no longer possible to assign `optional<U>` to `optional<T>` 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<T&>` ([@https://svn.boost.org/trac/boost/ticket/10839 Trac #10839]).
|
||||
|
||||
|
||||
[heading Boost Release 1.57]
|
||||
|
@ -2028,9 +2028,13 @@
|
||||
If both are uninitialized, <code class="computeroutput"><span class="keyword">true</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> Pointers have shallow relational
|
||||
operators while <code class="computeroutput"><span class="identifier">optional</span></code>
|
||||
has deep relational operators. Do not use <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> directly in generic code which expect
|
||||
<span class="bold"><strong>Notes:</strong></span> This definition guarantees that
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
not containing a value is compared unequal to any <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> containing any value, and equal to
|
||||
any other <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
not containing a value. Pointers have shallow relational operators while
|
||||
<code class="computeroutput"><span class="identifier">optional</span></code> has deep relational
|
||||
operators. Do not use <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> directly in generic code which expect
|
||||
to be given either an <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> or a pointer; use <a href="../../../../../utility/OptionalPointee.html#equal" target="_top"><code class="computeroutput"><span class="identifier">equal_pointees</span><span class="special">()</span></code></a>
|
||||
instead
|
||||
</li>
|
||||
@ -2070,8 +2074,11 @@
|
||||
<span class="special">:</span> <span class="special">*</span><span class="identifier">x</span> <span class="special"><</span> <span class="special">*</span><span class="identifier">y</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> Pointers have shallow relational
|
||||
operators while <code class="computeroutput"><span class="identifier">optional</span></code>
|
||||
<span class="bold"><strong>Notes:</strong></span> This definition guarantees that
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
not containing a value is ordered as less than any <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> containing any value, and equivalent
|
||||
to any other <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> not containing a value. Pointers
|
||||
have shallow relational operators while <code class="computeroutput"><span class="identifier">optional</span></code>
|
||||
has deep relational operators. Do not use <code class="computeroutput"><span class="keyword">operator</span><span class="special"><</span></code> directly in generic code which expect
|
||||
to be given either an <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> or a pointer; use <a href="../../../../../utility/OptionalPointee.html#less" target="_top"><code class="computeroutput"><span class="identifier">less_pointees</span><span class="special">()</span></code></a>
|
||||
instead. <code class="computeroutput"><span class="identifier">T</span></code> need not be
|
||||
|
@ -54,7 +54,12 @@
|
||||
</li>
|
||||
<li class="listitem">
|
||||
It is no longer possible to assign <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">U</span><span class="special">></span></code> to <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> when <code class="computeroutput"><span class="identifier">U</span></code>
|
||||
is not assignable or convertible to <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
is not assignable or convertible to <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
(<a href="https://svn.boost.org/trac/boost/ticket/11087" target="_top">Trac #11087</a>).
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Value accessors now work correctly on rvalues of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code> (<a href="https://svn.boost.org/trac/boost/ticket/10839" target="_top">Trac
|
||||
#10839</a>).
|
||||
</li>
|
||||
</ul></div>
|
||||
<h4>
|
||||
|
@ -138,7 +138,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: March 06, 2015 at 18:13:34 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: March 09, 2015 at 09:53:44 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
@ -39,10 +39,12 @@
|
||||
|
||||
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">optional</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span> <span class="special">:</span>
|
||||
<span class="keyword">public</span> <span class="special">:</span>
|
||||
|
||||
<span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">value_type</span><span class="special">;</span>
|
||||
|
||||
<span class="comment">// (If T is of reference type, the parameters and results by reference are by value)</span>
|
||||
|
||||
|
@ -1020,7 +1020,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
||||
reference_const_type operator *() const& { return this->get() ; }
|
||||
reference_type operator *() & { return this->get() ; }
|
||||
reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; }
|
||||
reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; }
|
||||
#else
|
||||
reference_const_type operator *() const { return this->get() ; }
|
||||
reference_type operator *() { return this->get() ; }
|
||||
@ -1046,7 +1046,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
reference_type_of_temporary_wrapper value() &&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return boost::move(this->get()) ;
|
||||
return base::types::move(this->get()) ;
|
||||
else
|
||||
throw_exception(bad_optional_access());
|
||||
}
|
||||
@ -1084,7 +1084,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
value_type value_or ( U&& v ) &&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return boost::move(get());
|
||||
return base::types::move(get());
|
||||
else
|
||||
return boost::forward<U>(v);
|
||||
}
|
||||
@ -1123,7 +1123,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
value_type value_or_eval ( F f ) &&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return boost::move(get());
|
||||
return base::types::move(get());
|
||||
else
|
||||
return f();
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import testing ;
|
||||
[ run optional_test_ref_convert_assign_mutable_int.cpp ]
|
||||
[ run optional_test_ref_convert_assign_const_int.cpp ]
|
||||
[ run optional_test_ref_portable_minimum.cpp ]
|
||||
[ run optional_test_ref_move.cpp ]
|
||||
[ run optional_test_inplace_factory.cpp ]
|
||||
[ run optional_test_io.cpp ]
|
||||
[ run optional_test_move.cpp ]
|
||||
|
@ -9,7 +9,6 @@
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
|
||||
#include <iostream>
|
||||
#include "boost/optional.hpp"
|
||||
|
||||
// THIS TEST SHOULD FAIL TO COMPILE
|
||||
|
69
test/optional_test_ref_move.cpp
Normal file
69
test/optional_test_ref_move.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright (C) 2014 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 "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include "boost/core/addressof.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
|
||||
using boost::optional;
|
||||
|
||||
std::string global("text");
|
||||
|
||||
optional<std::string&> make_optional_string_ref()
|
||||
{
|
||||
return optional<std::string&>(global);
|
||||
}
|
||||
|
||||
std::string& return_global()
|
||||
{
|
||||
return global;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
optional<std::string&> opt;
|
||||
opt = make_optional_string_ref();
|
||||
BOOST_TEST(bool(opt));
|
||||
BOOST_TEST(*opt == global);
|
||||
BOOST_TEST(boost::addressof(*opt) == boost::addressof(global));
|
||||
|
||||
{
|
||||
std::string& str = *make_optional_string_ref();
|
||||
BOOST_TEST(str == global);
|
||||
BOOST_TEST(boost::addressof(str) == boost::addressof(global));
|
||||
}
|
||||
|
||||
{
|
||||
std::string& str = make_optional_string_ref().value();
|
||||
BOOST_TEST(str == global);
|
||||
BOOST_TEST(boost::addressof(str) == boost::addressof(global));
|
||||
}
|
||||
|
||||
{
|
||||
std::string& str = make_optional_string_ref().value_or(global);
|
||||
BOOST_TEST(str == global);
|
||||
BOOST_TEST(boost::addressof(str) == boost::addressof(global));
|
||||
}
|
||||
|
||||
{
|
||||
std::string& str = make_optional_string_ref().value_or_eval(&return_global);
|
||||
BOOST_TEST(str == global);
|
||||
BOOST_TEST(boost::addressof(str) == boost::addressof(global));
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
Reference in New Issue
Block a user