Merge branch 'develop'
@ -2,7 +2,7 @@
|
||||
[quickbook 1.4]
|
||||
[authors [Cacciola Carballal, Fernando Luis]]
|
||||
[copyright 2003-2007 Fernando Luis Cacciola Carballal]
|
||||
[copyright 2014 Andrzej Krzemieński]
|
||||
[copyright 2014-2015 Andrzej Krzemieński]
|
||||
[category miscellaneous]
|
||||
[id optional]
|
||||
[dirname optional]
|
||||
@ -80,16 +80,19 @@ This is how you solve it with `boost::optional`:
|
||||
[include 11_development.qbk]
|
||||
[include 12_when_to_use.qbk]
|
||||
[include 13_relational_operators.qbk]
|
||||
[include 14_optional_references.qbk]
|
||||
[include 15_in_place_factories.qbk]
|
||||
[include 16_optional_bool.qbk]
|
||||
[include 17_exception_safety.qbk]
|
||||
[include 18_type_requirements.qbk]
|
||||
[include 14_io.qbk]
|
||||
[include 15_optional_references.qbk]
|
||||
[include 16_in_place_factories.qbk]
|
||||
[include 17_optional_bool.qbk]
|
||||
[include 18_exception_safety.qbk]
|
||||
[include 19_type_requirements.qbk]
|
||||
[include 1A_on_performance.qbk]
|
||||
[endsect]
|
||||
[section Reference]
|
||||
[include 20_reference.qbk]
|
||||
[endsect]
|
||||
[include 90_dependencies.qbk]
|
||||
[include 91_acknowledgments.qbk]
|
||||
[include 91_relnotes.qbk]
|
||||
[include 92_acknowledgments.qbk]
|
||||
|
||||
|
||||
|
37
doc/14_io.qbk
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
[section IO operators]
|
||||
|
||||
It is possible to use `optional<T>` with IO streams, provided that `T` can be used with streams. IOStream operators are defined in a separate header.
|
||||
|
||||
``
|
||||
#include <iostream>
|
||||
#include <boost/optional/optional_io.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::optional<int> o1 = 1, oN = boost::none;
|
||||
std::cout << o1;
|
||||
std::cin >> oN;
|
||||
}
|
||||
``
|
||||
|
||||
The current implementation does not guarantee any particular output. What it guarantees is that if streaming out and then back in `T` gives the same value, then streaming out and then back in `optional<T>` will also give back the same result:
|
||||
|
||||
``
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <boost/optional/optional_io.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::optional<int> o1 = 1, oN = boost::none;
|
||||
boost::optional<int> x1, x2;
|
||||
std::stringstream s;
|
||||
s << o1 << oN;
|
||||
s >> x1 >> x2;
|
||||
assert (o1 == x1);
|
||||
assert (oN == x2);
|
||||
}
|
||||
``
|
||||
|
||||
[endsect]
|
131
doc/1A_on_performance.qbk
Normal file
@ -0,0 +1,131 @@
|
||||
|
||||
[section Performance considerations]
|
||||
|
||||
Technical details aside, the memory layout of `optional<T>` is more-less this:
|
||||
|
||||
template <typename T>
|
||||
class optional
|
||||
{
|
||||
bool _initialized;
|
||||
std::aligned_storage_t<sizeof(t), alignof(T)> _storage;
|
||||
};
|
||||
|
||||
But for the purpose of this analysis, considering memory layouts, we can think of it as:
|
||||
|
||||
template <typename T>
|
||||
class optional
|
||||
{
|
||||
bool _initialized;
|
||||
T _storage;
|
||||
};
|
||||
|
||||
Given type `optional<int>`, and assuming that `sizeof(int) == 4`, we will get `sizeof(optional<int>) == 8`. This is so because of the alignment rules, for our two members we get the following alignment:
|
||||
|
||||
[$images/opt_align1.png]
|
||||
|
||||
This means you can fit twice as many `int`s as `optional<int>`s into the same space of memory. Therefore, if the size of the objects is critical for your application (e.g., because you want to utilize your CPU cache in order to gain performance) and you have determined you are willing to trade the code clarity, it is recommended that you simply go with type `int` and use some 'magic value' to represent ['not-an-int].
|
||||
|
||||
Even if you cannot spare any value of `int` to represent ['not-an-int] (e.g., because every value is useful, or you do want to signal ['not-an-int] explicitly), at least for `Trivial` types you should consider storing the value and the `bool` flag representing the ['null-state] separately. Consider the following class:
|
||||
|
||||
struct Record
|
||||
{
|
||||
optional<int> _min;
|
||||
optional<int> _max;
|
||||
};
|
||||
|
||||
Its memory layout can be depicted as follows:
|
||||
|
||||
[$images/opt_align2.png]
|
||||
|
||||
This is exactly the same as if we had the following members:
|
||||
|
||||
struct Record
|
||||
{
|
||||
bool _has_min;
|
||||
int _min;
|
||||
bool _has_max;
|
||||
int _max;
|
||||
};
|
||||
|
||||
But when they are stored separately, we at least have an option to reorder them like this:
|
||||
|
||||
struct Record
|
||||
{
|
||||
bool _has_min;
|
||||
bool _has_max;
|
||||
int _min;
|
||||
int _max;
|
||||
};
|
||||
|
||||
Which gives us the following layout (and smaller total size):
|
||||
|
||||
[$images/opt_align3.png]
|
||||
|
||||
Sometimes it requires detailed consideration what data we make optional. In our case above, if we determine that both minimum and maximum value can be provided or not provided together, but one is never provided without the other, we can make only one optional memebr:
|
||||
|
||||
struct Limits
|
||||
{
|
||||
int _min;
|
||||
int _max;
|
||||
};
|
||||
|
||||
struct Record
|
||||
{
|
||||
optional<Limits> _limits;
|
||||
};
|
||||
|
||||
This would give us the following layout:
|
||||
|
||||
[$images/opt_align4.png]
|
||||
|
||||
[heading Optional function parameters]
|
||||
|
||||
Having function parameters of type `const optional<T>&` may incur certain unexpected run-time cost connected to copy construction of `T`. Consider the following code.
|
||||
|
||||
void fun(const optional<Big>& v)
|
||||
{
|
||||
if (v) doSomethingWith(*v);
|
||||
else doSomethingElse();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
optional<Big> ov;
|
||||
Big v;
|
||||
fun(none);
|
||||
fun(ov); // no copy
|
||||
fun(v); // copy constructor of Big
|
||||
}
|
||||
|
||||
No copy elision or move semantics can save us from copying type `Big` here. Not that we need any copy, but this is how `optional` works. In order to avoid copying in this case, one could provide second overload of `fun`:
|
||||
|
||||
void fun(const Big& v)
|
||||
{
|
||||
doSomethingWith(v);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
optional<Big> ov;
|
||||
Big v;
|
||||
fun(ov); // no copy
|
||||
fun(v); // no copy: second overload selected
|
||||
}
|
||||
|
||||
Alternatively, you could consider using an optional reference instead:
|
||||
|
||||
void fun(optional<const Big&> v) // note where the reference is
|
||||
{
|
||||
if (v) doSomethingWith(*v);
|
||||
else doSomethingElse();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
optional<Big> ov;
|
||||
Big v;
|
||||
fun(none);
|
||||
fun(ov); // doesn't compile
|
||||
fun(v); // no copy
|
||||
}
|
||||
[endsect]
|
44
doc/91_relnotes.qbk
Normal file
@ -0,0 +1,44 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2015 Andrzej Krzemienski
|
||||
|
||||
Distributed under 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)
|
||||
]
|
||||
|
||||
|
||||
[section:relnotes Release Notes]
|
||||
|
||||
[heading Boost Release 1.58]
|
||||
|
||||
* `boost::none_t` is no longer convertible from literal `0`. This avoids a bug where `optional<rational<int>> oi = 0;` would initialize an optional object with no contained value.
|
||||
* 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]
|
||||
|
||||
|
||||
[heading Boost Release 1.57]
|
||||
|
||||
* [@https://github.com/boostorg/optional/pull/9 Git pull #9]: ['"Supply `<string>` to fix C++03 compile error on `logic_error("...")`"].
|
||||
|
||||
|
||||
[heading Boost Release 1.56]
|
||||
|
||||
* Added support for rvalue references. Now `optional<T>` works with moveable but non-copyable `T`'s,
|
||||
* Improved `swap` (now uses move operations),
|
||||
* Added function `emplace()`. This is the last of the requests from [@https://svn.boost.org/trac/boost/ticket/1841 Trac #1841],
|
||||
* `optional` is moveable, including conditional `noexcept` specifications, which make it `move_if_noexcept`-friendly,
|
||||
* Using explicit operator bool() on platforms that support it ([@https://svn.boost.org/trac/boost/ticket/4227 Trac #4227]) (breaking change),
|
||||
* Forward declaration of `operator<<(ostream&, optional const&)` to prevent inadvertent incorrect serialization of optional objects,
|
||||
* Removed deprecated function `reset()` from examples ([@https://svn.boost.org/trac/boost/ticket/9005 Trac #9005]),
|
||||
* Equality comparison with `boost::none` does not require that `T` be EqualityComparable,
|
||||
* Optional rvalue references are explicitly disallowed,
|
||||
* Binding temporaries to optional references is explicitly disallowed (breaking change),
|
||||
* More ways to access the contained value, functions `value()`, `value_or()`, `value_or_eval()`,
|
||||
* Updated and reorganized documentation, added tutorial and quick guide sections.
|
||||
|
||||
|
||||
|
||||
[endsect][/ relnotes]
|
@ -9,7 +9,7 @@
|
||||
]
|
||||
|
||||
|
||||
[section Acknowledgements]
|
||||
[section:acknowledgements Acknowledgements]
|
||||
|
||||
[heading Pre-formal review]
|
||||
|
@ -20,6 +20,16 @@ xml optional
|
||||
00_optional.qbk
|
||||
;
|
||||
|
||||
install images
|
||||
:
|
||||
images/opt_align1.png
|
||||
images/opt_align2.png
|
||||
images/opt_align3.png
|
||||
images/opt_align4.png
|
||||
:
|
||||
<location>html/images
|
||||
;
|
||||
|
||||
boostbook standalone
|
||||
:
|
||||
optional
|
||||
|
@ -6,7 +6,7 @@
|
||||
<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">
|
||||
<link rel="prev" href="relnotes.html" title="Release Notes">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -19,7 +19,7 @@
|
||||
</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>
|
||||
<a accesskey="p" href="relnotes.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">
|
||||
@ -116,7 +116,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
@ -124,7 +124,7 @@
|
||||
</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>
|
||||
<a accesskey="p" href="relnotes.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>
|
||||
|
@ -75,7 +75,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<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="next" href="../acknowledgements.html" title="Acknowledgements">
|
||||
<link rel="next" href="../relnotes.html" title="Release Notes">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<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="../acknowledgements.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="../relnotes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
@ -86,7 +86,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
@ -94,7 +94,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<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="../acknowledgements.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="../relnotes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -155,7 +155,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -61,7 +61,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -61,7 +61,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -80,7 +80,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -50,7 +50,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -2084,7 +2084,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
135
doc/html/boost_optional/relnotes.html
Normal file
@ -0,0 +1,135 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Release Notes</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">
|
||||
<link rel="next" href="acknowledgements.html" title="Acknowledgements">
|
||||
</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><a accesskey="n" href="acknowledgements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_optional.relnotes"></a><a class="link" href="relnotes.html" title="Release Notes">Release Notes</a>
|
||||
</h2></div></div></div>
|
||||
<h4>
|
||||
<a name="boost_optional.relnotes.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.relnotes.boost_release_1_58"></a></span><a class="link" href="relnotes.html#boost_optional.relnotes.boost_release_1_58">Boost
|
||||
Release 1.58</a>
|
||||
</h4>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">none_t</span></code> is no longer convertible from
|
||||
literal <code class="computeroutput"><span class="number">0</span></code>. This avoids a bug
|
||||
where <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">rational</span><span class="special"><</span><span class="keyword">int</span><span class="special">>></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span></code> would
|
||||
initialize an optional object with no contained value.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Improved the trick that prevents streaming out <code class="computeroutput"><span class="identifier">optional</span></code>
|
||||
without header <code class="computeroutput"><span class="identifier">optional_io</span><span class="special">.</span><span class="identifier">hpp</span></code>
|
||||
by using safe-bool idiom. This addresses <a href="https://svn.boost.org/trac/boost/ticket/10825" target="_top">Trac
|
||||
#10825</a>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
IOStream operators are now mentioned in documentation.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Added a way to manually disable move semantics: just define macro <code class="computeroutput"><span class="identifier">BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES</span></code>.
|
||||
This can be used to work around <a href="https://svn.boost.org/trac/boost/ticket/10399" target="_top">Trac
|
||||
#10399</a>
|
||||
</li>
|
||||
</ul></div>
|
||||
<h4>
|
||||
<a name="boost_optional.relnotes.h1"></a>
|
||||
<span class="phrase"><a name="boost_optional.relnotes.boost_release_1_57"></a></span><a class="link" href="relnotes.html#boost_optional.relnotes.boost_release_1_57">Boost
|
||||
Release 1.57</a>
|
||||
</h4>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<a href="https://github.com/boostorg/optional/pull/9" target="_top">Git pull #9</a>:
|
||||
<span class="emphasis"><em>"Supply <code class="computeroutput"><span class="special"><</span><span class="identifier">string</span><span class="special">></span></code>
|
||||
to fix C++03 compile error on <code class="computeroutput"><span class="identifier">logic_error</span><span class="special">(</span><span class="string">"..."</span><span class="special">)</span></code>"</em></span>.
|
||||
</li></ul></div>
|
||||
<h4>
|
||||
<a name="boost_optional.relnotes.h2"></a>
|
||||
<span class="phrase"><a name="boost_optional.relnotes.boost_release_1_56"></a></span><a class="link" href="relnotes.html#boost_optional.relnotes.boost_release_1_56">Boost
|
||||
Release 1.56</a>
|
||||
</h4>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
Added support for rvalue references. Now <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> works with moveable but non-copyable
|
||||
<code class="computeroutput"><span class="identifier">T</span></code>'s,
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Improved <code class="computeroutput"><span class="identifier">swap</span></code> (now uses
|
||||
move operations),
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Added function <code class="computeroutput"><span class="identifier">emplace</span><span class="special">()</span></code>. This is the last of the requests from
|
||||
<a href="https://svn.boost.org/trac/boost/ticket/1841" target="_top">Trac #1841</a>,
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span></code> is moveable, including
|
||||
conditional <code class="computeroutput"><span class="keyword">noexcept</span></code> specifications,
|
||||
which make it <code class="computeroutput"><span class="identifier">move_if_noexcept</span></code>-friendly,
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Using explicit operator bool() on platforms that support it (<a href="https://svn.boost.org/trac/boost/ticket/4227" target="_top">Trac
|
||||
#4227</a>) (breaking change),
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Forward declaration of <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<(</span><span class="identifier">ostream</span><span class="special">&,</span> <span class="identifier">optional</span>
|
||||
<span class="keyword">const</span><span class="special">&)</span></code>
|
||||
to prevent inadvertent incorrect serialization of optional objects,
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Removed deprecated function <code class="computeroutput"><span class="identifier">reset</span><span class="special">()</span></code> from examples (<a href="https://svn.boost.org/trac/boost/ticket/9005" target="_top">Trac
|
||||
#9005</a>),
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Equality comparison with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span></code>
|
||||
does not require that <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
be EqualityComparable,
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Optional rvalue references are explicitly disallowed,
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Binding temporaries to optional references is explicitly disallowed (breaking
|
||||
change),
|
||||
</li>
|
||||
<li class="listitem">
|
||||
More ways to access the contained value, functions <code class="computeroutput"><span class="identifier">value</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">value_or</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">value_or_eval</span><span class="special">()</span></code>,
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Updated and reorganized documentation, added tutorial and quick guide sections.
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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><a accesskey="n" href="acknowledgements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -94,7 +94,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -170,7 +170,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -173,7 +173,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -107,7 +107,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -161,7 +161,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -183,7 +183,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
87
doc/html/boost_optional/tutorial/io_operators.html
Normal file
@ -0,0 +1,87 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>IO operators</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="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="relational_operators.html" title="Relational operators">
|
||||
<link rel="next" href="optional_references.html" title="Optional references">
|
||||
</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="relational_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.io_operators"></a><a class="link" href="io_operators.html" title="IO operators">IO operators</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
It is possible to use <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
with IO streams, provided that <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
can be used with streams. IOStream operators are defined in a separate header.
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">optional</span><span class="special">/</span><span class="identifier">optional_io</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">o1</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">oN</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">o1</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cin</span> <span class="special">>></span> <span class="identifier">oN</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
The current implementation does not guarantee any particular output. What
|
||||
it guarantees is that if streaming out and then back in <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
gives the same value, then streaming out and then back in <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
will also give back the same result:
|
||||
</p>
|
||||
<p>
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">sstream</span><span class="special">></span>
|
||||
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">optional</span><span class="special">/</span><span class="identifier">optional_io</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">o1</span> <span class="special">=</span> <span class="number">1</span><span class="special">,</span> <span class="identifier">oN</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span><span class="special">;</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">x1</span><span class="special">,</span> <span class="identifier">x2</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">s</span><span class="special">;</span>
|
||||
<span class="identifier">s</span> <span class="special"><<</span> <span class="identifier">o1</span> <span class="special"><<</span> <span class="identifier">oN</span><span class="special">;</span>
|
||||
<span class="identifier">s</span> <span class="special">>></span> <span class="identifier">x1</span> <span class="special">>></span> <span class="identifier">x2</span><span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span><span class="identifier">o1</span> <span class="special">==</span> <span class="identifier">x1</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span><span class="identifier">oN</span> <span class="special">==</span> <span class="identifier">x2</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
</p>
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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="relational_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -6,7 +6,7 @@
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="relational_operators.html" title="Relational operators">
|
||||
<link rel="prev" href="io_operators.html" title="IO operators">
|
||||
<link rel="next" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="relational_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="io_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
@ -101,7 +101,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
@ -109,7 +109,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="relational_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="io_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
223
doc/html/boost_optional/tutorial/performance_considerations.html
Normal file
@ -0,0 +1,223 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Performance considerations</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="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="type_requirements.html" title="Type requirements">
|
||||
<link rel="next" href="../../optional/reference.html" title="Reference">
|
||||
</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="type_requirements.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="../../optional/reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.performance_considerations"></a><a class="link" href="performance_considerations.html" title="Performance considerations">Performance
|
||||
considerations</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Technical details aside, the memory layout of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
is more-less this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</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">bool</span> <span class="identifier">_initialized</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">aligned_storage_t</span><span class="special"><</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">t</span><span class="special">),</span> <span class="keyword">alignof</span><span class="special">(</span><span class="identifier">T</span><span class="special">)></span> <span class="identifier">_storage</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
But for the purpose of this analysis, considering memory layouts, we can
|
||||
think of it as:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</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">bool</span> <span class="identifier">_initialized</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">_storage</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Given type <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code>, and
|
||||
assuming that <code class="computeroutput"><span class="keyword">sizeof</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">==</span>
|
||||
<span class="number">4</span></code>, we will get <code class="computeroutput"><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">>)</span>
|
||||
<span class="special">==</span> <span class="number">8</span></code>.
|
||||
This is so because of the alignment rules, for our two members we get the
|
||||
following alignment:
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../../images/opt_align1.png" alt="opt_align1"></span>
|
||||
</p>
|
||||
<p>
|
||||
This means you can fit twice as many <code class="computeroutput"><span class="keyword">int</span></code>s
|
||||
as <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code>s into
|
||||
the same space of memory. Therefore, if the size of the objects is critical
|
||||
for your application (e.g., because you want to utilize your CPU cache in
|
||||
order to gain performance) and you have determined you are willing to trade
|
||||
the code clarity, it is recommended that you simply go with type <code class="computeroutput"><span class="keyword">int</span></code> and use some 'magic value' to represent
|
||||
<span class="emphasis"><em>not-an-int</em></span>.
|
||||
</p>
|
||||
<p>
|
||||
Even if you cannot spare any value of <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
to represent <span class="emphasis"><em>not-an-int</em></span> (e.g., because every value is
|
||||
useful, or you do want to signal <span class="emphasis"><em>not-an-int</em></span> explicitly),
|
||||
at least for <code class="computeroutput"><span class="identifier">Trivial</span></code> types
|
||||
you should consider storing the value and the <code class="computeroutput"><span class="keyword">bool</span></code>
|
||||
flag representing the <span class="emphasis"><em>null-state</em></span> separately. Consider
|
||||
the following class:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">_min</span><span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">_max</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Its memory layout can be depicted as follows:
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../../images/opt_align2.png" alt="opt_align2"></span>
|
||||
</p>
|
||||
<p>
|
||||
This is exactly the same as if we had the following members:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">_has_min</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">_has_max</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
But when they are stored separately, we at least have an option to reorder
|
||||
them like this:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Record</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">_has_min</span><span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">_has_max</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
Which gives us the following layout (and smaller total size):
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../../images/opt_align3.png" alt="opt_align3"></span>
|
||||
</p>
|
||||
<p>
|
||||
Sometimes it requires detailed consideration what data we make optional.
|
||||
In our case above, if we determine that both minimum and maximum value can
|
||||
be provided or not provided together, but one is never provided without the
|
||||
other, we can make only one optional memebr:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Limits</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">int</span> <span class="identifier">_min</span><span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">_max</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">Record</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">Limits</span><span class="special">></span> <span class="identifier">_limits</span><span class="special">;</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
This would give us the following layout:
|
||||
</p>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../../images/opt_align4.png" alt="opt_align4"></span>
|
||||
</p>
|
||||
<h5>
|
||||
<a name="boost_optional.tutorial.performance_considerations.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.tutorial.performance_considerations.optional_function_parameters"></a></span><a class="link" href="performance_considerations.html#boost_optional.tutorial.performance_considerations.optional_function_parameters">Optional
|
||||
function parameters</a>
|
||||
</h5>
|
||||
<p>
|
||||
Having function parameters of type <code class="computeroutput"><span class="keyword">const</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span></code>
|
||||
may incur certain unexpected run-time cost connected to copy construction
|
||||
of <code class="computeroutput"><span class="identifier">T</span></code>. Consider the following
|
||||
code.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">fun</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">Big</span><span class="special">>&</span> <span class="identifier">v</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">v</span><span class="special">)</span> <span class="identifier">doSomethingWith</span><span class="special">(*</span><span class="identifier">v</span><span class="special">);</span>
|
||||
<span class="keyword">else</span> <span class="identifier">doSomethingElse</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">Big</span><span class="special">></span> <span class="identifier">ov</span><span class="special">;</span>
|
||||
<span class="identifier">Big</span> <span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="identifier">fun</span><span class="special">(</span><span class="identifier">none</span><span class="special">);</span>
|
||||
<span class="identifier">fun</span><span class="special">(</span><span class="identifier">ov</span><span class="special">);</span> <span class="comment">// no copy</span>
|
||||
<span class="identifier">fun</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span> <span class="comment">// copy constructor of Big</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
No copy elision or move semantics can save us from copying type <code class="computeroutput"><span class="identifier">Big</span></code> here. Not that we need any copy, but
|
||||
this is how <code class="computeroutput"><span class="identifier">optional</span></code> works.
|
||||
In order to avoid copying in this case, one could provide second overload
|
||||
of <code class="computeroutput"><span class="identifier">fun</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">fun</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Big</span><span class="special">&</span> <span class="identifier">v</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">doSomethingWith</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">Big</span><span class="special">></span> <span class="identifier">ov</span><span class="special">;</span>
|
||||
<span class="identifier">Big</span> <span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="identifier">fun</span><span class="special">(</span><span class="identifier">ov</span><span class="special">);</span> <span class="comment">// no copy</span>
|
||||
<span class="identifier">fun</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span> <span class="comment">// no copy: second overload selected</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Alternatively, you could consider using an optional reference instead:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">fun</span><span class="special">(</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="identifier">Big</span><span class="special">&></span> <span class="identifier">v</span><span class="special">)</span> <span class="comment">// note where the reference is</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">v</span><span class="special">)</span> <span class="identifier">doSomethingWith</span><span class="special">(*</span><span class="identifier">v</span><span class="special">);</span>
|
||||
<span class="keyword">else</span> <span class="identifier">doSomethingElse</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">Big</span><span class="special">></span> <span class="identifier">ov</span><span class="special">;</span>
|
||||
<span class="identifier">Big</span> <span class="identifier">v</span><span class="special">;</span>
|
||||
<span class="identifier">fun</span><span class="special">(</span><span class="identifier">none</span><span class="special">);</span>
|
||||
<span class="identifier">fun</span><span class="special">(</span><span class="identifier">ov</span><span class="special">);</span> <span class="comment">// doesn't compile</span>
|
||||
<span class="identifier">fun</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span> <span class="comment">// no copy</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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="type_requirements.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="../../optional/reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -135,7 +135,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="when_to_use_optional.html" title="When to use Optional">
|
||||
<link rel="next" href="optional_references.html" title="Optional references">
|
||||
<link rel="next" href="io_operators.html" title="IO operators">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="when_to_use_optional.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="when_to_use_optional.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="io_operators.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
@ -30,7 +30,7 @@
|
||||
<p>
|
||||
Type <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> is
|
||||
<a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a> whenever <code class="computeroutput"><span class="identifier">T</span></code> is <a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a>. Two optional
|
||||
objects containing a value compare in the same as their contained values.
|
||||
objects containing a value compare in the same way as their contained values.
|
||||
The uninitialized state of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
is treated as a distinct value, equal to itself, and unequal to any value
|
||||
of type <code class="computeroutput"><span class="identifier">T</span></code>:
|
||||
@ -99,7 +99,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
@ -107,7 +107,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="when_to_use_optional.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="when_to_use_optional.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="io_operators.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="exception_safety_guarantees.html" title="Exception Safety Guarantees">
|
||||
<link rel="next" href="../../optional/reference.html" title="Reference">
|
||||
<link rel="next" href="performance_considerations.html" title="Performance considerations">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="../../optional/reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="performance_considerations.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
@ -95,7 +95,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
@ -103,7 +103,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="../../optional/reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.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="performance_considerations.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -128,7 +128,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
BIN
doc/html/images/opt_align1.png
Normal file
After Width: | Height: | Size: 417 B |
BIN
doc/html/images/opt_align2.png
Normal file
After Width: | Height: | Size: 472 B |
BIN
doc/html/images/opt_align3.png
Normal file
After Width: | Height: | Size: 468 B |
BIN
doc/html/images/opt_align4.png
Normal file
After Width: | Height: | Size: 428 B |
@ -26,7 +26,7 @@
|
||||
<span class="firstname">Fernando Luis</span> <span class="surname">Cacciola Carballal</span>
|
||||
</h3></div></div>
|
||||
<div><p class="copyright">Copyright © 2003-2007 Fernando Luis Cacciola Carballal</p></div>
|
||||
<div><p class="copyright">Copyright © 2014 Andrzej Krzemieński</p></div>
|
||||
<div><p class="copyright">Copyright © 2014, 2015 Andrzej Krzemieński</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="optional.legal"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
@ -59,6 +59,7 @@
|
||||
use Optional</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/relational_operators.html">Relational
|
||||
operators</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/io_operators.html">IO operators</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/optional_references.html">Optional
|
||||
references</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html">Rebinding
|
||||
@ -70,6 +71,8 @@
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/exception_safety_guarantees.html">Exception
|
||||
Safety Guarantees</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/type_requirements.html">Type requirements</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/performance_considerations.html">Performance
|
||||
considerations</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="optional/reference.html">Reference</a></span></dt>
|
||||
<dd><dl>
|
||||
@ -84,6 +87,7 @@
|
||||
<dt><span class="section"><a href="boost_optional/dependencies_and_portability/optional_reference_binding.html">Optional
|
||||
Reference Binding</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_optional/relnotes.html">Release Notes</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/acknowledgements.html">Acknowledgements</a></span></dt>
|
||||
</dl>
|
||||
</div>
|
||||
@ -108,8 +112,9 @@
|
||||
It is possible that this parameter is not specified; such situation is no error.
|
||||
It is valid to not specify the parameter and in that case the program is supposed
|
||||
to behave slightly differently. Also, suppose that any possible value of type
|
||||
<code class="computeroutput"><span class="keyword">int</span></code> is a valid value for <code class="computeroutput"><span class="string">"MaxValue"</span></code>, so we cannot jut use <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code> to represent
|
||||
the absence of the parameter in the config file.
|
||||
<code class="computeroutput"><span class="keyword">int</span></code> is a valid value for <code class="computeroutput"><span class="string">"MaxValue"</span></code>, so we cannot just use
|
||||
<code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>
|
||||
to represent the absence of the parameter in the config file.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="optional.introduction.h1"></a>
|
||||
@ -133,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: September 12, 2014 at 09:54:26 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: January 21, 2015 at 13:59:23 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<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="../boost_optional/tutorial/type_requirements.html" title="Type requirements">
|
||||
<link rel="prev" href="../boost_optional/tutorial/performance_considerations.html" title="Performance considerations">
|
||||
<link rel="next" href="../boost_optional/reference/detailed_semantics.html" title="Detailed Semantics">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../boost_optional/tutorial/type_requirements.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><a accesskey="n" href="../boost_optional/reference/detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="../boost_optional/tutorial/performance_considerations.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><a accesskey="n" href="../boost_optional/reference/detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@ -173,7 +173,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
@ -181,7 +181,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../boost_optional/tutorial/type_requirements.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><a accesskey="n" href="../boost_optional/reference/detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="../boost_optional/tutorial/performance_considerations.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><a accesskey="n" href="../boost_optional/reference/detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -33,6 +33,7 @@
|
||||
use Optional</a></span></dt>
|
||||
<dt><span class="section"><a href="../boost_optional/tutorial/relational_operators.html">Relational
|
||||
operators</a></span></dt>
|
||||
<dt><span class="section"><a href="../boost_optional/tutorial/io_operators.html">IO operators</a></span></dt>
|
||||
<dt><span class="section"><a href="../boost_optional/tutorial/optional_references.html">Optional
|
||||
references</a></span></dt>
|
||||
<dt><span class="section"><a href="../boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html">Rebinding
|
||||
@ -44,6 +45,8 @@
|
||||
<dt><span class="section"><a href="../boost_optional/tutorial/exception_safety_guarantees.html">Exception
|
||||
Safety Guarantees</a></span></dt>
|
||||
<dt><span class="section"><a href="../boost_optional/tutorial/type_requirements.html">Type requirements</a></span></dt>
|
||||
<dt><span class="section"><a href="../boost_optional/tutorial/performance_considerations.html">Performance
|
||||
considerations</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
@ -139,7 +142,7 @@
|
||||
</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 © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014, 2015 Andrzej Krzemień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>
|
||||
|
BIN
doc/images/opt_align1.png
Normal file
After Width: | Height: | Size: 417 B |
BIN
doc/images/opt_align2.png
Normal file
After Width: | Height: | Size: 472 B |
BIN
doc/images/opt_align3.png
Normal file
After Width: | Height: | Size: 468 B |
BIN
doc/images/opt_align4.png
Normal file
After Width: | Height: | Size: 428 B |
@ -1,4 +1,5 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2014 Andrzej Krzemienski.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -20,7 +21,31 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
|
||||
none_t const none = (static_cast<none_t>(0)) ;
|
||||
#else
|
||||
|
||||
namespace detail { namespace optional_detail {
|
||||
|
||||
// the trick here is to make boost::none defined once as a global but in a header file
|
||||
template <typename T>
|
||||
struct none_instance
|
||||
{
|
||||
static const T instance;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
const T none_instance<T>::instance = T(); // global, but because 'tis a template, no cpp file required
|
||||
|
||||
} } // namespace detail::optional_detail
|
||||
|
||||
|
||||
namespace {
|
||||
// TU-local
|
||||
const none_t& none = detail::optional_detail::none_instance<none_t>::instance;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// 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
|
||||
@ -14,9 +15,12 @@
|
||||
|
||||
namespace boost {
|
||||
|
||||
#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
|
||||
namespace detail { struct none_helper{}; }
|
||||
|
||||
typedef int detail::none_helper::*none_t ;
|
||||
#else
|
||||
class none_t {};
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2014 Andrzej Krzemienski.
|
||||
// Copyright (C) 2014, 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -57,6 +57,10 @@
|
||||
|
||||
#include <boost/optional/optional_fwd.hpp>
|
||||
|
||||
#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES)
|
||||
#define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
|
||||
// AFAICT only Intel 7 correctly resolves the overload set
|
||||
// that includes the in-place factory taking functions,
|
||||
@ -148,7 +152,7 @@ struct types_when_isnt_ref
|
||||
{
|
||||
typedef T const& reference_const_type ;
|
||||
typedef T & reference_type ;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
typedef T && rval_reference_type ;
|
||||
typedef T && reference_type_of_temporary_wrapper;
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
@ -171,7 +175,7 @@ struct types_when_is_ref
|
||||
|
||||
typedef raw_type& reference_const_type ;
|
||||
typedef raw_type& reference_type ;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
typedef BOOST_DEDUCED_TYPENAME remove_const<raw_type>::type&& rval_reference_type ;
|
||||
typedef raw_type& reference_type_of_temporary_wrapper;
|
||||
static reference_type move(reference_type r) { return r; }
|
||||
@ -226,7 +230,7 @@ class optional_base : public optional_tag
|
||||
protected:
|
||||
typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
|
||||
#endif
|
||||
@ -255,7 +259,7 @@ class optional_base : public optional_tag
|
||||
construct(val);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// move-construct an optional<T> initialized from an rvalue-ref to 'val'.
|
||||
// Can throw if T::T(T&&) does
|
||||
optional_base ( rval_reference_type val )
|
||||
@ -286,7 +290,7 @@ class optional_base : public optional_tag
|
||||
construct(rhs.get_impl());
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Creates a deep move of another optional<T>
|
||||
// Can throw if T::T(T&&) does
|
||||
optional_base ( optional_base&& rhs )
|
||||
@ -298,7 +302,7 @@ class optional_base : public optional_tag
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
|
||||
template<class Expr, class PtrExpr>
|
||||
explicit optional_base ( Expr&& expr, PtrExpr const* tag )
|
||||
@ -342,7 +346,7 @@ class optional_base : public optional_tag
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Assigns from another optional<T> (deep-moves the rhs value)
|
||||
void assign ( optional_base&& rhs )
|
||||
{
|
||||
@ -377,7 +381,7 @@ class optional_base : public optional_tag
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
|
||||
template<class U>
|
||||
void assign ( optional<U>&& rhs )
|
||||
@ -405,7 +409,7 @@ class optional_base : public optional_tag
|
||||
else construct(val);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Assigns from a T (deep-moves the rhs value)
|
||||
void assign ( rval_reference_type val )
|
||||
{
|
||||
@ -421,7 +425,7 @@ class optional_base : public optional_tag
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
template<class Expr, class ExprPtr>
|
||||
void assign_expr ( Expr&& expr, ExprPtr const* tag )
|
||||
{
|
||||
@ -466,7 +470,7 @@ class optional_base : public optional_tag
|
||||
m_initialized = true ;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
void construct ( rval_reference_type val )
|
||||
{
|
||||
::new (m_storage.address()) internal_type( types::move(val) ) ;
|
||||
@ -475,7 +479,7 @@ class optional_base : public optional_tag
|
||||
#endif
|
||||
|
||||
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
// Constructs in-place
|
||||
// upon exception *this is always uninitialized
|
||||
template<class... Args>
|
||||
@ -485,7 +489,7 @@ class optional_base : public optional_tag
|
||||
::new (m_storage.address()) internal_type( boost::forward<Args>(args)... );
|
||||
m_initialized = true ;
|
||||
}
|
||||
#elif (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
||||
template<class Arg>
|
||||
void emplace_assign ( Arg&& arg )
|
||||
{
|
||||
@ -513,7 +517,7 @@ class optional_base : public optional_tag
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Constructs in-place using the given factory
|
||||
template<class Expr>
|
||||
void construct ( Expr&& factory, in_place_factory_base const* )
|
||||
@ -584,7 +588,7 @@ class optional_base : public optional_tag
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Constructs using any expression implicitly convertible to the single argument
|
||||
// of a one-argument T constructor.
|
||||
// Converting constructions of optional<T> from optional<U> uses this function with
|
||||
@ -642,7 +646,7 @@ class optional_base : public optional_tag
|
||||
// For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
|
||||
// instead of choosing the wrong overload
|
||||
//
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
|
||||
template<class Expr>
|
||||
void construct ( Expr&& expr, optional_tag const* )
|
||||
@ -673,7 +677,7 @@ class optional_base : public optional_tag
|
||||
|
||||
void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
|
||||
void assign_value ( argument_type val, is_reference_tag ) { construct(val); }
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast<rval_reference_type>(val); }
|
||||
void assign_value ( rval_reference_type val, is_reference_tag ) { construct( static_cast<rval_reference_type>(val) ); }
|
||||
#endif
|
||||
@ -750,7 +754,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
|
||||
#endif
|
||||
@ -770,7 +774,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
// Can throw if T::T(T const&) does
|
||||
optional ( argument_type val ) : base(val) {}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Creates an optional<T> initialized with 'move(val)'.
|
||||
// Can throw if T::T(T &&) does
|
||||
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
|
||||
@ -795,7 +799,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
this->construct(rhs.get());
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Creates a deep move of another convertible optional<U>
|
||||
// Requires a valid conversion from U to T.
|
||||
// Can throw if T::T(U&&) does
|
||||
@ -819,7 +823,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
// even though explicit overloads are present for these.
|
||||
// Depending on the above some T ctor is called.
|
||||
// Can throw if the resolved T ctor throws.
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
|
||||
|
||||
template<class Expr>
|
||||
@ -834,14 +838,14 @@ class optional : public optional_detail::optional_base<T>
|
||||
#else
|
||||
template<class Expr>
|
||||
explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
|
||||
#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
#endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
|
||||
// Creates a deep copy of another optional<T>
|
||||
// Can throw if T::T(T const&) does
|
||||
optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Creates a deep move of another optional<T>
|
||||
// Can throw if T::T(T&&) does
|
||||
optional ( optional && rhs )
|
||||
@ -856,7 +860,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
|
||||
// Assigns from an expression. See corresponding constructor.
|
||||
// Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
|
||||
template<class Expr>
|
||||
BOOST_DEDUCED_TYPENAME boost::disable_if_c<
|
||||
@ -878,7 +882,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
this->assign_expr(expr,boost::addressof(expr));
|
||||
return *this ;
|
||||
}
|
||||
#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
#endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
|
||||
|
||||
// Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value)
|
||||
@ -891,7 +895,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
return *this ;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
|
||||
// Requires a valid conversion from U to T.
|
||||
// Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
|
||||
@ -912,7 +916,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
return *this ;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Assigns from another optional<T> (deep-moves the rhs value)
|
||||
optional& operator= ( optional && rhs )
|
||||
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
|
||||
@ -930,7 +934,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
return *this ;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Assigns from a T (deep-moves the rhs value)
|
||||
optional& operator= ( rval_reference_type val )
|
||||
{
|
||||
@ -949,7 +953,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
return *this ;
|
||||
}
|
||||
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
// Constructs in-place
|
||||
// upon exception *this is always uninitialized
|
||||
template<class... Args>
|
||||
@ -957,7 +961,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
{
|
||||
this->emplace_assign( boost::forward<Args>(args)... );
|
||||
}
|
||||
#elif (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
||||
template<class Arg>
|
||||
void emplace ( Arg&& arg )
|
||||
{
|
||||
@ -1004,7 +1008,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
// Returns a reference to the value if this is initialized, otherwise,
|
||||
// the behaviour is UNDEFINED
|
||||
// No-throw
|
||||
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
|
||||
#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()) ; }
|
||||
@ -1013,7 +1017,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
reference_type operator *() { return this->get() ; }
|
||||
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
|
||||
|
||||
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
|
||||
#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
|
||||
reference_const_type value() const&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
@ -1075,7 +1079,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
else
|
||||
return boost::forward<U>(v);
|
||||
}
|
||||
#elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
value_type value_or ( U&& v ) const
|
||||
{
|
||||
@ -1130,7 +1134,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
} ;
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
template<class T>
|
||||
class optional<T&&>
|
||||
{
|
||||
@ -1226,10 +1230,13 @@ get_pointer ( optional<T>& opt )
|
||||
return opt.get_ptr() ;
|
||||
}
|
||||
|
||||
// Forward declaration to prevent operator safe-bool from being used.
|
||||
template<class CharType, class CharTrait, class T>
|
||||
// The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header.
|
||||
template<class CharType, class CharTrait>
|
||||
std::basic_ostream<CharType, CharTrait>&
|
||||
operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v);
|
||||
operator<<(std::basic_ostream<CharType, CharTrait>& out, optional_detail::optional_tag const& v)
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output boost::optional, include header <boost/optional/optional_io.hpp>");
|
||||
}
|
||||
|
||||
// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
|
||||
// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
|
||||
@ -1437,7 +1444,7 @@ struct swap_selector<true>
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
template<>
|
||||
struct swap_selector<false>
|
||||
{
|
||||
@ -1494,7 +1501,7 @@ struct swap_selector<false>
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
|
||||
} // namespace optional_detail
|
||||
|
||||
|
@ -16,21 +16,33 @@
|
||||
#include <ostream>
|
||||
|
||||
#include <boost/none.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include "boost/optional/optional.hpp"
|
||||
#include "boost/utility/value_init.hpp"
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class CharType, class CharTrait>
|
||||
inline
|
||||
std::basic_ostream<CharType, CharTrait>&
|
||||
operator<<(std::basic_ostream<CharType, CharTrait>& out, none_t const&)
|
||||
{
|
||||
if (out.good())
|
||||
{
|
||||
out << "--";
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
template<class CharType, class CharTrait, class T>
|
||||
inline
|
||||
std::basic_ostream<CharType, CharTrait>&
|
||||
operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v)
|
||||
{
|
||||
if ( out.good() )
|
||||
if (out.good())
|
||||
{
|
||||
if ( !v )
|
||||
if (!v)
|
||||
out << "--" ;
|
||||
else out << ' ' << *v ;
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
{
|
||||
"key": "optional",
|
||||
"boost-version": "1.30.0",
|
||||
"name": "Optional",
|
||||
"authors": [
|
||||
"Fernando Cacciola"
|
||||
],
|
||||
"description": "Discriminated-union wrapper for optional values.",
|
||||
"description": "A value-semantic, type-safe wrapper for representing 'optional' (or 'nullable') objects of a given type. An optional object may or may not contain a value of the underlying type.",
|
||||
"category": [
|
||||
"Miscellaneous"
|
||||
"Data structures"
|
||||
],
|
||||
"maintainers": [
|
||||
"Fernando Cacciola <fernando_cacciola -at- ciudad.com.ar>",
|
||||
|
@ -17,15 +17,26 @@ import testing ;
|
||||
{
|
||||
test-suite optional :
|
||||
[ run optional_test.cpp ]
|
||||
[ run optional_test_swap.cpp ]
|
||||
[ run optional_test_conversions_from_U.cpp ]
|
||||
[ run optional_test_tie.cpp ]
|
||||
[ run optional_test_ref.cpp ]
|
||||
[ run optional_test_inplace.cpp ]
|
||||
[ run optional_test_ref_assign_portable_minimum.cpp ]
|
||||
[ run optional_test_ref_assign_mutable_int.cpp ]
|
||||
[ run optional_test_ref_assign_const_int.cpp ]
|
||||
[ run optional_test_ref_converting_ctor.cpp ]
|
||||
[ run optional_test_ref_convert_assign_non_int.cpp ]
|
||||
[ 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_inplace_factory.cpp ]
|
||||
[ run optional_test_io.cpp ]
|
||||
[ run optional_test_move.cpp ]
|
||||
[ run optional_test_noexcept_move.cpp ]
|
||||
[ run optional_test_equals_none.cpp ]
|
||||
[ run optional_test_value_access.cpp ]
|
||||
[ run optional_test_emplace.cpp ]
|
||||
[ run optional_test_minimum_requirements.cpp ]
|
||||
[ run optional_test_msvc_bug_workaround.cpp ]
|
||||
[ compile-fail optional_test_fail1.cpp ]
|
||||
[ compile-fail optional_test_fail3a.cpp ]
|
||||
[ compile-fail optional_test_fail3b.cpp ]
|
||||
@ -41,7 +52,9 @@ import testing ;
|
||||
[ compile-fail optional_test_ref_fail_init_from_Urefref.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_fail_convert_from_null.cpp ]
|
||||
[ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ]
|
||||
[ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ]
|
||||
[ compile-fail optional_test_fail_io_without_io.cpp ]
|
||||
;
|
||||
}
|
||||
|
197
test/optional_ref_assign_test_defs.hpp
Normal file
@ -0,0 +1,197 @@
|
||||
// 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
|
||||
|
||||
#ifndef BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP
|
||||
#define BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/addressof.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
using boost::addressof;
|
||||
|
||||
template <typename T>
|
||||
void test_copy_assignment_for_const()
|
||||
{
|
||||
const typename concrete_type_of<T>::type v(2);
|
||||
optional<const T&> o;
|
||||
o = optional<const T&>(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(o != none);
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST(val(*o) == val(v));
|
||||
BOOST_TEST(val(*o) == 2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_copy_assignment_for_noconst_const()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2);
|
||||
optional<const T&> o;
|
||||
o = optional<const T&>(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(o != none);
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST(val(*o) == val(v));
|
||||
BOOST_TEST(val(*o) == 2);
|
||||
|
||||
val(v) = 9;
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 9);
|
||||
BOOST_TEST_EQ(val(v), 9);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_copy_assignment_for()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2);
|
||||
optional<T&> o;
|
||||
o = optional<T&>(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(o != none);
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST(val(*o) == val(v));
|
||||
BOOST_TEST(val(*o) == 2);
|
||||
|
||||
val(v) = 9;
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 9);
|
||||
BOOST_TEST_EQ(val(v), 9);
|
||||
|
||||
val(*o) = 7;
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 7);
|
||||
BOOST_TEST_EQ(val(v), 7);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_rebinding_assignment_semantics_const()
|
||||
{
|
||||
const typename concrete_type_of<T>::type v(2), w(7);
|
||||
optional<const T&> o(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 2);
|
||||
|
||||
o = optional<const T&>(w);
|
||||
BOOST_TEST_EQ(val(v), 2);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(addressof(*o) != addressof(v));
|
||||
BOOST_TEST_NE(val(*o), val(v));
|
||||
BOOST_TEST_NE(val(*o), 2);
|
||||
|
||||
BOOST_TEST(addressof(*o) == addressof(w));
|
||||
BOOST_TEST_EQ(val(*o), val(w));
|
||||
BOOST_TEST_EQ(val(*o), 7);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_rebinding_assignment_semantics_noconst_const()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2), w(7);
|
||||
optional<const T&> o(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 2);
|
||||
|
||||
o = optional<const T&>(w);
|
||||
BOOST_TEST_EQ(val(v), 2);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(addressof(*o) != addressof(v));
|
||||
BOOST_TEST_NE(val(*o), val(v));
|
||||
BOOST_TEST_NE(val(*o), 2);
|
||||
|
||||
BOOST_TEST(addressof(*o) == addressof(w));
|
||||
BOOST_TEST_EQ(val(*o), val(w));
|
||||
BOOST_TEST_EQ(val(*o), 7);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_rebinding_assignment_semantics()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2), w(7);
|
||||
optional<T&> o(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(addressof(*o) == addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 2);
|
||||
|
||||
o = optional<T&>(w);
|
||||
BOOST_TEST_EQ(val(v), 2);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(addressof(*o) != addressof(v));
|
||||
BOOST_TEST_NE(val(*o), val(v));
|
||||
BOOST_TEST_NE(val(*o), 2);
|
||||
|
||||
BOOST_TEST(addressof(*o) == addressof(w));
|
||||
BOOST_TEST_EQ(val(*o), val(w));
|
||||
BOOST_TEST_EQ(val(*o), 7);
|
||||
|
||||
val(*o) = 8;
|
||||
BOOST_TEST(addressof(*o) == addressof(w));
|
||||
BOOST_TEST_EQ(val(*o), val(w));
|
||||
BOOST_TEST_EQ(val(*o), 8);
|
||||
BOOST_TEST_EQ(val(w), 8);
|
||||
BOOST_TEST_EQ(val(v), 2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_converting_assignment()
|
||||
{
|
||||
typename concrete_type_of<T>::type v1(1), v2(2), v3(3);
|
||||
optional<T&> oA(v1), oB(none);
|
||||
|
||||
oA = v2;
|
||||
BOOST_TEST(oA);
|
||||
BOOST_TEST(addressof(*oA) == addressof(v2));
|
||||
|
||||
oB = v3;
|
||||
BOOST_TEST(oB);
|
||||
BOOST_TEST(addressof(*oB) == addressof(v3));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_converting_assignment_for_noconst_const()
|
||||
{
|
||||
typename concrete_type_of<T>::type v1(1), v2(2), v3(3);
|
||||
optional<const T&> oA(v1), oB(none);
|
||||
|
||||
oA = v2;
|
||||
BOOST_TEST(oA);
|
||||
BOOST_TEST(addressof(*oA) == addressof(v2));
|
||||
|
||||
oB = v3;
|
||||
BOOST_TEST(oB);
|
||||
BOOST_TEST(addressof(*oB) == addressof(v3));
|
||||
}
|
||||
|
||||
#endif //BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP
|
||||
|
@ -906,372 +906,6 @@ void test_no_implicit_conversions()
|
||||
test_no_implicit_conversions_impl(p);
|
||||
}
|
||||
|
||||
struct A {} ;
|
||||
void test_conversions1()
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
|
||||
char c = 20 ;
|
||||
optional<char> opt0(c);
|
||||
optional<int> opt1(opt0);
|
||||
BOOST_CHECK(*opt1 == static_cast<int>(c));
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
|
||||
float f = 21.22f ;
|
||||
double d = f ;
|
||||
optional<float> opt2(f) ;
|
||||
optional<double> opt3 ;
|
||||
opt3 = opt2 ;
|
||||
BOOST_CHECK(*opt3 == d);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_conversions2()
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
char c = 20 ;
|
||||
optional<int> opt(c);
|
||||
BOOST_CHECK( get(opt) == static_cast<int>(c));
|
||||
|
||||
float f = 21.22f ;
|
||||
optional<double> opt1;
|
||||
opt1 = f ;
|
||||
BOOST_CHECK(*get(&opt1) == static_cast<double>(f));
|
||||
}
|
||||
|
||||
|
||||
namespace optional_swap_test
|
||||
{
|
||||
class default_ctor_exception : public std::exception {} ;
|
||||
class copy_ctor_exception : public std::exception {} ;
|
||||
class assignment_exception : public std::exception {} ;
|
||||
|
||||
//
|
||||
// Base class for swap test classes. Its assignment should not be called, when swapping
|
||||
// optional<T> objects. (The default std::swap would do so.)
|
||||
//
|
||||
class base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
base_class_with_forbidden_assignment & operator=(const base_class_with_forbidden_assignment &)
|
||||
{
|
||||
BOOST_CHECK(!"The assignment should not be used while swapping!");
|
||||
throw assignment_exception();
|
||||
}
|
||||
|
||||
virtual ~base_class_with_forbidden_assignment() {}
|
||||
};
|
||||
|
||||
//
|
||||
// Class without default constructor
|
||||
//
|
||||
class class_without_default_ctor : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
char data;
|
||||
explicit class_without_default_ctor(char arg) : data(arg) {}
|
||||
};
|
||||
|
||||
//
|
||||
// Class whose default constructor should not be used by optional::swap!
|
||||
//
|
||||
class class_whose_default_ctor_should_not_be_used : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
char data;
|
||||
explicit class_whose_default_ctor_should_not_be_used(char arg) : data(arg) {}
|
||||
|
||||
class_whose_default_ctor_should_not_be_used()
|
||||
{
|
||||
BOOST_CHECK(!"This default constructor should not be used while swapping!");
|
||||
throw default_ctor_exception();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Class whose default constructor should be used by optional::swap.
|
||||
// Its copy constructor should be avoided!
|
||||
//
|
||||
class class_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
char data;
|
||||
explicit class_whose_default_ctor_should_be_used(char arg) : data(arg) { }
|
||||
|
||||
class_whose_default_ctor_should_be_used() : data('\0') { }
|
||||
|
||||
class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &)
|
||||
{
|
||||
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
|
||||
throw copy_ctor_exception();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Class template whose default constructor should be used by optional::swap.
|
||||
// Its copy constructor should be avoided!
|
||||
//
|
||||
template <class T>
|
||||
class template_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
T data;
|
||||
explicit template_whose_default_ctor_should_be_used(T arg) : data(arg) { }
|
||||
|
||||
template_whose_default_ctor_should_be_used() : data('\0') { }
|
||||
|
||||
template_whose_default_ctor_should_be_used(const template_whose_default_ctor_should_be_used &)
|
||||
{
|
||||
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
|
||||
throw copy_ctor_exception();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Class whose explicit constructor should be used by optional::swap.
|
||||
// Its other constructors should be avoided!
|
||||
//
|
||||
class class_whose_explicit_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
char data;
|
||||
explicit class_whose_explicit_ctor_should_be_used(char arg) : data(arg) { }
|
||||
|
||||
class_whose_explicit_ctor_should_be_used()
|
||||
{
|
||||
BOOST_CHECK(!"This default constructor should not be used while swapping!");
|
||||
throw default_ctor_exception();
|
||||
}
|
||||
|
||||
class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &)
|
||||
{
|
||||
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
|
||||
throw copy_ctor_exception();
|
||||
}
|
||||
};
|
||||
|
||||
void swap(class_whose_default_ctor_should_not_be_used & lhs, class_whose_default_ctor_should_not_be_used & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
void swap(class_whose_default_ctor_should_be_used & lhs, class_whose_default_ctor_should_be_used & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
void swap(class_without_default_ctor & lhs, class_without_default_ctor & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
void swap(class_whose_explicit_ctor_should_be_used & lhs, class_whose_explicit_ctor_should_be_used & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void swap(template_whose_default_ctor_should_be_used<T> & lhs, template_whose_default_ctor_should_be_used<T> & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
//
|
||||
// optional<T>::swap should be customized when neither the copy constructor
|
||||
// nor the default constructor of T are supposed to be used when swapping, e.g.,
|
||||
// for the following type T = class_whose_explicit_ctor_should_be_used.
|
||||
//
|
||||
void swap(boost::optional<class_whose_explicit_ctor_should_be_used> & x, boost::optional<class_whose_explicit_ctor_should_be_used> & y)
|
||||
{
|
||||
bool hasX(x);
|
||||
bool hasY(y);
|
||||
|
||||
if ( !hasX && !hasY )
|
||||
return;
|
||||
|
||||
if( !hasX )
|
||||
x = boost::in_place('\0');
|
||||
else if ( !hasY )
|
||||
y = boost::in_place('\0');
|
||||
|
||||
optional_swap_test::swap(*x,*y);
|
||||
|
||||
if( !hasX )
|
||||
y = boost::none ;
|
||||
else if( !hasY )
|
||||
x = boost::none ;
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace optional_swap_test.
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
//
|
||||
// Compile time tweaking on whether or not swap should use the default constructor:
|
||||
//
|
||||
|
||||
template <> struct optional_swap_should_use_default_constructor<
|
||||
optional_swap_test::class_whose_default_ctor_should_be_used> : mpl::true_ {} ;
|
||||
|
||||
template <> struct optional_swap_should_use_default_constructor<
|
||||
optional_swap_test::class_whose_default_ctor_should_not_be_used> : mpl::false_ {} ;
|
||||
|
||||
template <class T> struct optional_swap_should_use_default_constructor<
|
||||
optional_swap_test::template_whose_default_ctor_should_be_used<T> > : mpl::true_ {} ;
|
||||
|
||||
|
||||
//
|
||||
// Specialization of boost::swap:
|
||||
//
|
||||
template <>
|
||||
void swap(optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & x, optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
namespace std {
|
||||
|
||||
//
|
||||
// Specializations of std::swap:
|
||||
//
|
||||
|
||||
template <>
|
||||
void swap(optional_swap_test::class_whose_default_ctor_should_be_used & x, optional_swap_test::class_whose_default_ctor_should_be_used & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swap(optional_swap_test::class_whose_default_ctor_should_not_be_used & x, optional_swap_test::class_whose_default_ctor_should_not_be_used & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swap(optional_swap_test::class_without_default_ctor & x, optional_swap_test::class_without_default_ctor & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swap(optional_swap_test::class_whose_explicit_ctor_should_be_used & x, optional_swap_test::class_whose_explicit_ctor_should_be_used & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
//
|
||||
// Tests whether the swap function works properly for optional<T>.
|
||||
// Assumes that T has one data member, of type char.
|
||||
// Returns true iff the test is passed.
|
||||
//
|
||||
template <class T>
|
||||
bool test_swap_function( T const* )
|
||||
{
|
||||
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||
try
|
||||
{
|
||||
optional<T> obj1;
|
||||
optional<T> obj2('a');
|
||||
|
||||
// Self-swap should not have any effect.
|
||||
swap(obj1, obj1);
|
||||
swap(obj2, obj2);
|
||||
BOOST_CHECK(!obj1);
|
||||
BOOST_CHECK(!!obj2 && obj2->data == 'a');
|
||||
|
||||
// Call non-member swap.
|
||||
swap(obj1, obj2);
|
||||
|
||||
// Test if obj1 and obj2 are really swapped.
|
||||
BOOST_CHECK(!!obj1 && obj1->data == 'a');
|
||||
BOOST_CHECK(!obj2);
|
||||
|
||||
// Call non-member swap one more time.
|
||||
swap(obj1, obj2);
|
||||
|
||||
// Test if obj1 and obj2 are swapped back.
|
||||
BOOST_CHECK(!obj1);
|
||||
BOOST_CHECK(!!obj2 && obj2->data == 'a');
|
||||
}
|
||||
catch(const std::exception &)
|
||||
{
|
||||
// The swap function should not throw, for our test cases.
|
||||
return false ;
|
||||
}
|
||||
return boost::minimal_test::errors_counter() == counter_before_test ;
|
||||
}
|
||||
|
||||
//
|
||||
// Tests whether the optional<T>::swap member function works properly.
|
||||
// Assumes that T has one data member, of type char.
|
||||
// Returns true iff the test is passed.
|
||||
//
|
||||
template <class T>
|
||||
bool test_swap_member_function( T const* )
|
||||
{
|
||||
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||
try
|
||||
{
|
||||
optional<T> obj1;
|
||||
optional<T> obj2('a');
|
||||
|
||||
// Self-swap should not have any effect.
|
||||
obj1.swap(obj1);
|
||||
obj2.swap(obj2);
|
||||
BOOST_CHECK(!obj1);
|
||||
BOOST_CHECK(!!obj2 && obj2->data == 'a');
|
||||
|
||||
// Call member swap.
|
||||
obj1.swap(obj2);
|
||||
|
||||
// Test if obj1 and obj2 are really swapped.
|
||||
BOOST_CHECK(!!obj1 && obj1->data == 'a');
|
||||
BOOST_CHECK(!obj2);
|
||||
|
||||
// Call member swap one more time.
|
||||
obj1.swap(obj2);
|
||||
|
||||
// Test if obj1 and obj2 are swapped back.
|
||||
BOOST_CHECK(!obj1);
|
||||
BOOST_CHECK(!!obj2 && obj2->data == 'a');
|
||||
}
|
||||
catch(const std::exception &)
|
||||
{
|
||||
// The optional<T>::swap member function should not throw, for our test cases.
|
||||
return false ;
|
||||
}
|
||||
return boost::minimal_test::errors_counter() == counter_before_test ;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Tests compile time tweaking of swap, by means of
|
||||
// optional_swap_should_use_default_constructor.
|
||||
//
|
||||
void test_swap_tweaking()
|
||||
{
|
||||
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) );
|
||||
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
|
||||
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
|
||||
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
|
||||
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
|
||||
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) );
|
||||
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
|
||||
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
|
||||
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
|
||||
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
|
||||
}
|
||||
|
||||
// Test for support for classes with overridden operator&
|
||||
class CustomAddressOfClass
|
||||
@ -1307,9 +941,6 @@ int test_main( int, char* [] )
|
||||
test_with_class_type();
|
||||
test_with_builtin_types();
|
||||
test_no_implicit_conversions();
|
||||
test_conversions1();
|
||||
test_conversions2();
|
||||
test_swap_tweaking();
|
||||
test_custom_addressof_operator();
|
||||
}
|
||||
catch ( ... )
|
||||
|
@ -51,6 +51,8 @@ using boost::get_pointer ;
|
||||
// via the safe_bool operator.
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1
|
||||
#define BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
#else
|
||||
#define BOOST_OPTIONAL_NO_NULL_COMPARE // Andrzej: I also disable 0 comparison everywhere
|
||||
#endif
|
||||
|
||||
#define ARG(T) (static_cast< T const* >(0))
|
||||
|
111
test/optional_test_conversions_from_U.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
// 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 "boost/core/lightweight_test.hpp"
|
||||
|
||||
using boost::optional;
|
||||
|
||||
|
||||
// testing types:
|
||||
// X is convertible to Y
|
||||
// ADeriv is convertible to ABase
|
||||
struct X
|
||||
{
|
||||
int val;
|
||||
explicit X(int v) : val(v) {}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int yval;
|
||||
Y(X const& x) : yval(x.val) {}
|
||||
friend bool operator==(Y const& l, Y const& r) { return l.yval == r.yval; }
|
||||
};
|
||||
|
||||
struct ABase
|
||||
{
|
||||
int val;
|
||||
explicit ABase(int v) : val(v) {}
|
||||
friend bool operator==(ABase const& l, ABase const& r) { return l.val == r.val; }
|
||||
};
|
||||
|
||||
struct ADeriv : ABase
|
||||
{
|
||||
explicit ADeriv(int v) : ABase(v) {}
|
||||
};
|
||||
|
||||
|
||||
template <typename T, typename U>
|
||||
void test_convert_optional_U_to_optional_T_for()
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
|
||||
{
|
||||
optional<U> ou(U(8));
|
||||
optional<T> ot1(ou);
|
||||
BOOST_TEST(ot1);
|
||||
BOOST_TEST(*ot1 == T(*ou));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
|
||||
{
|
||||
optional<U> ou(U(8));
|
||||
optional<T> ot2;
|
||||
ot2 = ou;
|
||||
BOOST_TEST(ot2);
|
||||
BOOST_TEST(*ot2 == T(*ou));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_convert_optional_U_to_optional_T()
|
||||
{
|
||||
test_convert_optional_U_to_optional_T_for<Y, X>();
|
||||
test_convert_optional_U_to_optional_T_for<ABase, ADeriv>();
|
||||
test_convert_optional_U_to_optional_T_for<long, short>();
|
||||
test_convert_optional_U_to_optional_T_for<double, float>();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
void test_convert_U_to_optional_T_for()
|
||||
{
|
||||
U u(8);
|
||||
optional<T> ot1(u);
|
||||
BOOST_TEST(ot1);
|
||||
BOOST_TEST(*ot1 == T(u));
|
||||
|
||||
optional<T> ot2;
|
||||
ot2 = u;
|
||||
BOOST_TEST(ot2);
|
||||
BOOST_TEST(*ot2 == T(u));
|
||||
}
|
||||
|
||||
void test_convert_U_to_optional_T()
|
||||
{
|
||||
test_convert_U_to_optional_T_for<Y, X>();
|
||||
test_convert_U_to_optional_T_for<ABase, ADeriv>();
|
||||
test_convert_U_to_optional_T_for<long, short>();
|
||||
test_convert_U_to_optional_T_for<double, float>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_convert_optional_U_to_optional_T();
|
||||
test_convert_U_to_optional_T();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -8,19 +8,6 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
// Revisions:
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||
#include "boost/static_assert.hpp"
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
@ -28,15 +15,15 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "boost/none.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
|
||||
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
|
||||
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
class Guard
|
||||
@ -68,36 +55,36 @@ void test_emplace()
|
||||
optional<Guard> o;
|
||||
|
||||
o.emplace();
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(0 == o->which_ctor);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(0 == o->which_ctor);
|
||||
|
||||
o.emplace(i, 2.0);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(1 == o->which_ctor);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(1 == o->which_ctor);
|
||||
|
||||
o.emplace(1, d);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(2 == o->which_ctor);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(2 == o->which_ctor);
|
||||
|
||||
o.emplace(1, 2.0);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(3 == o->which_ctor);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(3 == o->which_ctor);
|
||||
|
||||
o.emplace(i, d);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(4 == o->which_ctor);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(4 == o->which_ctor);
|
||||
|
||||
o.emplace(cs);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(5 == o->which_ctor);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(5 == o->which_ctor);
|
||||
|
||||
o.emplace(ms);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(6 == o->which_ctor);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(6 == o->which_ctor);
|
||||
|
||||
o.emplace(std::string());
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(7 == o->which_ctor);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(7 == o->which_ctor);
|
||||
}
|
||||
|
||||
|
||||
@ -119,10 +106,10 @@ void test_no_moves_on_emplacement()
|
||||
try {
|
||||
optional<ThrowOnMove> o;
|
||||
o.emplace(1);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_TEST(o);
|
||||
}
|
||||
catch (...) {
|
||||
BOOST_CHECK(false);
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -143,47 +130,40 @@ void test_clear_on_throw()
|
||||
optional<Thrower> ot;
|
||||
try {
|
||||
ot.emplace(false);
|
||||
BOOST_CHECK(ot);
|
||||
BOOST_TEST(ot);
|
||||
} catch(...) {
|
||||
BOOST_CHECK(false);
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
try {
|
||||
ot.emplace(true);
|
||||
BOOST_CHECK(false);
|
||||
BOOST_TEST(false);
|
||||
} catch(...) {
|
||||
BOOST_CHECK(!ot);
|
||||
BOOST_TEST(!ot);
|
||||
}
|
||||
}
|
||||
|
||||
void test_no_assignment_on_emplacement()
|
||||
{
|
||||
optional<const std::string> os;
|
||||
BOOST_CHECK(!os);
|
||||
BOOST_TEST(!os);
|
||||
os.emplace("wow");
|
||||
BOOST_CHECK(os);
|
||||
BOOST_CHECK(*os == "wow");
|
||||
BOOST_TEST(os);
|
||||
BOOST_TEST_EQ(*os, "wow");
|
||||
}
|
||||
|
||||
int test_main( int, char* [] )
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
test_emplace();
|
||||
test_emplace();
|
||||
#endif
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
test_no_moves_on_emplacement();
|
||||
test_no_moves_on_emplacement();
|
||||
#endif
|
||||
test_clear_on_throw();
|
||||
test_no_assignment_on_emplacement();
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
test_clear_on_throw();
|
||||
test_no_assignment_on_emplacement();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,18 +8,6 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
// Revisions:
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
@ -27,11 +15,9 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "boost/none.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
struct SemiRegular // no operator==
|
||||
{
|
||||
@ -41,28 +27,17 @@ private: void operator!=(SemiRegular const&) const {}
|
||||
|
||||
void test_equal_to_none_of_noncomparable_T()
|
||||
{
|
||||
optional<SemiRegular> i = SemiRegular();
|
||||
optional<SemiRegular> o;
|
||||
|
||||
BOOST_CHECK(i != boost::none);
|
||||
BOOST_CHECK(boost::none != i);
|
||||
BOOST_CHECK(o == boost::none);
|
||||
BOOST_CHECK(boost::none == o);
|
||||
boost::optional<SemiRegular> i = SemiRegular();
|
||||
boost::optional<SemiRegular> o;
|
||||
|
||||
BOOST_TEST(i != boost::none);
|
||||
BOOST_TEST(boost::none != i);
|
||||
BOOST_TEST(o == boost::none);
|
||||
BOOST_TEST(boost::none == o);
|
||||
}
|
||||
|
||||
int test_main( int, char* [] )
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
test_equal_to_none_of_noncomparable_T();
|
||||
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
test_equal_to_none_of_noncomparable_T();
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
25
test/optional_test_fail_convert_from_null.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 NoInitFromNull{};
|
||||
|
||||
void test_conversion_from_null()
|
||||
{
|
||||
boost::optional<NoInitFromNull> opt = 0;
|
||||
}
|
||||
|
||||
|
24
test/optional_test_fail_io_without_io.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (C) 2015, Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
|
||||
#include <iostream>
|
||||
#include "boost/optional.hpp"
|
||||
// but no boost/optional/optional_io.hpp
|
||||
|
||||
// THIS TEST SHOULD FAIL TO COMPILE
|
||||
// Unless one includes header boost/optional/optional_io.hpp, it should not be possible
|
||||
// to stream out an optional object.
|
||||
|
||||
void test_streaming_out_optional()
|
||||
{
|
||||
boost::optional<int> opt;
|
||||
std::cout << opt;
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// 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:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
#include "boost/utility/in_place_factory.hpp"
|
||||
#include "boost/utility/typed_in_place_factory.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
struct A
|
||||
{
|
||||
A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {}
|
||||
|
||||
friend bool operator == ( A const& x, A const& y )
|
||||
{ return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; }
|
||||
|
||||
double m_a0 ;
|
||||
std::string m_a1 ;
|
||||
} ;
|
||||
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
double a00 = 3.14, a10 = 6.02e-23;
|
||||
std::string a01("pi"), a11("mol");
|
||||
|
||||
A a0(a00,a01);
|
||||
A a1(a10,a11);
|
||||
|
||||
boost::optional<A> opt1(a0);
|
||||
|
||||
boost::optional<A> opt2 ( boost::in_place(a00,a01) ) ;
|
||||
|
||||
boost::optional<A> opt3 ( boost::in_place<A>(a00,a01) ) ;
|
||||
|
||||
BOOST_CHECK( opt1 == opt2 ) ;
|
||||
BOOST_CHECK( opt2 == opt2 ) ;
|
||||
BOOST_CHECK( *opt2 == a0 ) ;
|
||||
|
||||
#ifndef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
|
||||
|
||||
opt2 = boost::in_place(a10,a11);
|
||||
BOOST_CHECK( *opt2 == a1 ) ;
|
||||
|
||||
opt3 = boost::in_place<A>(a10,a11);
|
||||
BOOST_CHECK( *opt3 == a1 ) ;
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
// If in-place factories are not supported there is nothing to test
|
||||
return 0 ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
104
test/optional_test_inplace_factory.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
|
||||
#include<string>
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
#include "boost/utility/in_place_factory.hpp"
|
||||
#include "boost/utility/typed_in_place_factory.hpp"
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "boost/none.hpp"
|
||||
|
||||
struct Guard
|
||||
{
|
||||
double num;
|
||||
std::string str;
|
||||
Guard() : num() {}
|
||||
Guard(double num_, std::string str_) : num(num_), str(str_) {}
|
||||
|
||||
friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; }
|
||||
friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); }
|
||||
|
||||
private:
|
||||
Guard(const Guard&);
|
||||
Guard& operator=(const Guard&);
|
||||
};
|
||||
|
||||
void test_ctor()
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
Guard g0, g1(1.0, "one"), g2(2.0, "two");
|
||||
|
||||
boost::optional<Guard> og0 ( boost::in_place() );
|
||||
boost::optional<Guard> og1 ( boost::in_place(1.0, "one") );
|
||||
boost::optional<Guard> og1_( boost::in_place(1.0, "one") );
|
||||
boost::optional<Guard> og2 ( boost::in_place<Guard>(2.0, "two") );
|
||||
|
||||
BOOST_TEST(og0);
|
||||
BOOST_TEST(og1);
|
||||
BOOST_TEST(og1_);
|
||||
BOOST_TEST(og2);
|
||||
|
||||
BOOST_TEST(*og0 == g0);
|
||||
BOOST_TEST(*og1 == g1);
|
||||
BOOST_TEST(*og1_ == g1);
|
||||
BOOST_TEST(*og2 == g2);
|
||||
|
||||
BOOST_TEST(og1_ == og1);
|
||||
BOOST_TEST(og1_ != og2);
|
||||
BOOST_TEST(og1_ != og0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_assign()
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
#ifndef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
|
||||
Guard g0, g1(1.0, "one"), g2(2.0, "two");
|
||||
|
||||
boost::optional<Guard> og0, og1, og1_, og2;
|
||||
|
||||
og0 = boost::in_place();
|
||||
og1 = boost::in_place(1.0, "one");
|
||||
og1_ = boost::in_place(1.0, "one");
|
||||
og2 = boost::in_place<Guard>(2.0, "two");
|
||||
|
||||
BOOST_TEST(og0);
|
||||
BOOST_TEST(og1);
|
||||
BOOST_TEST(og1_);
|
||||
BOOST_TEST(og2);
|
||||
|
||||
BOOST_TEST(*og0 == g0);
|
||||
BOOST_TEST(*og1 == g1);
|
||||
BOOST_TEST(*og1_ == g1);
|
||||
BOOST_TEST(*og2 == g2);
|
||||
|
||||
BOOST_TEST(og1_ == og1);
|
||||
BOOST_TEST(og1_ != og2);
|
||||
BOOST_TEST(og1_ != og0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_ctor();
|
||||
test_assign();
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -8,53 +9,45 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
#include "boost/utility/in_place_factory.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
struct A
|
||||
{
|
||||
A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {}
|
||||
|
||||
friend bool operator == ( A const& x, A const& y )
|
||||
{ return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; }
|
||||
|
||||
double m_a0 ;
|
||||
std::string m_a1 ;
|
||||
} ;
|
||||
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
int invalid_extra_parameter ;
|
||||
boost::optional<A> opt2 ( boost::in_place(3.14,"pi",invalid_extra_parameter) ) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
int invalid_extra_parameter ;
|
||||
boost::optional<A> opt2 ( A(3.14,"pi",invalid_extra_parameter) ) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include "boost/utility/in_place_factory.hpp"
|
||||
#include "boost/utility/typed_in_place_factory.hpp"
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "boost/none.hpp"
|
||||
|
||||
struct Guard
|
||||
{
|
||||
double num;
|
||||
std::string str;
|
||||
Guard() : num() {}
|
||||
Guard(double num_, std::string str_) : num(num_), str(str_) {}
|
||||
|
||||
friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; }
|
||||
friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); }
|
||||
|
||||
private:
|
||||
Guard(const Guard&);
|
||||
Guard& operator=(const Guard&);
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
int excessive_param = 2;
|
||||
boost::optional<Guard> og1 ( boost::in_place(1.0, "one", excessive_param) );
|
||||
#else
|
||||
NOTHING_TO_TEST_SO_JUST_FAIL
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -8,55 +9,45 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
#include "boost/utility/typed_in_place_factory.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
struct A
|
||||
{
|
||||
A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {}
|
||||
|
||||
friend bool operator == ( A const& x, A const& y )
|
||||
{ return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; }
|
||||
|
||||
double m_a0 ;
|
||||
std::string m_a1 ;
|
||||
} ;
|
||||
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
// This must fail to compile.
|
||||
// The first template argument to in_place<> is the target-type,
|
||||
// not the first constructor parameter type.
|
||||
boost::optional<A> opt2 ( boost::in_place<int>(3.14,"pi") ) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
boost::optional<A> opt2 ( int(3.14) ) ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include "boost/utility/in_place_factory.hpp"
|
||||
#include "boost/utility/typed_in_place_factory.hpp"
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "boost/none.hpp"
|
||||
|
||||
struct Guard
|
||||
{
|
||||
double num;
|
||||
std::string str;
|
||||
Guard() : num() {}
|
||||
Guard(double num_, std::string str_) : num(num_), str(str_) {}
|
||||
|
||||
friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; }
|
||||
friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); }
|
||||
|
||||
private:
|
||||
Guard(const Guard&);
|
||||
Guard& operator=(const Guard&);
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||
typedef int BAD_TARGET_TYPE;
|
||||
boost::optional<Guard> og1 ( boost::in_place<BAD_TARGET_TYPE>(1.0, "one") );
|
||||
#else
|
||||
NOTHING_TO_TEST_SO_JUST_FAIL
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// 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
|
||||
@ -8,52 +9,24 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
#include<sstream>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include <sstream>
|
||||
#include "boost/optional/optional.hpp"
|
||||
#include "boost/optional/optional_io.hpp"
|
||||
#include "boost/none.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#ifdef ENABLE_TRACE
|
||||
#define TRACE(msg) std::cout << msg << std::endl ;
|
||||
#else
|
||||
#define TRACE(msg)
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
|
||||
void assertion_failed (char const * expr, char const * func, char const * file, long )
|
||||
{
|
||||
using std::string ;
|
||||
string msg = string("Boost assertion failure for \"")
|
||||
+ string(expr)
|
||||
+ string("\" at file \"")
|
||||
+ string(file)
|
||||
+ string("\" function \"")
|
||||
+ string(func)
|
||||
+ string("\"") ;
|
||||
|
||||
TRACE(msg);
|
||||
|
||||
throw std::logic_error(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace std ;
|
||||
using namespace boost ;
|
||||
using boost::optional;
|
||||
using boost::make_optional;
|
||||
|
||||
template<class Opt>
|
||||
void test2( Opt o, Opt buff )
|
||||
{
|
||||
stringstream s ;
|
||||
std::stringstream s ;
|
||||
|
||||
const int markv = 123 ;
|
||||
int mark = 0 ;
|
||||
@ -61,8 +34,8 @@ void test2( Opt o, Opt buff )
|
||||
s << o << " " << markv ;
|
||||
s >> buff >> mark ;
|
||||
|
||||
BOOST_ASSERT( buff == o ) ;
|
||||
BOOST_ASSERT( mark == markv ) ;
|
||||
BOOST_TEST( buff == o ) ;
|
||||
BOOST_TEST( mark == markv ) ;
|
||||
}
|
||||
|
||||
|
||||
@ -75,18 +48,41 @@ void test( T v, T w )
|
||||
test2( optional<T> () , make_optional(w));
|
||||
}
|
||||
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
try
|
||||
{
|
||||
test(1,2);
|
||||
test(string("hello"),string("buffer"));
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
template <class T>
|
||||
void subtest_tag_none_reversibility_with_optional(optional<T> ov)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << boost::none;
|
||||
s >> ov;
|
||||
BOOST_TEST(!ov);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void subtest_tag_none_equivalence_with_optional()
|
||||
{
|
||||
std::stringstream s, r;
|
||||
optional<T> ov;
|
||||
s << boost::none;
|
||||
r << ov;
|
||||
BOOST_TEST_EQ(s.str(), r.str());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void test_tag_none(T v)
|
||||
{
|
||||
subtest_tag_none_reversibility_with_optional(optional<T>(v));
|
||||
subtest_tag_none_reversibility_with_optional(optional<T>());
|
||||
subtest_tag_none_equivalence_with_optional<T>();
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test(1,2);
|
||||
test(std::string("hello"), std::string("buffer"));
|
||||
test_tag_none(10);
|
||||
test_tag_none(std::string("text"));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2014 Andrzej Krzemienski.
|
||||
// Copyright (C) 2014-2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -8,19 +8,6 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
// Revisions:
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||
#include "boost/static_assert.hpp"
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
@ -28,12 +15,9 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "boost/none.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
class NonConstructible
|
||||
{
|
||||
private:
|
||||
@ -46,16 +30,10 @@ private:
|
||||
|
||||
void test_non_constructible()
|
||||
{
|
||||
optional<NonConstructible> o;
|
||||
BOOST_CHECK(!o);
|
||||
BOOST_CHECK(o == boost::none);
|
||||
try {
|
||||
o.value();
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
catch(...) {
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
boost::optional<NonConstructible> o;
|
||||
BOOST_TEST(!o);
|
||||
BOOST_TEST(o == boost::none);
|
||||
BOOST_TEST_THROWS(o.value(), boost::bad_optional_access);
|
||||
}
|
||||
|
||||
class Guard
|
||||
@ -72,33 +50,26 @@ private:
|
||||
|
||||
void test_guard()
|
||||
{
|
||||
optional<Guard> o;
|
||||
boost::optional<Guard> o;
|
||||
o.emplace(1);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(o != boost::none);
|
||||
}
|
||||
|
||||
void test_non_assignable()
|
||||
{
|
||||
optional<const std::string> o;
|
||||
boost::optional<const std::string> o;
|
||||
o.emplace("cat");
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(*o == "cat");
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(o != boost::none);
|
||||
BOOST_TEST_EQ(*o, std::string("cat"));
|
||||
}
|
||||
|
||||
int test_main( int, char* [] )
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
test_non_constructible();
|
||||
test_guard();
|
||||
test_non_assignable();
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
test_non_constructible();
|
||||
test_guard();
|
||||
test_non_assignable();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2014 Andrzej Krzemienski.
|
||||
// Copyright (C) 2014 - 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -8,19 +8,7 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
// Revisions:
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||
#include "boost/static_assert.hpp"
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
@ -28,11 +16,10 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/none.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
|
||||
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
|
||||
@ -86,37 +73,37 @@ bool operator!=( Oracle const& a, Oracle const& b ) { return a.val.i != b.val.i;
|
||||
void test_move_ctor_from_U()
|
||||
{
|
||||
optional<Oracle> o1 ((OracleVal()));
|
||||
BOOST_CHECK(o1);
|
||||
BOOST_CHECK(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed);
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed);
|
||||
|
||||
OracleVal v1;
|
||||
optional<Oracle> o2 (v1);
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed );
|
||||
BOOST_CHECK(v1.s == sIntConstructed);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed );
|
||||
BOOST_TEST(v1.s == sIntConstructed);
|
||||
|
||||
optional<Oracle> o3 (boost::move(v1));
|
||||
BOOST_CHECK(o3);
|
||||
BOOST_CHECK(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed);
|
||||
BOOST_CHECK(v1.s == sMovedFrom);
|
||||
BOOST_TEST(o3);
|
||||
BOOST_TEST(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed);
|
||||
BOOST_TEST(v1.s == sMovedFrom);
|
||||
}
|
||||
|
||||
void test_move_ctor_form_T()
|
||||
{
|
||||
optional<Oracle> o1 ((Oracle()));
|
||||
BOOST_CHECK(o1);
|
||||
BOOST_CHECK(o1->s == sMoveConstructed);
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(o1->s == sMoveConstructed);
|
||||
|
||||
Oracle v1;
|
||||
optional<Oracle> o2 (v1);
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->s == sCopyConstructed);
|
||||
BOOST_CHECK(v1.s == sDefaultConstructed);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->s == sCopyConstructed);
|
||||
BOOST_TEST(v1.s == sDefaultConstructed);
|
||||
|
||||
optional<Oracle> o3 (boost::move(v1));
|
||||
BOOST_CHECK(o3);
|
||||
BOOST_CHECK(o3->s == sMoveConstructed);
|
||||
BOOST_CHECK(v1.s == sMovedFrom);
|
||||
BOOST_TEST(o3);
|
||||
BOOST_TEST(o3->s == sMoveConstructed);
|
||||
BOOST_TEST(v1.s == sMovedFrom);
|
||||
}
|
||||
|
||||
void test_move_ctor_from_optional_T()
|
||||
@ -124,22 +111,22 @@ void test_move_ctor_from_optional_T()
|
||||
optional<Oracle> o1;
|
||||
optional<Oracle> o2(boost::move(o1));
|
||||
|
||||
BOOST_CHECK(!o1);
|
||||
BOOST_CHECK(!o2);
|
||||
BOOST_TEST(!o1);
|
||||
BOOST_TEST(!o2);
|
||||
|
||||
optional<Oracle> o3((Oracle()));
|
||||
optional<Oracle> o4(boost::move(o3));
|
||||
BOOST_CHECK(o3);
|
||||
BOOST_CHECK(o4);
|
||||
BOOST_CHECK(o3->s == sMovedFrom);
|
||||
BOOST_CHECK(o4->s == sMoveConstructed);
|
||||
BOOST_TEST(o3);
|
||||
BOOST_TEST(o4);
|
||||
BOOST_TEST(o3->s == sMovedFrom);
|
||||
BOOST_TEST(o4->s == sMoveConstructed);
|
||||
|
||||
optional<Oracle> o5((optional<Oracle>()));
|
||||
BOOST_CHECK(!o5);
|
||||
BOOST_TEST(!o5);
|
||||
|
||||
optional<Oracle> o6((optional<Oracle>(Oracle())));
|
||||
BOOST_CHECK(o6);
|
||||
BOOST_CHECK(o6->s == sMoveConstructed);
|
||||
BOOST_TEST(o6);
|
||||
BOOST_TEST(o6->s == sMoveConstructed);
|
||||
|
||||
optional<Oracle> o7(o6); // does copy ctor from non-const lvalue compile?
|
||||
}
|
||||
@ -149,59 +136,59 @@ void test_move_assign_from_U()
|
||||
optional<Oracle> o1 = boost::none; // test if additional ctors didn't break it
|
||||
o1 = boost::none; // test if additional assignments didn't break it
|
||||
o1 = OracleVal();
|
||||
BOOST_CHECK(o1);
|
||||
BOOST_TEST(o1);
|
||||
|
||||
BOOST_CHECK(o1->s == sValueMoveConstructed);
|
||||
BOOST_TEST(o1->s == sValueMoveConstructed);
|
||||
|
||||
o1 = OracleVal();
|
||||
BOOST_CHECK(o1);
|
||||
BOOST_CHECK(o1->s == sMoveAssigned);
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(o1->s == sMoveAssigned);
|
||||
|
||||
OracleVal v1;
|
||||
optional<Oracle> o2;
|
||||
o2 = v1;
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->s == sValueCopyConstructed);
|
||||
BOOST_CHECK(v1.s == sIntConstructed);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->s == sValueCopyConstructed);
|
||||
BOOST_TEST(v1.s == sIntConstructed);
|
||||
o2 = v1;
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->s == sCopyAssigned || o2->s == sMoveAssigned);
|
||||
BOOST_CHECK(v1.s == sIntConstructed);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->s == sCopyAssigned || o2->s == sMoveAssigned);
|
||||
BOOST_TEST(v1.s == sIntConstructed);
|
||||
|
||||
optional<Oracle> o3;
|
||||
o3 = boost::move(v1);
|
||||
BOOST_CHECK(o3);
|
||||
BOOST_CHECK(o3->s == sValueMoveConstructed);
|
||||
BOOST_CHECK(v1.s == sMovedFrom);
|
||||
BOOST_TEST(o3);
|
||||
BOOST_TEST(o3->s == sValueMoveConstructed);
|
||||
BOOST_TEST(v1.s == sMovedFrom);
|
||||
}
|
||||
|
||||
void test_move_assign_from_T()
|
||||
{
|
||||
optional<Oracle> o1;
|
||||
o1 = Oracle();
|
||||
BOOST_CHECK(o1);
|
||||
BOOST_CHECK(o1->s == sMoveConstructed);
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(o1->s == sMoveConstructed);
|
||||
|
||||
o1 = Oracle();
|
||||
BOOST_CHECK(o1);
|
||||
BOOST_CHECK(o1->s == sMoveAssigned);
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(o1->s == sMoveAssigned);
|
||||
|
||||
Oracle v1;
|
||||
optional<Oracle> o2;
|
||||
o2 = v1;
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->s == sCopyConstructed);
|
||||
BOOST_CHECK(v1.s == sDefaultConstructed);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->s == sCopyConstructed);
|
||||
BOOST_TEST(v1.s == sDefaultConstructed);
|
||||
o2 = v1;
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->s == sCopyAssigned);
|
||||
BOOST_CHECK(v1.s == sDefaultConstructed);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->s == sCopyAssigned);
|
||||
BOOST_TEST(v1.s == sDefaultConstructed);
|
||||
|
||||
optional<Oracle> o3;
|
||||
o3 = boost::move(v1);
|
||||
BOOST_CHECK(o3);
|
||||
BOOST_CHECK(o3->s == sMoveConstructed);
|
||||
BOOST_CHECK(v1.s == sMovedFrom);
|
||||
BOOST_TEST(o3);
|
||||
BOOST_TEST(o3->s == sMoveConstructed);
|
||||
BOOST_TEST(v1.s == sMovedFrom);
|
||||
}
|
||||
|
||||
void test_move_assign_from_optional_T()
|
||||
@ -209,23 +196,23 @@ void test_move_assign_from_optional_T()
|
||||
optional<Oracle> o1;
|
||||
optional<Oracle> o2;
|
||||
o1 = optional<Oracle>();
|
||||
BOOST_CHECK(!o1);
|
||||
BOOST_TEST(!o1);
|
||||
optional<Oracle> o3((Oracle()));
|
||||
o1 = o3;
|
||||
BOOST_CHECK(o3);
|
||||
BOOST_CHECK(o3->s == sMoveConstructed);
|
||||
BOOST_CHECK(o1);
|
||||
BOOST_CHECK(o1->s == sCopyConstructed);
|
||||
BOOST_TEST(o3);
|
||||
BOOST_TEST(o3->s == sMoveConstructed);
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(o1->s == sCopyConstructed);
|
||||
|
||||
o2 = boost::move(o3);
|
||||
BOOST_CHECK(o3);
|
||||
BOOST_CHECK(o3->s == sMovedFrom);
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->s == sMoveConstructed);
|
||||
BOOST_TEST(o3);
|
||||
BOOST_TEST(o3->s == sMovedFrom);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->s == sMoveConstructed);
|
||||
|
||||
o2 = optional<Oracle>((Oracle()));
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->s == sMoveAssigned);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->s == sMoveAssigned);
|
||||
}
|
||||
|
||||
class MoveOnly
|
||||
@ -247,21 +234,21 @@ void test_with_move_only()
|
||||
{
|
||||
optional<MoveOnly> o1;
|
||||
optional<MoveOnly> o2((MoveOnly(1)));
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->val == 1);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->val == 1);
|
||||
optional<MoveOnly> o3 (boost::move(o1));
|
||||
BOOST_CHECK(!o3);
|
||||
BOOST_TEST(!o3);
|
||||
optional<MoveOnly> o4 (boost::move(o2));
|
||||
BOOST_CHECK(o4);
|
||||
BOOST_CHECK(o4->val == 1);
|
||||
BOOST_CHECK(o2);
|
||||
BOOST_CHECK(o2->val == 0);
|
||||
BOOST_TEST(o4);
|
||||
BOOST_TEST(o4->val == 1);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2->val == 0);
|
||||
|
||||
o3 = boost::move(o4);
|
||||
BOOST_CHECK(o3);
|
||||
BOOST_CHECK(o3->val == 1);
|
||||
BOOST_CHECK(o4);
|
||||
BOOST_CHECK(o4->val == 0);
|
||||
BOOST_TEST(o3);
|
||||
BOOST_TEST(o3->val == 1);
|
||||
BOOST_TEST(o4);
|
||||
BOOST_TEST(o4->val == 0);
|
||||
}
|
||||
|
||||
class MoveOnlyB
|
||||
@ -287,15 +274,15 @@ void test_move_assign_from_optional_U()
|
||||
optional<MoveOnlyB> b1;
|
||||
b1 = boost::move(a);
|
||||
|
||||
BOOST_CHECK(b1);
|
||||
BOOST_CHECK(b1->val == 2);
|
||||
BOOST_CHECK(a);
|
||||
BOOST_CHECK(a->val == 0);
|
||||
BOOST_TEST(b1);
|
||||
BOOST_TEST(b1->val == 2);
|
||||
BOOST_TEST(a);
|
||||
BOOST_TEST(a->val == 0);
|
||||
|
||||
b1 = MoveOnly(4);
|
||||
|
||||
BOOST_CHECK(b1);
|
||||
BOOST_CHECK(b1->val == 4);
|
||||
BOOST_TEST(b1);
|
||||
BOOST_TEST(b1->val == 4);
|
||||
}
|
||||
|
||||
void test_move_ctor_from_optional_U()
|
||||
@ -303,15 +290,15 @@ void test_move_ctor_from_optional_U()
|
||||
optional<MoveOnly> a((MoveOnly(2)));
|
||||
optional<MoveOnlyB> b1(boost::move(a));
|
||||
|
||||
BOOST_CHECK(b1);
|
||||
BOOST_CHECK(b1->val == 2);
|
||||
BOOST_CHECK(a);
|
||||
BOOST_CHECK(a->val == 0);
|
||||
BOOST_TEST(b1);
|
||||
BOOST_TEST(b1->val == 2);
|
||||
BOOST_TEST(a);
|
||||
BOOST_TEST(a->val == 0);
|
||||
|
||||
optional<MoveOnlyB> b2(( optional<MoveOnly>(( MoveOnly(4) )) ));
|
||||
|
||||
BOOST_CHECK(b2);
|
||||
BOOST_CHECK(b2->val == 4);
|
||||
BOOST_TEST(b2);
|
||||
BOOST_TEST(b2->val == 4);
|
||||
}
|
||||
|
||||
void test_swap()
|
||||
@ -320,8 +307,8 @@ void test_swap()
|
||||
optional<MoveOnly> b((MoveOnly(3)));
|
||||
swap(a, b);
|
||||
|
||||
BOOST_CHECK(a->val == 3);
|
||||
BOOST_CHECK(b->val == 2);
|
||||
BOOST_TEST(a->val == 3);
|
||||
BOOST_TEST(b->val == 2);
|
||||
}
|
||||
|
||||
void test_optional_ref_to_movables()
|
||||
@ -329,66 +316,24 @@ void test_optional_ref_to_movables()
|
||||
MoveOnly m(3);
|
||||
optional<MoveOnly&> orm = m;
|
||||
orm->val = 2;
|
||||
BOOST_CHECK(m.val == 2);
|
||||
BOOST_TEST(m.val == 2);
|
||||
|
||||
optional<MoveOnly&> orm2 = orm;
|
||||
orm2->val = 1;
|
||||
BOOST_CHECK(m.val == 1);
|
||||
BOOST_CHECK(orm->val == 1);
|
||||
BOOST_TEST(m.val == 1);
|
||||
BOOST_TEST(orm->val == 1);
|
||||
|
||||
optional<MoveOnly&> orm3 = boost::move(orm);
|
||||
orm3->val = 4;
|
||||
BOOST_CHECK(m.val == 4);
|
||||
BOOST_CHECK(orm->val == 4);
|
||||
BOOST_CHECK(orm2->val == 4);
|
||||
BOOST_TEST(m.val == 4);
|
||||
BOOST_TEST(orm->val == 4);
|
||||
BOOST_TEST(orm2->val == 4);
|
||||
}
|
||||
|
||||
// these 4 classes have different noexcept signatures in move operations
|
||||
struct NothrowBoth {
|
||||
NothrowBoth(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
|
||||
void operator=(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
|
||||
};
|
||||
struct NothrowCtor {
|
||||
NothrowCtor(NothrowCtor&&) BOOST_NOEXCEPT_IF(true) {};
|
||||
void operator=(NothrowCtor&&) BOOST_NOEXCEPT_IF(false) {};
|
||||
};
|
||||
struct NothrowAssign {
|
||||
NothrowAssign(NothrowAssign&&) BOOST_NOEXCEPT_IF(false) {};
|
||||
void operator=(NothrowAssign&&) BOOST_NOEXCEPT_IF(true) {};
|
||||
};
|
||||
struct NothrowNone {
|
||||
NothrowNone(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
|
||||
void operator=(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_NOEXCEPT
|
||||
|
||||
void test_noexcept() // this is a compile-time test
|
||||
{
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowBoth> >::value);
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<optional<NothrowBoth> >::value);
|
||||
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowBoth>()));
|
||||
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowCtor> >::value);
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowCtor> >::value);
|
||||
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowCtor>()));
|
||||
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowAssign> >::value);
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowAssign> >::value);
|
||||
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowAssign>()));
|
||||
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowNone> >::value);
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowNone> >::value);
|
||||
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowNone>()));
|
||||
}
|
||||
#endif // !defned BOOST_NO_NOEXCEPT
|
||||
|
||||
#endif
|
||||
|
||||
int test_main( int, char* [] )
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
test_move_ctor_from_U();
|
||||
test_move_ctor_form_T();
|
||||
@ -402,13 +347,6 @@ int test_main( int, char* [] )
|
||||
test_optional_ref_to_movables();
|
||||
test_swap();
|
||||
#endif
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
41
test/optional_test_msvc_bug_workaround.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
|
||||
#define BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
|
||||
|
||||
struct Wrapper
|
||||
{
|
||||
operator int () { return 9; }
|
||||
operator boost::optional<int> () { return 7; }
|
||||
};
|
||||
|
||||
void test()
|
||||
{
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
boost::optional<int> v = Wrapper();
|
||||
BOOST_TEST(v);
|
||||
BOOST_TEST_EQ(*v, 7);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
return boost::report_errors();
|
||||
}
|
116
test/optional_test_noexcept_move.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
// 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/static_assert.hpp"
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
|
||||
using boost::optional;
|
||||
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_NOEXCEPT
|
||||
|
||||
// these 4 classes have different noexcept signatures in move operations
|
||||
struct NothrowBoth {
|
||||
NothrowBoth(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
|
||||
void operator=(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
|
||||
};
|
||||
struct NothrowCtor {
|
||||
NothrowCtor(NothrowCtor&&) BOOST_NOEXCEPT_IF(true) {};
|
||||
void operator=(NothrowCtor&&) BOOST_NOEXCEPT_IF(false) {};
|
||||
};
|
||||
struct NothrowAssign {
|
||||
NothrowAssign(NothrowAssign&&) BOOST_NOEXCEPT_IF(false) {};
|
||||
void operator=(NothrowAssign&&) BOOST_NOEXCEPT_IF(true) {};
|
||||
};
|
||||
struct NothrowNone {
|
||||
NothrowNone(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
|
||||
void operator=(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
|
||||
};
|
||||
|
||||
#if 0 // these also test type_traits, which are wrong
|
||||
void test_noexcept_as_defined() // this is a compile-time test
|
||||
{
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<NothrowBoth>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<NothrowBoth>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<NothrowCtor>::value);
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<NothrowCtor>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<NothrowAssign>::value);
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<NothrowAssign>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<NothrowNone>::value);
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<NothrowNone>::value);
|
||||
}
|
||||
|
||||
void test_noexcept_on_optional_with_type_traits() // this is a compile-time test
|
||||
{
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowBoth> >::value);
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<optional<NothrowBoth> >::value);
|
||||
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowBoth>()));
|
||||
|
||||
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowCtor> >::value);
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowCtor> >::value);
|
||||
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowCtor>()));
|
||||
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowAssign> >::value);
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowAssign> >::value);
|
||||
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowAssign>()));
|
||||
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowNone> >::value);
|
||||
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowNone> >::value);
|
||||
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowNone>()));
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_noexcept_optional_with_operator() // compile-time test
|
||||
{
|
||||
typedef optional<NothrowBoth> ONx2;
|
||||
typedef optional<NothrowCtor> ONxC;
|
||||
typedef optional<NothrowAssign> ONxA;
|
||||
typedef optional<NothrowNone> ONx0;
|
||||
ONx2 onx2;
|
||||
ONxC onxC;
|
||||
ONxA onxA;
|
||||
ONx0 onx0;
|
||||
|
||||
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx2() ));
|
||||
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx2(boost::move(onx2)) ));
|
||||
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( onx2 = ONx2() ));
|
||||
|
||||
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxC() ));
|
||||
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxC(boost::move(onxC)) ));
|
||||
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onxC = ONxC() ));
|
||||
|
||||
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxA() ));
|
||||
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( ONxA(boost::move(onxA)) ));
|
||||
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onxA = ONxA() ));
|
||||
|
||||
BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx0() ));
|
||||
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( ONx0(boost::move(onx0)) ));
|
||||
BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onx0 = ONx0() ));
|
||||
}
|
||||
|
||||
#endif // !defned BOOST_NO_NOEXCEPT
|
||||
#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,373 +0,0 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// 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:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/none.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
template<class T>
|
||||
inline void check_ref_uninitialized_const ( optional<T&> const& opt )
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
BOOST_CHECK( opt == 0 ) ;
|
||||
#endif
|
||||
BOOST_CHECK( !opt ) ;
|
||||
}
|
||||
template<class T>
|
||||
inline void check_ref_uninitialized ( optional<T&>& opt )
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
BOOST_CHECK( opt == 0 ) ;
|
||||
#endif
|
||||
BOOST_CHECK( !opt ) ;
|
||||
|
||||
check_ref_uninitialized_const(opt);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void check_ref_initialized_const ( optional<T&> const& opt )
|
||||
{
|
||||
BOOST_CHECK( opt ) ;
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
BOOST_CHECK( opt != 0 ) ;
|
||||
#endif
|
||||
|
||||
BOOST_CHECK ( !!opt ) ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void check_ref_initialized ( optional<T&>& opt )
|
||||
{
|
||||
BOOST_CHECK( opt ) ;
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
BOOST_CHECK( opt != 0 ) ;
|
||||
#endif
|
||||
|
||||
BOOST_CHECK ( !!opt ) ;
|
||||
|
||||
check_ref_initialized_const(opt);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void check_ref_value_const ( optional<T&> const& opt, T const& v, T const& z )
|
||||
{
|
||||
BOOST_CHECK( *opt == v ) ;
|
||||
BOOST_CHECK( *opt != z ) ;
|
||||
BOOST_CHECK( opt.get() == v ) ;
|
||||
BOOST_CHECK( opt.get() != z ) ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void check_ref_value ( optional<T&>& opt, T const& v, T const& z )
|
||||
{
|
||||
BOOST_CHECK( *opt == v ) ;
|
||||
BOOST_CHECK( *opt != z ) ;
|
||||
BOOST_CHECK( opt.get() == v ) ;
|
||||
BOOST_CHECK( opt.get() != z ) ;
|
||||
|
||||
check_ref_value_const(opt,v,z);
|
||||
}
|
||||
|
||||
//
|
||||
// Basic test.
|
||||
// Check ordinary functionality:
|
||||
// Initialization, assignment, comparison and value-accessing.
|
||||
//
|
||||
template<class T>
|
||||
void test_basics( T const* )
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
T z(0);
|
||||
|
||||
T original_a(1);
|
||||
|
||||
T a(1);
|
||||
|
||||
T b(2);
|
||||
|
||||
T c(10);
|
||||
|
||||
T& aref = a ;
|
||||
T& bref = b ;
|
||||
|
||||
// Default construction.
|
||||
// 'def' state is Uninitialized.
|
||||
// T::T() is not called
|
||||
optional<T&> def ;
|
||||
check_ref_uninitialized(def);
|
||||
|
||||
// Direct initialization.
|
||||
// 'oa' state is Initialized and binds to 'a'
|
||||
// T::T( T const& x ) is NOT used becasue the optional holds a reference.
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
optional<T&> oa ( aref ) ;
|
||||
check_is_pending_copy( ARG(T) );
|
||||
check_ref_initialized(oa);
|
||||
check_ref_value(oa,a,z);
|
||||
*oa = b ; // changes the value of 'a' through the reference
|
||||
BOOST_CHECK( a == b ) ;
|
||||
|
||||
|
||||
// Copy initialization.
|
||||
// T::T ( T const& x ) is NOT used becasue the optional holds a reference.
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
optional<T&> const oa2 ( oa ) ;
|
||||
check_is_pending_copy( ARG(T) ) ;
|
||||
check_ref_initialized_const(oa2);
|
||||
check_ref_value_const(oa2,a,z);
|
||||
*oa2 = original_a ; // restores the value of 'a' through the reference
|
||||
BOOST_CHECK( a == original_a ) ;
|
||||
|
||||
optional<T&> ob ;
|
||||
|
||||
// Value-Assignment upon Uninitialized optional.
|
||||
// T::T ( T const& x ) is NOT used becasue the optional holds a reference.
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
ob = a ; // Binds ob to a temporary non-const refererence to 'a'
|
||||
check_is_pending_copy( ARG(T) ) ;
|
||||
check_ref_initialized(ob);
|
||||
check_ref_value(ob,a,z);
|
||||
a = c;
|
||||
check_ref_value(ob,a,z);
|
||||
|
||||
// Value-Assignment upon Initialized optional.
|
||||
// T::operator= ( T const& x ) is used.
|
||||
set_pending_assign( ARG(T) ) ;
|
||||
ob = b ; // Rebinds 'ob' to 'b' (without changing 'a')
|
||||
check_is_pending_assign( ARG(T) ) ;
|
||||
check_ref_initialized(ob);
|
||||
check_ref_value(ob,b,z);
|
||||
BOOST_CHECK(a == c); // From a=c in previous test
|
||||
b = c;
|
||||
check_ref_value(ob,b,z);
|
||||
|
||||
|
||||
// Assignment initialization.
|
||||
// T::T ( T const& x ) is NOT used becasue the optional holds a reference.
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
optional<T&> const oa3 = b ;
|
||||
check_is_pending_copy( ARG(T) ) ;
|
||||
check_ref_initialized_const(oa3);
|
||||
check_ref_value_const(oa3,b,z);
|
||||
|
||||
|
||||
// Assignment
|
||||
// T::operator=( T const& x ) is used.
|
||||
set_pending_assign( ARG(T) ) ;
|
||||
oa = ob ; // Rebinds 'a' to 'b'
|
||||
check_is_pending_assign( ARG(T) ) ;
|
||||
check_ref_initialized(oa);
|
||||
a = original_a ;
|
||||
check_ref_value(oa,b,z);
|
||||
|
||||
// Uninitializing Assignment upon Initialized Optional
|
||||
// T::~T() is NOT used becasue the optional holds a reference.
|
||||
set_pending_dtor( ARG(T) ) ;
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
oa = def ;
|
||||
check_is_pending_dtor( ARG(T) ) ;
|
||||
check_is_pending_copy( ARG(T) ) ;
|
||||
check_ref_uninitialized(oa);
|
||||
|
||||
// Uninitializing Assignment upon Uninitialized Optional
|
||||
// (Dtor is not called this time)
|
||||
set_pending_dtor( ARG(T) ) ;
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
oa = def ;
|
||||
check_is_pending_dtor( ARG(T) ) ;
|
||||
check_is_pending_copy( ARG(T) ) ;
|
||||
check_ref_uninitialized(oa);
|
||||
|
||||
|
||||
// Deinitialization of Initialized Optional
|
||||
// T::~T() is NOT used becasue the optional holds a reference.
|
||||
set_pending_dtor( ARG(T) ) ;
|
||||
ob.reset();
|
||||
check_is_pending_dtor( ARG(T) ) ;
|
||||
check_ref_uninitialized(ob);
|
||||
|
||||
// Deinitialization of Uninitialized Optional
|
||||
// T::~T() is not called this time
|
||||
set_pending_dtor( ARG(T) ) ;
|
||||
ob.reset();
|
||||
check_is_pending_dtor( ARG(T) ) ;
|
||||
check_ref_uninitialized(ob);
|
||||
}
|
||||
|
||||
//
|
||||
// This verifies relational operators.
|
||||
//
|
||||
template<class T>
|
||||
void test_relops( T const* )
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
reset_throw_on_copy( ARG(T) ) ;
|
||||
|
||||
T v0(18);
|
||||
T v1(19);
|
||||
T v2(19);
|
||||
|
||||
optional<T&> def0 ;
|
||||
optional<T&> def1 ;
|
||||
optional<T&> opt0(v0);
|
||||
optional<T&> opt1(v1);
|
||||
optional<T&> opt2(v2);
|
||||
|
||||
// Check identity
|
||||
BOOST_CHECK ( def0 == def0 ) ;
|
||||
BOOST_CHECK ( opt0 == opt0 ) ;
|
||||
BOOST_CHECK ( !(def0 != def0) ) ;
|
||||
BOOST_CHECK ( !(opt0 != opt0) ) ;
|
||||
|
||||
// Check when both are uininitalized.
|
||||
BOOST_CHECK ( def0 == def1 ) ; // both uninitialized compare equal
|
||||
BOOST_CHECK ( !(def0 < def1) ) ; // uninitialized is never less than uninitialized
|
||||
BOOST_CHECK ( !(def0 > def1) ) ; // uninitialized is never greater than uninitialized
|
||||
BOOST_CHECK ( !(def0 != def1) ) ;
|
||||
BOOST_CHECK ( def0 <= def1 ) ;
|
||||
BOOST_CHECK ( def0 >= def1 ) ;
|
||||
|
||||
// Check when only lhs is uninitialized.
|
||||
BOOST_CHECK ( def0 != opt0 ) ; // uninitialized is never equal to initialized
|
||||
BOOST_CHECK ( !(def0 == opt0) ) ;
|
||||
BOOST_CHECK ( def0 < opt0 ) ; // uninitialized is always less than initialized
|
||||
BOOST_CHECK ( !(def0 > opt0) ) ;
|
||||
BOOST_CHECK ( def0 <= opt0 ) ;
|
||||
BOOST_CHECK ( !(def0 >= opt0) ) ;
|
||||
|
||||
// Check when only rhs is uninitialized.
|
||||
BOOST_CHECK ( opt0 != def0 ) ; // initialized is never equal to uninitialized
|
||||
BOOST_CHECK ( !(opt0 == def0) ) ;
|
||||
BOOST_CHECK ( !(opt0 < def0) ) ; // initialized is never less than uninitialized
|
||||
BOOST_CHECK ( opt0 > def0 ) ;
|
||||
BOOST_CHECK ( !(opt0 <= def0) ) ;
|
||||
BOOST_CHECK ( opt0 >= opt0 ) ;
|
||||
|
||||
// If both are initialized, values are compared
|
||||
BOOST_CHECK ( opt0 != opt1 ) ;
|
||||
BOOST_CHECK ( opt1 == opt2 ) ;
|
||||
BOOST_CHECK ( opt0 < opt1 ) ;
|
||||
BOOST_CHECK ( opt1 > opt0 ) ;
|
||||
BOOST_CHECK ( opt1 <= opt2 ) ;
|
||||
BOOST_CHECK ( opt1 >= opt0 ) ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void test_none( T const* )
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
using boost::none ;
|
||||
|
||||
T a(1234);
|
||||
|
||||
optional<T&> def0 ;
|
||||
optional<T&> def1(none) ;
|
||||
optional<T&> non_def(a) ;
|
||||
|
||||
BOOST_CHECK ( def0 == none ) ;
|
||||
BOOST_CHECK ( non_def != none ) ;
|
||||
BOOST_CHECK ( !def1 ) ;
|
||||
|
||||
non_def = none ;
|
||||
BOOST_CHECK ( !non_def ) ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void test_arrow( T const* )
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
T a(1234);
|
||||
|
||||
optional<T&> oa(a) ;
|
||||
optional<T&> const coa(a) ;
|
||||
|
||||
BOOST_CHECK ( coa->V() == 1234 ) ;
|
||||
|
||||
oa->V() = 4321 ;
|
||||
|
||||
BOOST_CHECK ( a.V() = 4321 ) ;
|
||||
}
|
||||
|
||||
void test_with_builtin_types()
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
test_basics( ARG(double) );
|
||||
test_relops( ARG(double) ) ;
|
||||
test_none ( ARG(double) ) ;
|
||||
}
|
||||
|
||||
void test_with_class_type()
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
test_basics( ARG(X) );
|
||||
test_relops( ARG(X) ) ;
|
||||
test_none ( ARG(X) ) ;
|
||||
test_arrow ( ARG(X) ) ;
|
||||
|
||||
BOOST_CHECK ( X::count == 0 ) ;
|
||||
}
|
||||
|
||||
void test_binding()
|
||||
{
|
||||
int i = 0 ;
|
||||
optional<int&> ori1 = i ;
|
||||
BOOST_CHECK( &(*ori1) == &i ) ;
|
||||
|
||||
optional<int&> ori2(i) ;
|
||||
BOOST_CHECK( &(*ori2) == &i ) ;
|
||||
|
||||
int const ci = 0 ;
|
||||
optional<int const&> orci1 = ci ;
|
||||
BOOST_CHECK( &(*orci1) == &ci ) ;
|
||||
|
||||
optional<int const&> orci2(ci) ;
|
||||
BOOST_CHECK( &(*orci2) == &ci ) ;
|
||||
}
|
||||
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
try
|
||||
{
|
||||
test_with_class_type();
|
||||
test_with_builtin_types();
|
||||
test_binding();
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
34
test/optional_test_ref_assign_const_int.cpp
Normal 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/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
#include "optional_ref_assign_test_defs.hpp"
|
||||
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
test_copy_assignment_for_const<int>();
|
||||
test_copy_assignment_for_noconst_const<int>();
|
||||
test_rebinding_assignment_semantics_const<int>();
|
||||
test_rebinding_assignment_semantics_noconst_const<int>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
31
test/optional_test_ref_assign_mutable_int.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
// 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 "boost/core/lightweight_test.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
#include "optional_ref_assign_test_defs.hpp"
|
||||
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
int main()
|
||||
{
|
||||
test_copy_assignment_for<int>();
|
||||
test_rebinding_assignment_semantics<int>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
44
test/optional_test_ref_assign_portable_minimum.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
// 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 "boost/core/lightweight_test.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
#include "optional_ref_assign_test_defs.hpp"
|
||||
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
|
||||
template <typename T>
|
||||
void test_optional_ref_assignment()
|
||||
{
|
||||
test_copy_assignment_for<T>();
|
||||
test_rebinding_assignment_semantics<T>();
|
||||
|
||||
test_copy_assignment_for_const<T>();
|
||||
test_copy_assignment_for_noconst_const<T>();
|
||||
test_rebinding_assignment_semantics_const<T>();
|
||||
test_rebinding_assignment_semantics_noconst_const<T>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_optional_ref_assignment<ScopeGuard>();
|
||||
//test_optional_ref_assignment<Abstract>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
30
test/optional_test_ref_convert_assign_const_int.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at: akrzemi1@gmail.com
|
||||
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/addressof.hpp"
|
||||
#include "boost/core/enable_if.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
#include "optional_ref_assign_test_defs.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
test_converting_assignment<const int>();
|
||||
test_converting_assignment_for_noconst_const<int>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
29
test/optional_test_ref_convert_assign_mutable_int.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at: akrzemi1@gmail.com
|
||||
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/addressof.hpp"
|
||||
#include "boost/core/enable_if.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
#include "optional_ref_assign_test_defs.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
test_converting_assignment<int>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
39
test/optional_test_ref_convert_assign_non_int.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at: akrzemi1@gmail.com
|
||||
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/addressof.hpp"
|
||||
#include "boost/core/enable_if.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
#include "optional_ref_assign_test_defs.hpp"
|
||||
|
||||
|
||||
template <typename T>
|
||||
void test_all_const_cases()
|
||||
{
|
||||
test_converting_assignment<T>();
|
||||
test_converting_assignment<const T>();
|
||||
test_converting_assignment_for_noconst_const<T>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_all_const_cases<ScopeGuard>();
|
||||
//test_all_const_cases<Abstract>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
107
test/optional_test_ref_converting_ctor.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
// 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 "boost/core/addressof.hpp"
|
||||
#include "boost/core/enable_if.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
template <typename T>
|
||||
void test_converting_ctor()
|
||||
{
|
||||
typename concrete_type_of<T>::type v1(1), v2(2);
|
||||
|
||||
{
|
||||
optional<T&> o1 = v1, o1_ = v1, o2 = v2;
|
||||
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
|
||||
BOOST_TEST(o1_);
|
||||
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1));
|
||||
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1));
|
||||
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2));
|
||||
BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1));
|
||||
}
|
||||
{
|
||||
const optional<T&> o1 = v1, o1_ = v1, o2 = v2;
|
||||
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
|
||||
BOOST_TEST(o1_);
|
||||
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1));
|
||||
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1));
|
||||
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2));
|
||||
BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_converting_ctor_for_noconst_const()
|
||||
{
|
||||
typename concrete_type_of<T>::type v1(1), v2(2);
|
||||
|
||||
{
|
||||
optional<const T&> o1 = v1, o1_ = v1, o2 = v2;
|
||||
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
|
||||
BOOST_TEST(o1_);
|
||||
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1));
|
||||
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1));
|
||||
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2));
|
||||
BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1));
|
||||
}
|
||||
{
|
||||
const optional<const T&> o1 = v1, o1_ = v1, o2 = v2;
|
||||
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1));
|
||||
BOOST_TEST(o1_);
|
||||
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1));
|
||||
BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1));
|
||||
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2));
|
||||
BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_all_const_cases()
|
||||
{
|
||||
test_converting_ctor<T>();
|
||||
test_converting_ctor<const T>();
|
||||
test_converting_ctor_for_noconst_const<T>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_all_const_cases<int>();
|
||||
test_all_const_cases<ScopeGuard>();
|
||||
//test_all_const_cases<Abstract>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
448
test/optional_test_ref_portable_minimum.cpp
Normal file
@ -0,0 +1,448 @@
|
||||
// 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 "boost/core/addressof.hpp"
|
||||
#include "boost/core/enable_if.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "testable_classes.hpp"
|
||||
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
struct CountingClass
|
||||
{
|
||||
static int count;
|
||||
static int assign_count;
|
||||
CountingClass() { ++count; }
|
||||
CountingClass(const CountingClass&) { ++count; }
|
||||
CountingClass& operator=(const CountingClass&) { ++assign_count; return *this; }
|
||||
~CountingClass() { ++count; }
|
||||
};
|
||||
|
||||
int CountingClass::count = 0;
|
||||
int CountingClass::assign_count = 0;
|
||||
|
||||
void test_no_object_creation()
|
||||
{
|
||||
BOOST_TEST_EQ(0, CountingClass::count);
|
||||
BOOST_TEST_EQ(0, CountingClass::assign_count);
|
||||
{
|
||||
CountingClass v1, v2;
|
||||
optional<CountingClass&> oA(v1);
|
||||
optional<CountingClass&> oB;
|
||||
optional<CountingClass&> oC = oA;
|
||||
oB = oA;
|
||||
*oB = v2;
|
||||
oC = none;
|
||||
oC = optional<CountingClass&>(v2);
|
||||
oB = none;
|
||||
oA = oB;
|
||||
}
|
||||
BOOST_TEST_EQ(4, CountingClass::count);
|
||||
BOOST_TEST_EQ(1, CountingClass::assign_count);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::enable_if< has_arrow<T> >::type
|
||||
test_arrow_const()
|
||||
{
|
||||
const typename concrete_type_of<T>::type v(2);
|
||||
optional<const T&> o(v);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST_EQ(o->val(), 2);
|
||||
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::disable_if< has_arrow<T> >::type
|
||||
test_arrow_const()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::enable_if< has_arrow<T> >::type
|
||||
test_arrow_noconst_const()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2);
|
||||
optional<const T&> o(v);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST_EQ(o->val(), 2);
|
||||
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
|
||||
|
||||
v.val() = 1;
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST_EQ(o->val(), 1);
|
||||
BOOST_TEST_EQ(v.val(), 1);
|
||||
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::disable_if< has_arrow<T> >::type
|
||||
test_arrow_noconst_const()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::enable_if< has_arrow<T> >::type
|
||||
test_arrow()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2);
|
||||
optional<T&> o(v);
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST_EQ(o->val(), 2);
|
||||
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
|
||||
|
||||
v.val() = 1;
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST_EQ(o->val(), 1);
|
||||
BOOST_TEST_EQ(v.val(), 1);
|
||||
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
|
||||
|
||||
o->val() = 3;
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST_EQ(o->val(), 3);
|
||||
BOOST_TEST_EQ(v.val(), 3);
|
||||
BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val()));
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::disable_if< has_arrow<T> >::type
|
||||
test_arrow()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_not_containing_value_for()
|
||||
{
|
||||
optional<T&> o1;
|
||||
optional<T&> o2 = none;
|
||||
optional<T&> o3 = o1;
|
||||
|
||||
BOOST_TEST(!o1);
|
||||
BOOST_TEST(!o2);
|
||||
BOOST_TEST(!o3);
|
||||
|
||||
BOOST_TEST(o1 == none);
|
||||
BOOST_TEST(o2 == none);
|
||||
BOOST_TEST(o3 == none);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_direct_init_for_const()
|
||||
{
|
||||
const typename concrete_type_of<T>::type v(2);
|
||||
optional<const T&> o(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(o != none);
|
||||
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_direct_init_for_noconst_const()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2);
|
||||
optional<const T&> o(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(o != none);
|
||||
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 2);
|
||||
|
||||
val(v) = 9;
|
||||
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 9);
|
||||
BOOST_TEST_EQ(val(v), 9);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_direct_init_for()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2);
|
||||
optional<T&> o(v);
|
||||
|
||||
BOOST_TEST(o);
|
||||
BOOST_TEST(o != none);
|
||||
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 2);
|
||||
|
||||
val(v) = 9;
|
||||
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 9);
|
||||
BOOST_TEST_EQ(val(v), 9);
|
||||
|
||||
val(*o) = 7;
|
||||
BOOST_TEST(boost::addressof(*o) == boost::addressof(v));
|
||||
BOOST_TEST_EQ(val(*o), val(v));
|
||||
BOOST_TEST_EQ(val(*o), 7);
|
||||
BOOST_TEST_EQ(val(v), 7);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_clearing_the_value()
|
||||
{
|
||||
typename concrete_type_of<T>::type v(2);
|
||||
optional<T&> o1(v), o2(v);
|
||||
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(o1 != none);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2 != none);
|
||||
|
||||
o1 = none;
|
||||
BOOST_TEST(!o1);
|
||||
BOOST_TEST(o1 == none);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(o2 != none);
|
||||
BOOST_TEST_EQ(val(*o2), 2);
|
||||
BOOST_TEST(boost::addressof(*o2) == boost::addressof(v));
|
||||
BOOST_TEST_EQ(val(v), 2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_equality()
|
||||
{
|
||||
typename concrete_type_of<T>::type v1(1), v2(2), v2_(2), v3(3);
|
||||
optional<T&> o1(v1), o2(v2), o2_(v2_), o3(v3), o3_(v3), oN, oN_;
|
||||
// o2 and o2_ point to different objects; o3 and o3_ point to the same object
|
||||
|
||||
BOOST_TEST(oN == oN);
|
||||
BOOST_TEST(oN == oN_);
|
||||
BOOST_TEST(oN_ == oN);
|
||||
BOOST_TEST(o1 == o1);
|
||||
BOOST_TEST(o2 == o2);
|
||||
BOOST_TEST(o2 == o2_);
|
||||
BOOST_TEST(o2_ == o2);
|
||||
BOOST_TEST(o3 == o3);
|
||||
BOOST_TEST(o3 == o3_);
|
||||
BOOST_TEST(!(oN == o1));
|
||||
BOOST_TEST(!(o1 == oN));
|
||||
BOOST_TEST(!(o2 == o1));
|
||||
BOOST_TEST(!(o2 == oN));
|
||||
|
||||
BOOST_TEST(!(oN != oN));
|
||||
BOOST_TEST(!(oN != oN_));
|
||||
BOOST_TEST(!(oN_ != oN));
|
||||
BOOST_TEST(!(o1 != o1));
|
||||
BOOST_TEST(!(o2 != o2));
|
||||
BOOST_TEST(!(o2 != o2_));
|
||||
BOOST_TEST(!(o2_ != o2));
|
||||
BOOST_TEST(!(o3 != o3));
|
||||
BOOST_TEST(!(o3 != o3_));
|
||||
BOOST_TEST( (oN != o1));
|
||||
BOOST_TEST( (o1 != oN));
|
||||
BOOST_TEST( (o2 != o1));
|
||||
BOOST_TEST( (o2 != oN));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_order()
|
||||
{
|
||||
typename concrete_type_of<T>::type v1(1), v2(2), v2_(2), v3(3);
|
||||
optional<T&> o1(v1), o2(v2), o2_(v2_), o3(v3), o3_(v3), oN, oN_;
|
||||
// o2 and o2_ point to different objects; o3 and o3_ point to the same object
|
||||
|
||||
BOOST_TEST(!(oN < oN));
|
||||
BOOST_TEST(!(oN < oN_));
|
||||
BOOST_TEST(!(oN_ < oN));
|
||||
BOOST_TEST(!(o1 < o1));
|
||||
BOOST_TEST(!(o2 < o2));
|
||||
BOOST_TEST(!(o2 < o2_));
|
||||
BOOST_TEST(!(o2_ < o2));
|
||||
BOOST_TEST(!(o3 < o3));
|
||||
BOOST_TEST(!(o3 < o3_));
|
||||
|
||||
BOOST_TEST( (oN <= oN));
|
||||
BOOST_TEST( (oN <= oN_));
|
||||
BOOST_TEST( (oN_ <= oN));
|
||||
BOOST_TEST( (o1 <= o1));
|
||||
BOOST_TEST( (o2 <= o2));
|
||||
BOOST_TEST( (o2 <= o2_));
|
||||
BOOST_TEST( (o2_ <= o2));
|
||||
BOOST_TEST( (o3 <= o3));
|
||||
BOOST_TEST( (o3 <= o3_));
|
||||
|
||||
BOOST_TEST(!(oN > oN));
|
||||
BOOST_TEST(!(oN > oN_));
|
||||
BOOST_TEST(!(oN_ > oN));
|
||||
BOOST_TEST(!(o1 > o1));
|
||||
BOOST_TEST(!(o2 > o2));
|
||||
BOOST_TEST(!(o2 > o2_));
|
||||
BOOST_TEST(!(o2_ > o2));
|
||||
BOOST_TEST(!(o3 > o3));
|
||||
BOOST_TEST(!(o3 > o3_));
|
||||
|
||||
BOOST_TEST( (oN >= oN));
|
||||
BOOST_TEST( (oN >= oN_));
|
||||
BOOST_TEST( (oN_ >= oN));
|
||||
BOOST_TEST( (o1 >= o1));
|
||||
BOOST_TEST( (o2 >= o2));
|
||||
BOOST_TEST( (o2 >= o2_));
|
||||
BOOST_TEST( (o2_ >= o2));
|
||||
BOOST_TEST( (o3 >= o3));
|
||||
BOOST_TEST( (o3 >= o3_));
|
||||
|
||||
BOOST_TEST( (oN < o1));
|
||||
BOOST_TEST( (oN_ < o1));
|
||||
BOOST_TEST( (oN < o2));
|
||||
BOOST_TEST( (oN_ < o2));
|
||||
BOOST_TEST( (oN < o2_));
|
||||
BOOST_TEST( (oN_ < o2_));
|
||||
BOOST_TEST( (oN < o3));
|
||||
BOOST_TEST( (oN_ < o3));
|
||||
BOOST_TEST( (oN < o3_));
|
||||
BOOST_TEST( (oN_ < o3_));
|
||||
BOOST_TEST( (o1 < o2));
|
||||
BOOST_TEST( (o1 < o2_));
|
||||
BOOST_TEST( (o1 < o3));
|
||||
BOOST_TEST( (o1 < o3_));
|
||||
BOOST_TEST( (o2 < o3));
|
||||
BOOST_TEST( (o2_ < o3));
|
||||
BOOST_TEST( (o2 < o3_));
|
||||
BOOST_TEST( (o2_ < o3_));
|
||||
|
||||
BOOST_TEST( (oN <= o1));
|
||||
BOOST_TEST( (oN_ <= o1));
|
||||
BOOST_TEST( (oN <= o2));
|
||||
BOOST_TEST( (oN_ <= o2));
|
||||
BOOST_TEST( (oN <= o2_));
|
||||
BOOST_TEST( (oN_ <= o2_));
|
||||
BOOST_TEST( (oN <= o3));
|
||||
BOOST_TEST( (oN_ <= o3));
|
||||
BOOST_TEST( (oN <= o3_));
|
||||
BOOST_TEST( (oN_ <= o3_));
|
||||
BOOST_TEST( (o1 <= o2));
|
||||
BOOST_TEST( (o1 <= o2_));
|
||||
BOOST_TEST( (o1 <= o3));
|
||||
BOOST_TEST( (o1 <= o3_));
|
||||
BOOST_TEST( (o2 <= o3));
|
||||
BOOST_TEST( (o2_ <= o3));
|
||||
BOOST_TEST( (o2 <= o3_));
|
||||
BOOST_TEST( (o2_ <= o3_));
|
||||
|
||||
BOOST_TEST(!(oN > o1));
|
||||
BOOST_TEST(!(oN_ > o1));
|
||||
BOOST_TEST(!(oN > o2));
|
||||
BOOST_TEST(!(oN_ > o2));
|
||||
BOOST_TEST(!(oN > o2_));
|
||||
BOOST_TEST(!(oN_ > o2_));
|
||||
BOOST_TEST(!(oN > o3));
|
||||
BOOST_TEST(!(oN_ > o3));
|
||||
BOOST_TEST(!(oN > o3_));
|
||||
BOOST_TEST(!(oN_ > o3_));
|
||||
BOOST_TEST(!(o1 > o2));
|
||||
BOOST_TEST(!(o1 > o2_));
|
||||
BOOST_TEST(!(o1 > o3));
|
||||
BOOST_TEST(!(o1 > o3_));
|
||||
BOOST_TEST(!(o2 > o3));
|
||||
BOOST_TEST(!(o2_ > o3));
|
||||
BOOST_TEST(!(o2 > o3_));
|
||||
BOOST_TEST(!(o2_ > o3_));
|
||||
|
||||
BOOST_TEST(!(oN >= o1));
|
||||
BOOST_TEST(!(oN_ >= o1));
|
||||
BOOST_TEST(!(oN >= o2));
|
||||
BOOST_TEST(!(oN_ >= o2));
|
||||
BOOST_TEST(!(oN >= o2_));
|
||||
BOOST_TEST(!(oN_ >= o2_));
|
||||
BOOST_TEST(!(oN >= o3));
|
||||
BOOST_TEST(!(oN_ >= o3));
|
||||
BOOST_TEST(!(oN >= o3_));
|
||||
BOOST_TEST(!(oN_ >= o3_));
|
||||
BOOST_TEST(!(o1 >= o2));
|
||||
BOOST_TEST(!(o1 >= o2_));
|
||||
BOOST_TEST(!(o1 >= o3));
|
||||
BOOST_TEST(!(o1 >= o3_));
|
||||
BOOST_TEST(!(o2 >= o3));
|
||||
BOOST_TEST(!(o2_ >= o3));
|
||||
BOOST_TEST(!(o2 >= o3_));
|
||||
BOOST_TEST(!(o2_ >= o3_));
|
||||
|
||||
BOOST_TEST(!(o1 < oN));
|
||||
BOOST_TEST(!(o1 < oN_));
|
||||
BOOST_TEST(!(o2 < oN));
|
||||
BOOST_TEST(!(o2 < oN_));
|
||||
BOOST_TEST(!(o2_ < oN));
|
||||
BOOST_TEST(!(o2_ < oN_));
|
||||
BOOST_TEST(!(o3 < oN));
|
||||
BOOST_TEST(!(o3 < oN_));
|
||||
BOOST_TEST(!(o3_ < oN));
|
||||
BOOST_TEST(!(o3_ < oN_));
|
||||
BOOST_TEST(!(o2 < oN));
|
||||
BOOST_TEST(!(o2_ < oN_));
|
||||
BOOST_TEST(!(o3 < oN));
|
||||
BOOST_TEST(!(o3_ < oN_));
|
||||
BOOST_TEST(!(o3 < oN));
|
||||
BOOST_TEST(!(o3 < oN_));
|
||||
BOOST_TEST(!(o3_ < oN));
|
||||
BOOST_TEST(!(o3_ < oN_));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_swap()
|
||||
{
|
||||
typename concrete_type_of<T>::type v1(1), v2(2);
|
||||
optional<T&> o1(v1), o1_(v1), o2(v2), o2_(v2), oN, oN_;
|
||||
|
||||
// swap(o1, o1); DOESN'T WORK
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_optional_ref()
|
||||
{
|
||||
test_not_containing_value_for<T>();
|
||||
test_direct_init_for<T>();
|
||||
test_clearing_the_value<T>();
|
||||
test_arrow<T>();
|
||||
test_equality<T>();
|
||||
test_order<T>();
|
||||
test_swap<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_optional_const_ref()
|
||||
{
|
||||
test_not_containing_value_for<const T>();
|
||||
test_direct_init_for_const<T>();
|
||||
test_direct_init_for_noconst_const<T>();
|
||||
test_clearing_the_value<const T>();
|
||||
test_arrow_const<T>();
|
||||
test_arrow_noconst_const<T>();
|
||||
test_equality<const T>();
|
||||
test_order<const T>();
|
||||
//test_swap<T>();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_optional_ref<int>();
|
||||
test_optional_ref<ScopeGuard>();
|
||||
//test_optional_ref<Abstract>();
|
||||
|
||||
test_optional_const_ref<int>();
|
||||
test_optional_const_ref<ScopeGuard>();
|
||||
//test_optional_const_ref<Abstract>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
360
test/optional_test_swap.cpp
Normal file
@ -0,0 +1,360 @@
|
||||
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
// Revisions:
|
||||
// 12 May 2008 (added more swap tests)
|
||||
//
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
|
||||
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
#define ARG(T) (static_cast< T const* >(0))
|
||||
|
||||
namespace optional_swap_test
|
||||
{
|
||||
class default_ctor_exception : public std::exception {} ;
|
||||
class copy_ctor_exception : public std::exception {} ;
|
||||
class assignment_exception : public std::exception {} ;
|
||||
|
||||
//
|
||||
// Base class for swap test classes. Its assignment should not be called, when swapping
|
||||
// optional<T> objects. (The default std::swap would do so.)
|
||||
//
|
||||
class base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
base_class_with_forbidden_assignment & operator=(const base_class_with_forbidden_assignment &)
|
||||
{
|
||||
BOOST_TEST(!"The assignment should not be used while swapping!");
|
||||
throw assignment_exception();
|
||||
}
|
||||
|
||||
virtual ~base_class_with_forbidden_assignment() {}
|
||||
};
|
||||
|
||||
//
|
||||
// Class without default constructor
|
||||
//
|
||||
class class_without_default_ctor : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
char data;
|
||||
explicit class_without_default_ctor(char arg) : data(arg) {}
|
||||
};
|
||||
|
||||
//
|
||||
// Class whose default constructor should not be used by optional::swap!
|
||||
//
|
||||
class class_whose_default_ctor_should_not_be_used : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
char data;
|
||||
explicit class_whose_default_ctor_should_not_be_used(char arg) : data(arg) {}
|
||||
|
||||
class_whose_default_ctor_should_not_be_used()
|
||||
{
|
||||
BOOST_TEST(!"This default constructor should not be used while swapping!");
|
||||
throw default_ctor_exception();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Class whose default constructor should be used by optional::swap.
|
||||
// Its copy constructor should be avoided!
|
||||
//
|
||||
class class_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
char data;
|
||||
explicit class_whose_default_ctor_should_be_used(char arg) : data(arg) { }
|
||||
|
||||
class_whose_default_ctor_should_be_used() : data('\0') { }
|
||||
|
||||
class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &)
|
||||
{
|
||||
BOOST_TEST(!"This copy constructor should not be used while swapping!");
|
||||
throw copy_ctor_exception();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Class template whose default constructor should be used by optional::swap.
|
||||
// Its copy constructor should be avoided!
|
||||
//
|
||||
template <class T>
|
||||
class template_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
T data;
|
||||
explicit template_whose_default_ctor_should_be_used(T arg) : data(arg) { }
|
||||
|
||||
template_whose_default_ctor_should_be_used() : data('\0') { }
|
||||
|
||||
template_whose_default_ctor_should_be_used(const template_whose_default_ctor_should_be_used &)
|
||||
{
|
||||
BOOST_TEST(!"This copy constructor should not be used while swapping!");
|
||||
throw copy_ctor_exception();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Class whose explicit constructor should be used by optional::swap.
|
||||
// Its other constructors should be avoided!
|
||||
//
|
||||
class class_whose_explicit_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||
{
|
||||
public:
|
||||
char data;
|
||||
explicit class_whose_explicit_ctor_should_be_used(char arg) : data(arg) { }
|
||||
|
||||
class_whose_explicit_ctor_should_be_used()
|
||||
{
|
||||
BOOST_TEST(!"This default constructor should not be used while swapping!");
|
||||
throw default_ctor_exception();
|
||||
}
|
||||
|
||||
class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &)
|
||||
{
|
||||
BOOST_TEST(!"This copy constructor should not be used while swapping!");
|
||||
throw copy_ctor_exception();
|
||||
}
|
||||
};
|
||||
|
||||
void swap(class_whose_default_ctor_should_not_be_used & lhs, class_whose_default_ctor_should_not_be_used & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
void swap(class_whose_default_ctor_should_be_used & lhs, class_whose_default_ctor_should_be_used & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
void swap(class_without_default_ctor & lhs, class_without_default_ctor & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
void swap(class_whose_explicit_ctor_should_be_used & lhs, class_whose_explicit_ctor_should_be_used & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void swap(template_whose_default_ctor_should_be_used<T> & lhs, template_whose_default_ctor_should_be_used<T> & rhs)
|
||||
{
|
||||
std::swap(lhs.data, rhs.data);
|
||||
}
|
||||
|
||||
//
|
||||
// optional<T>::swap should be customized when neither the copy constructor
|
||||
// nor the default constructor of T are supposed to be used when swapping, e.g.,
|
||||
// for the following type T = class_whose_explicit_ctor_should_be_used.
|
||||
//
|
||||
void swap(boost::optional<class_whose_explicit_ctor_should_be_used> & x, boost::optional<class_whose_explicit_ctor_should_be_used> & y)
|
||||
{
|
||||
bool hasX(x);
|
||||
bool hasY(y);
|
||||
|
||||
if ( !hasX && !hasY )
|
||||
return;
|
||||
|
||||
if( !hasX )
|
||||
x = boost::in_place('\0');
|
||||
else if ( !hasY )
|
||||
y = boost::in_place('\0');
|
||||
|
||||
optional_swap_test::swap(*x,*y);
|
||||
|
||||
if( !hasX )
|
||||
y = boost::none ;
|
||||
else if( !hasY )
|
||||
x = boost::none ;
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace optional_swap_test.
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
||||
//
|
||||
// Compile time tweaking on whether or not swap should use the default constructor:
|
||||
//
|
||||
|
||||
template <> struct optional_swap_should_use_default_constructor<
|
||||
optional_swap_test::class_whose_default_ctor_should_be_used> : mpl::true_ {} ;
|
||||
|
||||
template <> struct optional_swap_should_use_default_constructor<
|
||||
optional_swap_test::class_whose_default_ctor_should_not_be_used> : mpl::false_ {} ;
|
||||
|
||||
template <class T> struct optional_swap_should_use_default_constructor<
|
||||
optional_swap_test::template_whose_default_ctor_should_be_used<T> > : mpl::true_ {} ;
|
||||
|
||||
|
||||
//
|
||||
// Specialization of boost::swap:
|
||||
//
|
||||
template <>
|
||||
void swap(optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & x, optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
namespace std {
|
||||
|
||||
//
|
||||
// Specializations of std::swap:
|
||||
//
|
||||
|
||||
template <>
|
||||
void swap(optional_swap_test::class_whose_default_ctor_should_be_used & x, optional_swap_test::class_whose_default_ctor_should_be_used & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swap(optional_swap_test::class_whose_default_ctor_should_not_be_used & x, optional_swap_test::class_whose_default_ctor_should_not_be_used & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swap(optional_swap_test::class_without_default_ctor & x, optional_swap_test::class_without_default_ctor & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
template <>
|
||||
void swap(optional_swap_test::class_whose_explicit_ctor_should_be_used & x, optional_swap_test::class_whose_explicit_ctor_should_be_used & y)
|
||||
{
|
||||
optional_swap_test::swap(x, y);
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
|
||||
//
|
||||
// Tests whether the swap function works properly for optional<T>.
|
||||
// Assumes that T has one data member, of type char.
|
||||
// Returns true iff the test is passed.
|
||||
//
|
||||
template <class T>
|
||||
void test_swap_function( T const* )
|
||||
{
|
||||
try
|
||||
{
|
||||
optional<T> obj1;
|
||||
optional<T> obj2('a');
|
||||
|
||||
// Self-swap should not have any effect.
|
||||
swap(obj1, obj1);
|
||||
swap(obj2, obj2);
|
||||
BOOST_TEST(!obj1);
|
||||
BOOST_TEST(!!obj2 && obj2->data == 'a');
|
||||
|
||||
// Call non-member swap.
|
||||
swap(obj1, obj2);
|
||||
|
||||
// Test if obj1 and obj2 are really swapped.
|
||||
BOOST_TEST(!!obj1 && obj1->data == 'a');
|
||||
BOOST_TEST(!obj2);
|
||||
|
||||
// Call non-member swap one more time.
|
||||
swap(obj1, obj2);
|
||||
|
||||
// Test if obj1 and obj2 are swapped back.
|
||||
BOOST_TEST(!obj1);
|
||||
BOOST_TEST(!!obj2 && obj2->data == 'a');
|
||||
}
|
||||
catch(const std::exception &)
|
||||
{
|
||||
// The swap function should not throw, for our test cases.
|
||||
BOOST_TEST(!"throw in swap");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tests whether the optional<T>::swap member function works properly.
|
||||
// Assumes that T has one data member, of type char.
|
||||
// Returns true iff the test is passed.
|
||||
//
|
||||
template <class T>
|
||||
void test_swap_member_function( T const* )
|
||||
{
|
||||
try
|
||||
{
|
||||
optional<T> obj1;
|
||||
optional<T> obj2('a');
|
||||
|
||||
// Self-swap should not have any effect.
|
||||
obj1.swap(obj1);
|
||||
obj2.swap(obj2);
|
||||
BOOST_TEST(!obj1);
|
||||
BOOST_TEST(!!obj2 && obj2->data == 'a');
|
||||
|
||||
// Call member swap.
|
||||
obj1.swap(obj2);
|
||||
|
||||
// Test if obj1 and obj2 are really swapped.
|
||||
BOOST_TEST(!!obj1 && obj1->data == 'a');
|
||||
BOOST_TEST(!obj2);
|
||||
|
||||
// Call member swap one more time.
|
||||
obj1.swap(obj2);
|
||||
|
||||
// Test if obj1 and obj2 are swapped back.
|
||||
BOOST_TEST(!obj1);
|
||||
BOOST_TEST(!!obj2 && obj2->data == 'a');
|
||||
}
|
||||
catch(const std::exception &)
|
||||
{
|
||||
BOOST_TEST(!"throw in swap");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Tests compile time tweaking of swap, by means of
|
||||
// optional_swap_should_use_default_constructor.
|
||||
//
|
||||
void test_swap_tweaking()
|
||||
{
|
||||
( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) );
|
||||
( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
|
||||
( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
|
||||
( test_swap_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
|
||||
( test_swap_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
|
||||
( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) );
|
||||
( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
|
||||
( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
|
||||
( test_swap_member_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
|
||||
( test_swap_member_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_swap_tweaking();
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
// 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
|
||||
//
|
||||
// Revisions:
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
//#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
//#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||
#include "boost/static_assert.hpp"
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
|
||||
const int global_i = 0;
|
||||
|
||||
class TestingReferenceBinding
|
||||
{
|
||||
public:
|
||||
TestingReferenceBinding(const int& ii)
|
||||
{
|
||||
BOOST_CHECK(&ii == &global_i);
|
||||
}
|
||||
|
||||
void operator=(const int& ii)
|
||||
{
|
||||
BOOST_CHECK(&ii == &global_i);
|
||||
}
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
void operator=(int&&)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class TestingReferenceBinding2 // same definition as above, I need a different type
|
||||
{
|
||||
public:
|
||||
TestingReferenceBinding2(const int& ii)
|
||||
{
|
||||
BOOST_CHECK(&ii == &global_i);
|
||||
}
|
||||
|
||||
void operator=(const int& ii)
|
||||
{
|
||||
BOOST_CHECK(&ii == &global_i);
|
||||
}
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
void operator=(int&&)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
void test_broken_compiler()
|
||||
{
|
||||
// we are not testing boost::optional here, but the c++ compiler
|
||||
// if this test fails, optional references will obviously fail too
|
||||
|
||||
const int& iref = global_i;
|
||||
BOOST_CHECK(&iref == &global_i);
|
||||
|
||||
TestingReferenceBinding ttt = global_i;
|
||||
ttt = global_i;
|
||||
|
||||
TestingReferenceBinding2 ttt2 = iref;
|
||||
ttt2 = iref;
|
||||
}
|
||||
|
||||
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
try
|
||||
{
|
||||
test_broken_compiler();
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -8,57 +9,66 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/optional.hpp"
|
||||
#include "boost/tuple/tuple.hpp"
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include "boost/none.hpp"
|
||||
#include "boost/tuple/tuple.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
// Test boost::tie() interoperabiliy.
|
||||
int test_main( int, char* [] )
|
||||
struct counting_oracle
|
||||
{
|
||||
typedef X T ;
|
||||
|
||||
try
|
||||
int val;
|
||||
counting_oracle() : val() { ++default_ctor_count; }
|
||||
counting_oracle(int v) : val(v) { ++val_ctor_count; }
|
||||
counting_oracle(const counting_oracle& rhs) : val(rhs.val) { ++copy_ctor_count; }
|
||||
counting_oracle& operator=(const counting_oracle& rhs) { val = rhs.val; ++copy_assign_count; return *this; }
|
||||
~counting_oracle() { ++dtor_count; }
|
||||
|
||||
static int dtor_count;
|
||||
static int default_ctor_count;
|
||||
static int val_ctor_count;
|
||||
static int copy_ctor_count;
|
||||
static int copy_assign_count;
|
||||
static int equals_count;
|
||||
|
||||
friend bool operator==(const counting_oracle& lhs, const counting_oracle& rhs) { ++equals_count; return lhs.val == rhs.val; }
|
||||
|
||||
static void clear_count()
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
T z(0);
|
||||
T a(1);
|
||||
T b(2);
|
||||
|
||||
optional<T> oa, ob ;
|
||||
|
||||
// T::T( T const& x ) is used
|
||||
set_pending_dtor( ARG(T) ) ;
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
boost::tie(oa,ob) = std::make_pair(a,b) ;
|
||||
check_is_not_pending_dtor( ARG(T) ) ;
|
||||
check_is_not_pending_copy( ARG(T) ) ;
|
||||
check_initialized(oa);
|
||||
check_initialized(ob);
|
||||
check_value(oa,a,z);
|
||||
check_value(ob,b,z);
|
||||
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
dtor_count = default_ctor_count = val_ctor_count = copy_ctor_count = copy_assign_count = equals_count = 0;
|
||||
}
|
||||
};
|
||||
|
||||
return 0;
|
||||
int counting_oracle::dtor_count = 0;
|
||||
int counting_oracle::default_ctor_count = 0;
|
||||
int counting_oracle::val_ctor_count = 0;
|
||||
int counting_oracle::copy_ctor_count = 0;
|
||||
int counting_oracle::copy_assign_count = 0;
|
||||
int counting_oracle::equals_count = 0;
|
||||
|
||||
// Test boost::tie() interoperability.
|
||||
int main()
|
||||
{
|
||||
const std::pair<counting_oracle, counting_oracle> pair(1, 2);
|
||||
counting_oracle::clear_count();
|
||||
|
||||
boost::optional<counting_oracle> o1, o2;
|
||||
boost::tie(o1, o2) = pair;
|
||||
|
||||
BOOST_TEST(o1);
|
||||
BOOST_TEST(o2);
|
||||
BOOST_TEST(*o1 == counting_oracle(1));
|
||||
BOOST_TEST(*o2 == counting_oracle(2));
|
||||
BOOST_TEST_EQ(2, counting_oracle::copy_ctor_count);
|
||||
BOOST_TEST_EQ(0, counting_oracle::copy_assign_count);
|
||||
BOOST_TEST_EQ(0, counting_oracle::default_ctor_count);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,18 +8,6 @@
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
// Revisions:
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
@ -27,11 +15,10 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/none.hpp"
|
||||
#include "boost/core/ignore_unused.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
using boost::optional;
|
||||
|
||||
struct IntWrapper
|
||||
{
|
||||
@ -48,10 +35,10 @@ void test_function_value_or_for()
|
||||
optional<T> oM1(1);
|
||||
const optional<T> oC2(2);
|
||||
|
||||
BOOST_CHECK(oM0.value_or(5) == 5);
|
||||
BOOST_CHECK(oC0.value_or(5) == 5);
|
||||
BOOST_CHECK(oM1.value_or(5) == 1);
|
||||
BOOST_CHECK(oC2.value_or(5) == 2);
|
||||
BOOST_TEST(oM0.value_or(5) == 5);
|
||||
BOOST_TEST(oC0.value_or(5) == 5);
|
||||
BOOST_TEST(oM1.value_or(5) == 1);
|
||||
BOOST_TEST(oC2.value_or(5) == 2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -64,36 +51,24 @@ void test_function_value_for()
|
||||
try
|
||||
{
|
||||
T& v = o1.value();
|
||||
BOOST_CHECK(v == 1);
|
||||
BOOST_TEST(v == 1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
T const& v = oC.value();
|
||||
BOOST_CHECK(v == 2);
|
||||
BOOST_TEST(v == 2);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
T& v = o0.value();
|
||||
BOOST_CHECK(false);
|
||||
boost::ignore_unused(v);
|
||||
}
|
||||
catch(boost::bad_optional_access const&)
|
||||
{
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
BOOST_TEST_THROWS(o0.value(), boost::bad_optional_access);
|
||||
}
|
||||
|
||||
void test_function_value()
|
||||
@ -120,12 +95,12 @@ void test_function_value_or()
|
||||
test_function_value_or_for<IntWrapper>();
|
||||
|
||||
optional<int> oi(1);
|
||||
BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 1);
|
||||
BOOST_CHECK(FatToIntConverter::conversions == 0);
|
||||
BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 1);
|
||||
BOOST_TEST(FatToIntConverter::conversions == 0);
|
||||
|
||||
oi = boost::none;
|
||||
BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 2);
|
||||
BOOST_CHECK(FatToIntConverter::conversions == 1);
|
||||
BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 2);
|
||||
BOOST_TEST(FatToIntConverter::conversions == 1);
|
||||
}
|
||||
|
||||
|
||||
@ -156,42 +131,34 @@ void test_function_value_or_eval()
|
||||
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_TEST_EQ(o1.value_or_eval(funM), 1);
|
||||
BOOST_TEST_EQ(oN.value_or_eval(funM), 5);
|
||||
BOOST_TEST_EQ(o1.value_or_eval(FunM()), 1);
|
||||
BOOST_TEST_EQ(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_TEST_EQ(o1.value_or_eval(funC), 1);
|
||||
BOOST_TEST_EQ(oN.value_or_eval(funC), 6);
|
||||
BOOST_TEST_EQ(o1.value_or_eval(FunC()), 1);
|
||||
BOOST_TEST_EQ(oN.value_or_eval(FunC()), 6);
|
||||
|
||||
BOOST_CHECK(o1.value_or_eval(funP) == 1);
|
||||
BOOST_CHECK(oN.value_or_eval(funP) == 7);
|
||||
BOOST_TEST_EQ(o1.value_or_eval(funP), 1);
|
||||
BOOST_TEST_EQ(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);
|
||||
BOOST_TEST_EQ(o1.value_or_eval([](){return 8;}), 1);
|
||||
BOOST_TEST_EQ(oN.value_or_eval([](){return 8;}), 8);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
BOOST_CHECK(o1.value_or_eval(throw_) == 1);
|
||||
BOOST_TEST_EQ(o1.value_or_eval(throw_), 1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BOOST_CHECK(oN.value_or_eval(throw_) == 1);
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_CHECK(true);
|
||||
}
|
||||
BOOST_TEST_THROWS(oN.value_or_eval(throw_), int);
|
||||
}
|
||||
|
||||
const optional<std::string> makeConstOptVal()
|
||||
@ -244,21 +211,12 @@ void test_move_only_getters()
|
||||
|
||||
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
|
||||
|
||||
int test_main( int, char* [] )
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
test_function_value();
|
||||
test_function_value_or();
|
||||
test_function_value_or_eval();
|
||||
test_const_move();
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
test_function_value();
|
||||
test_function_value_or();
|
||||
test_function_value_or_eval();
|
||||
test_const_move();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
|
91
test/testable_classes.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
// 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/libs/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
|
||||
#ifndef BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP
|
||||
#define BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP
|
||||
|
||||
struct ScopeGuard // no copy/move ctor/assign
|
||||
{
|
||||
int val_;
|
||||
explicit ScopeGuard(int v) : val_(v) {}
|
||||
int& val() { return val_; }
|
||||
const int& val() const { return val_; }
|
||||
|
||||
private:
|
||||
ScopeGuard(ScopeGuard const&);
|
||||
void operator=(ScopeGuard const&);
|
||||
};
|
||||
|
||||
struct Abstract
|
||||
{
|
||||
virtual int& val() = 0;
|
||||
virtual const int& val() const = 0;
|
||||
virtual ~Abstract() {}
|
||||
Abstract(){}
|
||||
|
||||
private:
|
||||
Abstract(Abstract const&);
|
||||
void operator=(Abstract const&);
|
||||
};
|
||||
|
||||
struct Impl : Abstract
|
||||
{
|
||||
int val_;
|
||||
Impl(int v) : val_(v) {}
|
||||
int& val() { return val_; }
|
||||
const int& val() const { return val_; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct concrete_type_of
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct concrete_type_of<Abstract>
|
||||
{
|
||||
typedef Impl type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct concrete_type_of<const Abstract>
|
||||
{
|
||||
typedef const Impl type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_arrow
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct has_arrow<int>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
int& val(int& i) { return i; }
|
||||
int& val(Abstract& a) { return a.val(); }
|
||||
int& val(ScopeGuard& g) { return g.val(); }
|
||||
|
||||
const int& val(const int& i) { return i; }
|
||||
const int& val(const Abstract& a) { return a.val(); }
|
||||
const int& val(const ScopeGuard& g) { return g.val(); }
|
||||
|
||||
bool operator==(const Abstract& l, const Abstract& r) { return l.val() == r.val(); }
|
||||
bool operator==(const ScopeGuard& l, const ScopeGuard& r) { return l.val() == r.val(); }
|
||||
|
||||
bool operator<(const Abstract& l, const Abstract& r) { return l.val() < r.val(); }
|
||||
bool operator<(const ScopeGuard& l, const ScopeGuard& r) { return l.val() < r.val(); }
|
||||
|
||||
#endif //BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP
|