Added func value_or_eval()

This commit is contained in:
Andrzej Krzemienski
2014-06-18 15:01:52 +02:00
parent a158b85bd6
commit d70114b3dc
14 changed files with 536 additions and 50 deletions

View File

@ -41,6 +41,7 @@ Distributed under the Boost Software License, Version 1.0.
[def __SGI_DEFAULT_CONSTRUCTIBLE__ [@http://www.sgi.com/tech/stl/DefaultConstructible.html `DefaultConstructible`]] [def __SGI_DEFAULT_CONSTRUCTIBLE__ [@http://www.sgi.com/tech/stl/DefaultConstructible.html `DefaultConstructible`]]
[def __SGI_LESS_THAN_COMPARABLE__ [@http://www.sgi.com/tech/stl/LessThanComparable.html `LessThanComparable`]] [def __SGI_LESS_THAN_COMPARABLE__ [@http://www.sgi.com/tech/stl/LessThanComparable.html `LessThanComparable`]]
[def __SGI_EQUALITY_COMPARABLE__ [@http://www.sgi.com/tech/stl/EqualityComparable.html `EqualityComparable`]] [def __SGI_EQUALITY_COMPARABLE__ [@http://www.sgi.com/tech/stl/EqualityComparable.html `EqualityComparable`]]
[def __SGI_GENERATOR__ [@http://www.sgi.com/tech/stl/Generator.html `Generator`]]
[/ Icons ] [/ Icons ]

View File

@ -48,7 +48,16 @@ This version throws an exception upon an attempt to access a non-existent contai
int k = convert(text).value_or(0); int k = convert(text).value_or(0);
This uses the `atoi`-like approach to conversions: if `text` does not represent an integral number just return `0`. Now, let's consider how function `convert` can be implemented. This uses the `atoi`-like approach to conversions: if `text` does not represent an integral number just return `0`. 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;
return -1;
});
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<int> convert(const std::string& text) boost::optionl<int> convert(const std::string& text)
{ {

View File

@ -73,14 +73,17 @@
T const& operator *() const& ; ``[link reference_optional_operator_asterisk __GO_TO__]`` T const& operator *() const& ; ``[link reference_optional_operator_asterisk __GO_TO__]``
T& operator *() &; ``[link reference_optional_operator_asterisk __GO_TO__]`` T& operator *() &; ``[link reference_optional_operator_asterisk __GO_TO__]``
T&& operator *() &&; ``[link reference_optional_operator_asterisk __GO_TO__]`` T operator *() &&; ``[link reference_optional_operator_asterisk_move __GO_TO__]``
T const& value() const& ; ``[link reference_optional_value __GO_TO__]`` T const& value() const& ; ``[link reference_optional_value __GO_TO__]``
T& value() & ; ``[link reference_optional_value __GO_TO__]`` T& value() & ; ``[link reference_optional_value __GO_TO__]``
T&& value() && ; ``[link reference_optional_value __GO_TO__]`` T value() && ; ``[link reference_optional_value_move __GO_TO__]``
template<class U> T value_or( U && v ) const& ; ``[link reference_optional_value_or __GO_TO__]`` template<class U> T value_or( U && v ) const& ; ``[link reference_optional_value_or __GO_TO__]``
template<class U> T value_or( U && v ) && ; ``[link reference_optional_value_or_move __GO_TO__]`` template<class U> T value_or( U && v ) && ; ``[link reference_optional_value_or_move __GO_TO__]``
template<class F> T value_or_eval( F f ) const& ; ``[link reference_optional_value_or_call __GO_TO__]``
template<class F> T value_or_eval( F f ) && ; ``[link reference_optional_value_or_call_move __GO_TO__]``
T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]`` T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]``
T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]`` T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]``
@ -442,7 +445,7 @@ __SPACE__
* [*Effect:] Move-constructs an `optional`. * [*Effect:] Move-constructs an `optional`.
* [*Postconditions:] If `rhs` is initialized, `*this` is initialized and its * [*Postconditions:] If `rhs` is initialized, `*this` is initialized and its
value is move constructed from `*rhs`; else `*this` is value is move-constructed from `*rhs`; else `*this` is
uninitialized. uninitialized.
* [*Throws:] Whatever `T::T( U&& )` throws. * [*Throws:] Whatever `T::T( U&& )` throws.
* [*Notes: ] `T::T( U&& )` is called if `rhs` is initialized, which requires a * [*Notes: ] `T::T( U&& )` is called if `rhs` is initialized, which requires a
@ -837,12 +840,11 @@ __SPACE__
[: `T const& optional<T` ['(not a ref)]`>::operator*() const& ;`] [: `T const& optional<T` ['(not a ref)]`>::operator*() const& ;`]
[: `T& optional<T` ['(not a ref)]`>::operator*() &;`] [: `T& optional<T` ['(not a ref)]`>::operator*() &;`]
[: `T&& optional<T` ['(not a ref)]`>::operator*() &&;`]
* [*Requires:] `*this` is initialized * [*Requires:] `*this` is initialized
* [*Returns:] A reference to the contained value * [*Returns:] A reference to the contained value
* [*Throws:] Nothing. * [*Throws:] Nothing.
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. On compilers that do not support ref-qualifiers on member functions these three overloads are replaced with the classical two: a `const` and non-`const` member functions. * [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. On compilers that do not support ref-qualifiers on member functions these two overloads are replaced with the classical two: a `const` and non-`const` member functions.
* [*Example:] * [*Example:]
`` ``
T v ; T v ;
@ -856,6 +858,17 @@ assert ( *opt == w ) ;
__SPACE__ __SPACE__
[#reference_optional_operator_asterisk_move]
[: `T optional<T` ['(not a ref)]`>::operator*() &&;`]
* [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `*this` is initialized.
* [*Returns:] A move-constructed copy the contained value.
* [*Throws:] Whatever the `T`'s constructor selected for the move throws.
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. On compilers that do not support ref-qualifiers on member functions this overload is not present.
__SPACE__
[: `T const& optional<T&>::operator*() const& ;`] [: `T const& optional<T&>::operator*() const& ;`]
[: `T & optional<T&>::operator*() & ;`] [: `T & optional<T&>::operator*() & ;`]
[: `T & optional<T&>::operator*() && ;`] [: `T & optional<T&>::operator*() && ;`]
@ -881,11 +894,10 @@ __SPACE__
[: `T const& optional<T>::value() const& ;`] [: `T const& optional<T>::value() const& ;`]
[: `T& optional<T>::value() & ;`] [: `T& optional<T>::value() & ;`]
[: `T&& optional<T>::value() && ;`]
* [*Returns:] A reference to the contained value, if `*this` is initialized. * [*Returns:] A reference to the contained value, if `*this` is initialized.
* [*Throws:] An instance of `bad_optional_access`, if `*this` is not initialized. * [*Throws:] An instance of `bad_optional_access`, if `*this` is not initialized.
* [*Notes:] On compilers that do not support ref-qualifiers on member functions these three overloads are replaced with the classical two: a `const` and non-`const` member functions. * [*Notes:] On compilers that do not support ref-qualifiers on member functions these two overloads are replaced with the classical two: a `const` and non-`const` member functions.
* [*Example:] * [*Example:]
`` ``
T v ; T v ;
@ -900,6 +912,18 @@ catch(bad_optional_access&) {
assert ( true ); assert ( true );
} }
`` ``
__SPACE__
[#reference_optional_value_move]
[: `T optional<T>::value() && ;`]
* [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__.
* [*Returns:] A move-constructed copy of the contained value, if `*this` is initialized.
* [*Throws:] An instance of `bad_optional_access`, if `*this` is not initialized.
* [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is not present.
__SPACE__ __SPACE__
@ -908,7 +932,7 @@ __SPACE__
[: `template<class U> T optional<T>::value_or(U && v) const& ;`] [: `template<class U> T optional<T>::value_or(U && v) const& ;`]
* [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `U &&` is convertible to `T`. * [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `U &&` is convertible to `T`.
* [*Returns:] `bool(*this) ? **this : static_cast<T>(forward<U>(v))`. * [*Returns:] `bool(*this) ? **this : static_cast<T>(std::forward<U>(v))`.
* [*Throws:] Any exception thrown by the selected constructor of `T`. * [*Throws:] Any exception thrown by the selected constructor of `T`.
* [*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&`. * [*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&`.
@ -919,9 +943,48 @@ __SPACE__
[: `template<class U> T optional<T>::value_or(U && v) && ;`] [: `template<class U> T optional<T>::value_or(U && v) && ;`]
* [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `U &&` is convertible to `T`. * [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `U &&` is convertible to `T`.
* [*Returns:] `bool(*this) ? std::move(**this) : static_cast<T>(forward<U>(v))`. * [*Returns:] `bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v))`.
* [*Throws:] Any exception thrown by the selected constructor of `T`. * [*Throws:] Any exception thrown by the selected constructor of `T`.
* [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is replaced with the classical non-`const`-qualified member function. On compilers without rvalue reference support the type of `v` becomes `U const&`. * [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is not present.
__SPACE__
[#reference_optional_value_or_call]
[: `template<class F> T optional<T>::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<T>(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.
* [*Example:]
``
int complain_and_0()
{
clog << "no value returned, using default" << endl;
return 0;
}
optional<int> o1 = 1;
optional<int> oN = none;
int i = o1.value_or_eval(complain_and_0); // fun not called
assert (i == 1);
int j = oN.value_or_eval(complain_and_0); // fun called
assert (i == 0);
``
__SPACE__
[#reference_optional_value_or_call_move]
[: `template<class F> T optional<T>::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<T>(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.
__SPACE__ __SPACE__

View File

@ -9,7 +9,7 @@
] ]
[section Acknowledgments] [section Acknowledgements]
[heading Pre-formal review] [heading Pre-formal review]
@ -55,6 +55,8 @@ Rob Stewart, and others.
with the proper semantics. with the proper semantics.
* Mat Marcus shown the virtues of a value-oriented interface, influencing * Mat Marcus shown the virtues of a value-oriented interface, influencing
the current design, and contributed the idea of "none". the current design, and contributed the idea of "none".
* Vladimir Batov's design of Boost.Convert library motivated the development
of value accessors for `optional`: functions `value`, `value_or`, `value_or_eval`.
[endsect] [endsect]

View File

@ -0,0 +1,130 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Acknowledgements</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="Boost.Optional">
<link rel="up" href="../index.html" title="Boost.Optional">
<link rel="prev" href="dependencies_and_portability/optional_reference_binding.html" title="Optional Reference Binding">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="dependencies_and_portability/optional_reference_binding.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_optional.acknowledgements"></a><a class="link" href="acknowledgements.html" title="Acknowledgements">Acknowledgements</a>
</h2></div></div></div>
<h4>
<a name="boost_optional.acknowledgements.h0"></a>
<span class="phrase"><a name="boost_optional.acknowledgements.pre_formal_review"></a></span><a class="link" href="acknowledgements.html#boost_optional.acknowledgements.pre_formal_review">Pre-formal
review</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Peter Dimov suggested the name 'optional', and was the first to point out
the need for aligned storage.
</li>
<li class="listitem">
Douglas Gregor developed 'type_with_alignment', and later Eric Friedman
coded 'aligned_storage', which are the core of the optional class implementation.
</li>
<li class="listitem">
Andrei Alexandrescu and Brian Parker also worked with aligned storage techniques
and their work influenced the current implementation.
</li>
<li class="listitem">
Gennadiy Rozental made extensive and important comments which shaped the
design.
</li>
<li class="listitem">
Vesa Karvonen and Douglas Gregor made quite useful comparisons between
optional, variant and any; and made other relevant comments.
</li>
<li class="listitem">
Douglas Gregor and Peter Dimov commented on comparisons and evaluation
in boolean contexts.
</li>
<li class="listitem">
Eric Friedman helped understand the issues involved with aligned storage,
move/copy operations and exception safety.
</li>
<li class="listitem">
Many others have participated with useful comments: Aleksey Gurotov, Kevlin
Henney, David Abrahams, and others I can't recall.
</li>
</ul></div>
<h4>
<a name="boost_optional.acknowledgements.h1"></a>
<span class="phrase"><a name="boost_optional.acknowledgements.post_formal_review"></a></span><a class="link" href="acknowledgements.html#boost_optional.acknowledgements.post_formal_review">Post-formal
review</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
William Kempf carefully considered the originally proposed interface and
suggested the new interface which is currently used. He also started and
fueled the discussion about the analogy optional&lt;&gt;/smart pointer
and about relational operators.
</li>
<li class="listitem">
Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson
focused on the relational semantics of optional (originally undefined);
concluding with the fact that the pointer-like interface doesn't make it
a pointer so it shall have deep relational operators.
</li>
<li class="listitem">
Augustus Saunders also explored the different relational semantics between
optional&lt;&gt; and a pointer and developed the OptionalPointee concept
as an aid against potential conflicts on generic code.
</li>
<li class="listitem">
Joel de Guzman noticed that optional&lt;&gt; can be seen as an API on top
of variant&lt;T,nil_t&gt;.
</li>
<li class="listitem">
Dave Gomboc explained the meaning and usage of the Haskell analog to optional&lt;&gt;:
the Maybe type constructor (analogy originally pointed out by David Sankel).
</li>
<li class="listitem">
Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey,
Rob Stewart, and others.
</li>
<li class="listitem">
Joel de Guzman made the case for the support of references and helped with
the proper semantics.
</li>
<li class="listitem">
Mat Marcus shown the virtues of a value-oriented interface, influencing
the current design, and contributed the idea of "none".
</li>
<li class="listitem">
Vladimir Batov's design of Boost.Convert library motivated the development
of value accessors for <code class="computeroutput"><span class="identifier">optional</span></code>:
functions <code class="computeroutput"><span class="identifier">value</span></code>, <code class="computeroutput"><span class="identifier">value_or</span></code>, <code class="computeroutput"><span class="identifier">value_or_eval</span></code>.
</li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;ski<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="dependencies_and_portability/optional_reference_binding.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
</div>
</body>
</html>

View File

@ -7,7 +7,7 @@
<link rel="home" href="../../index.html" title="Boost.Optional"> <link rel="home" href="../../index.html" title="Boost.Optional">
<link rel="up" href="../dependencies_and_portability.html" title="Dependencies and Portability"> <link rel="up" href="../dependencies_and_portability.html" title="Dependencies and Portability">
<link rel="prev" href="../dependencies_and_portability.html" title="Dependencies and Portability"> <link rel="prev" href="../dependencies_and_portability.html" title="Dependencies and Portability">
<link rel="next" href="../acknowledgments.html" title="Acknowledgments"> <link rel="next" href="../acknowledgements.html" title="Acknowledgements">
</head> </head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr> <table cellpadding="2" width="100%"><tr>
@ -20,7 +20,7 @@
</tr></table> </tr></table>
<hr> <hr>
<div class="spirit-nav"> <div class="spirit-nav">
<a accesskey="p" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../acknowledgments.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> <a accesskey="p" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../acknowledgements.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div> </div>
<div class="section"> <div class="section">
<div class="titlepage"><div><div><h3 class="title"> <div class="titlepage"><div><div><h3 class="title">
@ -94,7 +94,7 @@
</tr></table> </tr></table>
<hr> <hr>
<div class="spirit-nav"> <div class="spirit-nav">
<a accesskey="p" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../acknowledgments.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> <a accesskey="p" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../acknowledgements.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div> </div>
</body> </body>
</html> </html>

View File

@ -111,6 +111,20 @@
This uses the <code class="computeroutput"><span class="identifier">atoi</span></code>-like approach This uses the <code class="computeroutput"><span class="identifier">atoi</span></code>-like approach
to conversions: if <code class="computeroutput"><span class="identifier">text</span></code> does to conversions: if <code class="computeroutput"><span class="identifier">text</span></code> does
not represent an integral number just return <code class="computeroutput"><span class="number">0</span></code>. not represent an integral number just return <code class="computeroutput"><span class="number">0</span></code>.
Finally, you can provide a callback to be called when trying to access the
contained value fails:
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">l</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">).</span><span class="identifier">value_or_eval</span><span class="special">([]()</span> <span class="special">-&gt;</span> <span class="keyword">int</span> <span class="special">{</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"could not convert; using -1 instead"</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span>
<span class="special">});</span>
</pre>
<p>
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.
</p>
<p>
Now, let's consider how function <code class="computeroutput"><span class="identifier">convert</span></code> Now, let's consider how function <code class="computeroutput"><span class="identifier">convert</span></code>
can be implemented. can be implemented.
</p> </p>

View File

@ -541,7 +541,7 @@
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Postconditions:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code> <span class="bold"><strong>Postconditions:</strong></span> If <code class="computeroutput"><span class="identifier">rhs</span></code>
is initialized, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized, <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initialized and its value is move constructed from <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code>; else <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is uninitialized. is initialized and its value is move-constructed from <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code>; else <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is uninitialized.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span> <span class="identifier">U</span><span class="special">&amp;&amp;</span> <span class="special">)</span></code> <span class="bold"><strong>Throws:</strong></span> Whatever <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span><span class="special">(</span> <span class="identifier">U</span><span class="special">&amp;&amp;</span> <span class="special">)</span></code>
@ -1269,10 +1269,6 @@
<code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;</span> <code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="special">&amp;;</span></code> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="special">&amp;;</span></code>
</p></blockquote></div> </p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="special">&amp;&amp;;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized <span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized
@ -1288,8 +1284,8 @@
<span class="bold"><strong>Notes:</strong></span> The requirement is asserted via <span class="bold"><strong>Notes:</strong></span> The requirement is asserted via
<code class="computeroutput"><span class="identifier">BOOST_ASSERT</span><span class="special">()</span></code>. <code class="computeroutput"><span class="identifier">BOOST_ASSERT</span><span class="special">()</span></code>.
On compilers that do not support ref-qualifiers on member functions these On compilers that do not support ref-qualifiers on member functions these
three overloads are replaced with the classical two: a <code class="computeroutput"><span class="keyword">const</span></code> and non-<code class="computeroutput"><span class="keyword">const</span></code> two overloads are replaced with the classical two: a <code class="computeroutput"><span class="keyword">const</span></code>
member functions. and non-<code class="computeroutput"><span class="keyword">const</span></code> member functions.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Example:</strong></span> <span class="bold"><strong>Example:</strong></span>
@ -1303,6 +1299,35 @@
</pre> </pre>
</li> </li>
</ul></div> </ul></div>
<p>
<span class="inlinemediaobject"><img src="../../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_operator_asterisk_move"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">T</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span></code>
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="special">&amp;&amp;;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>
is <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
and <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is initialized.
</li>
<li class="listitem">
<span class="bold"><strong>Returns:</strong></span> A move-constructed copy the
contained value.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever the <code class="computeroutput"><span class="identifier">T</span></code>'s
constructor selected for the move throws.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> The requirement is asserted via
<code class="computeroutput"><span class="identifier">BOOST_ASSERT</span><span class="special">()</span></code>.
On compilers that do not support ref-qualifiers on member functions this
overload is not present.
</li>
</ul></div>
<p> <p>
<span class="inlinemediaobject"><img src="../../images/space.png" alt="space"></span> <span class="inlinemediaobject"><img src="../../images/space.png" alt="space"></span>
</p> </p>
@ -1357,10 +1382,6 @@
<code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;</span> <code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;</span> <span class="special">;</span></code> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;</span> <span class="special">;</span></code>
</p></blockquote></div> </p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;&amp;</span> <span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Returns:</strong></span> A reference to the contained <span class="bold"><strong>Returns:</strong></span> A reference to the contained
@ -1373,8 +1394,8 @@
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Notes:</strong></span> On compilers that do not support <span class="bold"><strong>Notes:</strong></span> On compilers that do not support
ref-qualifiers on member functions these three overloads are replaced ref-qualifiers on member functions these two overloads are replaced with
with the classical two: a <code class="computeroutput"><span class="keyword">const</span></code> the classical two: a <code class="computeroutput"><span class="keyword">const</span></code>
and non-<code class="computeroutput"><span class="keyword">const</span></code> member functions. and non-<code class="computeroutput"><span class="keyword">const</span></code> member functions.
</li> </li>
<li class="listitem"> <li class="listitem">
@ -1391,9 +1412,36 @@
<span class="identifier">assert</span> <span class="special">(</span> <span class="keyword">true</span> <span class="special">);</span> <span class="identifier">assert</span> <span class="special">(</span> <span class="keyword">true</span> <span class="special">);</span>
<span class="special">}</span> <span class="special">}</span>
</pre> </pre>
<span class="inlinemediaobject"><img src="../../images/space.png" alt="space"></span>
</li> </li>
</ul></div> </ul></div>
<p>
<span class="inlinemediaobject"><img src="../../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_value_move"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">T</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;&amp;</span>
<span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>
is <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Returns:</strong></span> A move-constructed copy of
the contained value, if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> An instance of <code class="computeroutput"><span class="identifier">bad_optional_access</span></code>, if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is not initialized.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> On compilers that do not support
ref-qualifiers on member functions this overload is not present.
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_value_or"></a><div class="blockquote"><blockquote class="blockquote"><p> <a name="reference_optional_value_or"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">U</span> <span class="special">&amp;&amp;</span> <code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">U</span> <span class="special">&amp;&amp;</span>
<span class="identifier">v</span><span class="special">)</span> <span class="identifier">v</span><span class="special">)</span>
@ -1407,7 +1455,7 @@
is convertible to <code class="computeroutput"><span class="identifier">T</span></code>. is convertible to <code class="computeroutput"><span class="identifier">T</span></code>.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Returns:</strong></span> <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">?</span> <span class="special">**</span><span class="keyword">this</span> <span class="special">:</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">))</span></code>. <span class="bold"><strong>Returns:</strong></span> <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">?</span> <span class="special">**</span><span class="keyword">this</span> <span class="special">:</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">))</span></code>.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Any exception thrown by the <span class="bold"><strong>Throws:</strong></span> Any exception thrown by the
@ -1437,7 +1485,7 @@
is convertible to <code class="computeroutput"><span class="identifier">T</span></code>. is convertible to <code class="computeroutput"><span class="identifier">T</span></code>.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Returns:</strong></span> <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">?</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(**</span><span class="keyword">this</span><span class="special">)</span> <span class="special">:</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">))</span></code>. <span class="bold"><strong>Returns:</strong></span> <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">?</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(**</span><span class="keyword">this</span><span class="special">)</span> <span class="special">:</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;(</span><span class="identifier">v</span><span class="special">))</span></code>.
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Any exception thrown by the <span class="bold"><strong>Throws:</strong></span> Any exception thrown by the
@ -1445,10 +1493,79 @@
</li> </li>
<li class="listitem"> <li class="listitem">
<span class="bold"><strong>Notes:</strong></span> On compilers that do not support <span class="bold"><strong>Notes:</strong></span> On compilers that do not support
ref-qualifiers on member functions this overload is not present.
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_value_or_call"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value_or_eval</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">)</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>
is <a href="../../../../../utility/CopyConstructible.html" target="_top"><code class="computeroutput"><span class="identifier">CopyConstructible</span></code></a> and <code class="computeroutput"><span class="identifier">F</span></code> models a <a href="http://www.sgi.com/tech/stl/Generator.html" target="_top"><code class="computeroutput"><span class="identifier">Generator</span></code></a> whose result type
is convertible to <code class="computeroutput"><span class="identifier">T</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Returns:</strong></span> <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">?</span> <span class="special">**</span><span class="keyword">this</span> <span class="special">:</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">())</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Any exception thrown by the
selected constructor of <code class="computeroutput"><span class="identifier">T</span></code>
or by <code class="computeroutput"><span class="identifier">f</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> Function <code class="computeroutput"><span class="identifier">f</span></code>
is only evaluated if <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">false</span></code>. On compilers that do not support
ref-qualifiers on member functions this overload is replaced with the ref-qualifiers on member functions this overload is replaced with the
classical non-<code class="computeroutput"><span class="keyword">const</span></code>-qualified <code class="computeroutput"><span class="keyword">const</span></code>-qualified member function.
member function. On compilers without rvalue reference support the type </li>
of <code class="computeroutput"><span class="identifier">v</span></code> becomes <code class="computeroutput"><span class="identifier">U</span> <span class="keyword">const</span><span class="special">&amp;</span></code>. <li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">complain_and_0</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">clog</span> <span class="special">&lt;&lt;</span> <span class="string">"no value returned, using default"</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">o1</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">oN</span> <span class="special">=</span> <span class="identifier">none</span><span class="special">;</span>
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">o1</span><span class="special">.</span><span class="identifier">value_or_eval</span><span class="special">(</span><span class="identifier">complain_and_0</span><span class="special">);</span> <span class="comment">// fun not called</span>
<span class="identifier">assert</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">==</span> <span class="number">1</span><span class="special">);</span>
<span class="keyword">int</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">oN</span><span class="special">.</span><span class="identifier">value_or_eval</span><span class="special">(</span><span class="identifier">complain_and_0</span><span class="special">);</span> <span class="comment">// fun called</span>
<span class="identifier">assert</span> <span class="special">(</span><span class="identifier">i</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
</pre>
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_value_or_call_move"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value_or_eval</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>
is <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
and <code class="computeroutput"><span class="identifier">F</span></code> models a <a href="http://www.sgi.com/tech/stl/Generator.html" target="_top"><code class="computeroutput"><span class="identifier">Generator</span></code></a>
whose result type is convertible to <code class="computeroutput"><span class="identifier">T</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Returns:</strong></span> <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">?</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(**</span><span class="keyword">this</span><span class="special">)</span> <span class="special">:</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;(</span><span class="identifier">f</span><span class="special">())</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Any exception thrown by the
selected constructor of <code class="computeroutput"><span class="identifier">T</span></code>
or by <code class="computeroutput"><span class="identifier">f</span></code>.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> Function <code class="computeroutput"><span class="identifier">f</span></code>
is only evaluated if <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">==</span> <span class="keyword">false</span></code>. On compilers that do not support
ref-qualifiers on member functions this overload is not present.
</li> </li>
</ul></div> </ul></div>
<p> <p>

View File

@ -84,7 +84,7 @@
<dt><span class="section"><a href="boost_optional/dependencies_and_portability/optional_reference_binding.html">Optional <dt><span class="section"><a href="boost_optional/dependencies_and_portability/optional_reference_binding.html">Optional
Reference Binding</a></span></dt> Reference Binding</a></span></dt>
</dl></dd> </dl></dd>
<dt><span class="section"><a href="boost_optional/acknowledgments.html">Acknowledgments</a></span></dt> <dt><span class="section"><a href="boost_optional/acknowledgements.html">Acknowledgements</a></span></dt>
</dl> </dl>
</div> </div>
<div class="section"> <div class="section">
@ -133,7 +133,7 @@
</div> </div>
</div> </div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: June 16, 2014 at 12:04:51 GMT</small></p></td> <td align="left"><p><small>Last revised: June 18, 2014 at 14:36:35 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td> <td align="right"><div class="copyright-footer"></div></td>
</tr></table> </tr></table>
<hr> <hr>

View File

@ -97,15 +97,18 @@
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">T</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">T</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;&amp;;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">T</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;&amp;;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_operator_asterisk_move"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">T</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_move"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or_move"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or_move"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or_eval</span><span class="special">(</span> <span class="identifier">F</span> <span class="identifier">f</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or_call"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or_eval</span><span class="special">(</span> <span class="identifier">F</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or_call_move"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">get_ptr</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">get_ptr</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">T</span><span class="special">*</span> <span class="identifier">get_ptr</span><span class="special">()</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">get_ptr</span><span class="special">()</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>

View File

@ -35,7 +35,6 @@
#include <boost/type_traits/remove_reference.hpp> #include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/decay.hpp> #include <boost/type_traits/decay.hpp>
#include <boost/type_traits/is_base_of.hpp> #include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_lvalue_reference.hpp> #include <boost/type_traits/is_lvalue_reference.hpp>
#include <boost/type_traits/is_nothrow_move_assignable.hpp> #include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp> #include <boost/type_traits/is_nothrow_move_constructible.hpp>
@ -51,7 +50,6 @@
#include <boost/utility/addressof.hpp> #include <boost/utility/addressof.hpp>
#include <boost/utility/compare_pointees.hpp> #include <boost/utility/compare_pointees.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/utility/in_place_factory.hpp> #include <boost/utility/in_place_factory.hpp>
#include <boost/utility/swap.hpp> #include <boost/utility/swap.hpp>
@ -115,6 +113,27 @@ template<class T> void swap ( optional<T>& x, optional<T>& y );
namespace optional_detail { namespace optional_detail {
// converts type U to type T using only implicit conversions/constructors
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename TT, typename UU>
TT convert(UU && u)
{
return forward<UU>(u);
}
#else
template <typename TT, typename UU>
TT convert(const UU& u)
{
return u;
}
template <typename TT, typename UU>
TT convert(UU& u)
{
return u;
}
#endif
// This local class is used instead of that in "aligned_storage.hpp" // This local class is used instead of that in "aligned_storage.hpp"
// because I've found the 'official' class to ICE BCB5.5 // because I've found the 'official' class to ICE BCB5.5
// when some types are used with optional<> // when some types are used with optional<>
@ -1010,7 +1029,7 @@ class optional : public optional_detail::optional_base<T>
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
reference_const_type operator *() const& { return this->get() ; } reference_const_type operator *() const& { return this->get() ; }
reference_type operator *() & { return this->get() ; } reference_type operator *() & { return this->get() ; }
reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; } value_type operator *() && { return boost::move(this->get()) ; }
#else #else
reference_const_type operator *() const { return this->get() ; } reference_const_type operator *() const { return this->get() ; }
reference_type operator *() { return this->get() ; } reference_type operator *() { return this->get() ; }
@ -1033,7 +1052,7 @@ class optional : public optional_detail::optional_base<T>
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object.")); throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
} }
reference_type_of_temporary_wrapper value() && value_type value() &&
{ {
if (this->is_initialized()) if (this->is_initialized())
return boost::move(this->get()) ; return boost::move(this->get()) ;
@ -1058,33 +1077,51 @@ class optional : public optional_detail::optional_base<T>
} }
#endif #endif
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
template <class U> template <class U>
value_type value_or ( U&& v ) const& value_type value_or ( U&& v ) const&
{ {
BOOST_STATIC_ASSERT((is_convertible<U&&, value_type>::value)); return this->is_initialized() ? get() : optional_detail::convert<value_type>(boost::forward<U>(v));
return this->is_initialized() ? get() : static_cast<value_type>(boost::forward<U>(v));
} }
template <class U> template <class U>
value_type value_or ( U&& v ) && value_type value_or ( U&& v ) &&
{ {
BOOST_STATIC_ASSERT((is_convertible<U&&, value_type>::value)); return this->is_initialized() ? boost::move(get()) : optional_detail::convert<value_type>(boost::forward<U>(v));
return this->is_initialized() ? boost::move(get()) : static_cast<value_type>(boost::forward<U>(v));
} }
#elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES #elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <class U> template <class U>
value_type value_or ( U&& v ) const value_type value_or ( U&& v ) const
{ {
BOOST_STATIC_ASSERT((is_convertible<U&&, value_type>::value)); return this->is_initialized() ? get() : optional_detail::convert<value_type>(boost::forward<U>(v));
return this->is_initialized() ? get() : static_cast<value_type>(boost::forward<U>(v));
} }
#else #else
template <class U> template <class U>
value_type value_or ( U const& v ) const value_type value_or ( U const& v ) const
{ {
BOOST_STATIC_ASSERT((is_convertible<U const&, value_type>::value)); return this->is_initialized() ? get() : optional_detail::convert<value_type>(v);
return this->is_initialized() ? get() : static_cast<value_type>(v); }
#endif
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
template <typename F>
value_type value_or_eval ( F f ) const&
{
return this->is_initialized() ? get() : optional_detail::convert<value_type>(f());
}
template <typename F>
value_type value_or_eval ( F f ) &&
{
return this->is_initialized() ? boost::move(get()) : optional_detail::convert<value_type>(f());
}
#else
template <typename F>
value_type value_or_eval ( F f ) const
{
return this->is_initialized() ? get() : optional_detail::convert<value_type>(f());
} }
#endif #endif

View File

@ -42,5 +42,6 @@ import testing ;
[ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ] [ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ] [ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ] [ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ]
; ;
} }

View File

@ -0,0 +1,34 @@
// 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.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
struct U
{};
struct T
{
explicit T(U const&) {}
};
U get_U() { return U(); }
void test_verifying_the_implicit_conversion_to_bool()
{
boost::optional<T> opt;
opt.value_or_eval(get_U);
}

View File

@ -128,6 +128,73 @@ void test_function_value_or()
BOOST_CHECK(FatToIntConverter::conversions == 1); BOOST_CHECK(FatToIntConverter::conversions == 1);
} }
struct FunM
{
int operator()() { return 5; }
};
struct FunC
{
int operator()() const { return 6; }
};
int funP ()
{
return 7;
}
int throw_()
{
throw int();
}
void test_function_value_or_call()
{
optional<int> o1 = 1;
optional<int> oN;
FunM funM;
FunC funC;
BOOST_CHECK(o1.value_or_eval(funM) == 1);
BOOST_CHECK(oN.value_or_eval(funM) == 5);
BOOST_CHECK(o1.value_or_eval(FunM()) == 1);
BOOST_CHECK(oN.value_or_eval(FunM()) == 5);
BOOST_CHECK(o1.value_or_eval(funC) == 1);
BOOST_CHECK(oN.value_or_eval(funC) == 6);
BOOST_CHECK(o1.value_or_eval(FunC()) == 1);
BOOST_CHECK(oN.value_or_eval(FunC()) == 6);
BOOST_CHECK(o1.value_or_eval(funP) == 1);
BOOST_CHECK(oN.value_or_eval(funP) == 7);
#ifndef BOOST_NO_CXX11_LAMBDAS
BOOST_CHECK(o1.value_or_eval([](){return 8;}) == 1);
BOOST_CHECK(oN.value_or_eval([](){return 8;}) == 8);
#endif
try
{
BOOST_CHECK(o1.value_or_eval(throw_) == 1);
}
catch(...)
{
BOOST_CHECK(false);
}
try
{
BOOST_CHECK(oN.value_or_eval(throw_) == 1);
BOOST_CHECK(false);
}
catch(...)
{
BOOST_CHECK(true);
}
}
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
struct MoveOnly struct MoveOnly
{ {
@ -144,15 +211,22 @@ optional<MoveOnly> makeMoveOnly()
return MoveOnly(1); return MoveOnly(1);
} }
MoveOnly moveOnlyDefault()
{
return MoveOnly(1);
}
// compile-time test // compile-time test
void test_move_only_getters() void test_move_only_getters()
{ {
MoveOnly m1 = *makeMoveOnly(); MoveOnly m1 = *makeMoveOnly();
MoveOnly m2 = makeMoveOnly().value(); MoveOnly m2 = makeMoveOnly().value();
MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1)); MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1));
MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault);
unused_variable(m1); unused_variable(m1);
unused_variable(m2); unused_variable(m2);
unused_variable(m3); unused_variable(m3);
unused_variable(m4);
} }
#endif #endif
@ -163,6 +237,7 @@ int test_main( int, char* [] )
{ {
test_function_value(); test_function_value();
test_function_value_or(); test_function_value_or();
test_function_value_or_call();
} }
catch ( ... ) catch ( ... )
{ {