summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/outcome/test/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/outcome/test/tests')
-rw-r--r--src/boost/libs/outcome/test/tests/comparison.cpp102
-rw-r--r--src/boost/libs/outcome/test/tests/constexpr.cpp118
-rw-r--r--src/boost/libs/outcome/test/tests/containers.cpp58
-rw-r--r--src/boost/libs/outcome/test/tests/core-outcome.cpp258
-rw-r--r--src/boost/libs/outcome/test/tests/core-result.cpp370
-rw-r--r--src/boost/libs/outcome/test/tests/coroutine-support.cpp120
-rw-r--r--src/boost/libs/outcome/test/tests/default-construction.cpp57
-rw-r--r--src/boost/libs/outcome/test/tests/experimental-core-outcome-status.cpp225
-rw-r--r--src/boost/libs/outcome/test/tests/experimental-core-result-status.cpp357
-rw-r--r--src/boost/libs/outcome/test/tests/experimental-p0709a.cpp169
-rw-r--r--src/boost/libs/outcome/test/tests/fileopen.cpp87
-rw-r--r--src/boost/libs/outcome/test/tests/hooks.cpp114
-rw-r--r--src/boost/libs/outcome/test/tests/issue0007.cpp81
-rw-r--r--src/boost/libs/outcome/test/tests/issue0009.cpp52
-rw-r--r--src/boost/libs/outcome/test/tests/issue0010.cpp88
-rw-r--r--src/boost/libs/outcome/test/tests/issue0012.cpp59
-rw-r--r--src/boost/libs/outcome/test/tests/issue0016.cpp56
-rw-r--r--src/boost/libs/outcome/test/tests/issue0059.cpp60
-rw-r--r--src/boost/libs/outcome/test/tests/issue0061.cpp128
-rw-r--r--src/boost/libs/outcome/test/tests/issue0064.cpp50
-rw-r--r--src/boost/libs/outcome/test/tests/issue0065.cpp66
-rw-r--r--src/boost/libs/outcome/test/tests/issue0071.cpp45
-rw-r--r--src/boost/libs/outcome/test/tests/issue0095.cpp58
-rw-r--r--src/boost/libs/outcome/test/tests/issue0115.cpp57
-rw-r--r--src/boost/libs/outcome/test/tests/issue0116.cpp45
-rw-r--r--src/boost/libs/outcome/test/tests/issue0140.cpp96
-rw-r--r--src/boost/libs/outcome/test/tests/issue0182.cpp42
-rw-r--r--src/boost/libs/outcome/test/tests/issue0203.cpp103
-rw-r--r--src/boost/libs/outcome/test/tests/issue0210.cpp78
-rw-r--r--src/boost/libs/outcome/test/tests/issue0220.cpp55
-rw-r--r--src/boost/libs/outcome/test/tests/noexcept-propagation.cpp84
-rw-r--r--src/boost/libs/outcome/test/tests/propagate.cpp90
-rw-r--r--src/boost/libs/outcome/test/tests/serialisation.cpp49
-rw-r--r--src/boost/libs/outcome/test/tests/success-failure.cpp69
-rw-r--r--src/boost/libs/outcome/test/tests/swap.cpp432
-rw-r--r--src/boost/libs/outcome/test/tests/udts.cpp154
-rw-r--r--src/boost/libs/outcome/test/tests/value-or-error.cpp54
37 files changed, 4186 insertions, 0 deletions
diff --git a/src/boost/libs/outcome/test/tests/comparison.cpp b/src/boost/libs/outcome/test/tests/comparison.cpp
new file mode 100644
index 000000000..1c093ffd2
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/comparison.cpp
@@ -0,0 +1,102 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4127) // conditional expression is constant
+#pragma warning(disable : 4244) // conversion from int to short
+#endif
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_comparison, "Tests that the outcome can compare to compatible outcomes")
+{
+#if !defined(__APPLE__) || defined(__cpp_exceptions)
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ auto p = boost::copy_exception(std::runtime_error("hi"));
+ // value comparison
+ {
+ outcome<int> a(1), b(2), c(2);
+ BOOST_CHECK(a == a);
+ BOOST_CHECK(b == b);
+ BOOST_CHECK(c == c);
+ BOOST_CHECK(a != b);
+ BOOST_CHECK(b == c);
+ }
+ // homogeneous outcome comparison
+ {
+ outcome<int> a(1), b(2), c(boost::system::errc::invalid_argument), d(p);
+ BOOST_CHECK(a == a);
+ BOOST_CHECK(a != b);
+ BOOST_CHECK(a != c);
+ BOOST_CHECK(a != d);
+ BOOST_CHECK(b == b);
+ BOOST_CHECK(b != c);
+ BOOST_CHECK(b != d);
+ BOOST_CHECK(c == c);
+ BOOST_CHECK(c != d);
+ BOOST_CHECK(d == d);
+ outcome<int> e(boost::system::errc::invalid_argument), f(p);
+ BOOST_CHECK(c == e);
+ BOOST_CHECK(d == f);
+ }
+ // heterogeneous outcome comparison, so outcome<int> to outcome<double> etc
+ {
+ outcome<int> a(1);
+ outcome<double> b(1);
+ outcome<unsigned short> c(1);
+ BOOST_CHECK(a == b);
+ BOOST_CHECK(a == c);
+ BOOST_CHECK(b == a);
+ BOOST_CHECK(b == c);
+ BOOST_CHECK(c == a);
+ BOOST_CHECK(c == b);
+ // outcome<void> e(in_place_type<void>);
+ outcome<unsigned short> f(boost::system::errc::invalid_argument);
+ outcome<double> g(p);
+ // BOOST_CHECK(a != e);
+ BOOST_CHECK(a != f);
+ BOOST_CHECK(a != g);
+ // BOOST_CHECK(e != f);
+ BOOST_CHECK(f != g);
+ }
+ // upconverting outcome comparison, so outcome<int>==result<int> etc
+ {
+ outcome<int> a(1);
+ result<int> b(1);
+ BOOST_CHECK(a == b);
+ BOOST_CHECK(b == a);
+ // result<void> e(in_place_type<void>), f(boost::system::errc::invalid_argument);
+ // BOOST_CHECK(a != e);
+ // BOOST_CHECK(a != f);
+ }
+ // Should I do outcome<int>(5) == 5? Unsure if it's wise
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/constexpr.cpp b/src/boost/libs/outcome/test/tests/constexpr.cpp
new file mode 100644
index 000000000..327b8f26a
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/constexpr.cpp
@@ -0,0 +1,118 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (9 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#if __cplusplus >= 201700 || _HAS_CXX17
+// Match LiteralType, even on C++ 17 and later
+template <class T> struct is_literal_type
+{
+ static constexpr bool value = //
+ std::is_void<T>::value //
+ || std::is_scalar<T>::value //
+ || std::is_reference<T>::value //
+ // leave out is_array for simplicity
+ || (std::is_class<T>::value && std::is_trivially_destructible<T>::value
+ // how does one detect if a type has at least one constexpr constructor without Reflection???
+ ) // leave out union for simplicity
+ ;
+};
+#else
+template <class T> using is_literal_type = std::is_literal_type<T>;
+#endif
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_constexpr, "Tests that outcome works as intended in a constexpr evaluation context")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+
+ static_assert(is_literal_type<result<int, void, void>>::value, "result<int, void, void> is not a literal type!");
+ static_assert(is_literal_type<outcome<int, void, void>>::value, "outcome<int, void, void> is not a literal type!");
+
+ // Unfortunately result<T> can never be a literal type as error_code can never be literal
+ //
+ // It can however be trivially destructible as error_code is trivially destructible. That
+ // makes possible lots of compiler optimisations
+ static_assert(std::is_trivially_destructible<result<int>>::value, "result<int> is not trivially destructible!");
+ static_assert(std::is_trivially_destructible<result<void>>::value, "result<void> is not trivially destructible!");
+
+ // outcome<T> default has no trivial operations, but if configured it can become so
+ static_assert(std::is_trivially_destructible<outcome<int, boost::system::error_code, void>>::value,
+ "outcome<int, boost::system::error_code, void> is not trivially destructible!");
+
+ {
+ // Test compatible results can be constructed from one another
+ constexpr result<int, long> g(in_place_type<int>, 5);
+ constexpr result<long, int> g2(g);
+ static_assert(g.has_value(), "");
+ static_assert(!g.has_error(), "");
+ static_assert(g.assume_value() == 5, ""); // value() with UDT E won't compile
+ static_assert(g2.has_value(), "");
+ static_assert(!g2.has_error(), "");
+ static_assert(g2.assume_value() == 5, ""); // value() with UDT E won't compile
+ constexpr result<void, int> g3(in_place_type<void>);
+ constexpr result<long, int> g4(g3);
+ constexpr result<int, void> g5(in_place_type<void>);
+ constexpr result<long, int> g6(g5);
+ (void) g4;
+ (void) g6;
+
+ // Test void
+ constexpr result<void, int> h(in_place_type<void>);
+ static_assert(h.has_value(), "");
+ constexpr result<int, void> h2(in_place_type<void>);
+ static_assert(!h2.has_value(), "");
+ static_assert(h2.has_error(), "");
+
+ // Test const
+ constexpr result<const int, void> i(5);
+ constexpr result<const int, void> i2(i);
+ (void) i2;
+ }
+ {
+ // Test compatible outcomes can be constructed from one another
+ constexpr outcome<int, long, char *> g(in_place_type<int>, 5);
+ constexpr outcome<long, int, const char *> g2(g);
+ static_assert(g.has_value(), "");
+ static_assert(!g.has_error(), "");
+ static_assert(!g.has_exception(), "");
+ static_assert(g.assume_value() == 5, ""); // value() with UDT E won't compile
+ static_assert(g2.has_value(), "");
+ static_assert(!g2.has_error(), "");
+ static_assert(!g2.has_exception(), "");
+ static_assert(g2.assume_value() == 5, ""); // value() with UDT E won't compile
+ constexpr outcome<void, int, char *> g3(in_place_type<void>);
+ constexpr outcome<long, int, const char *> g4(g3);
+ constexpr outcome<int, void, char *> g5(in_place_type<void>);
+ constexpr outcome<long, int, const char *> g6(g5);
+ (void) g4;
+ (void) g6;
+ }
+}
diff --git a/src/boost/libs/outcome/test/tests/containers.cpp b/src/boost/libs/outcome/test/tests/containers.cpp
new file mode 100644
index 000000000..b92af4b70
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/containers.cpp
@@ -0,0 +1,58 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_containers, "Tests that outcome works as intended inside containers")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ outcome<std::vector<int>> a(std::vector<int>{5, 6, 7, 8});
+ BOOST_CHECK(a.has_value());
+ BOOST_CHECK(a.value().size() == 4U);
+ auto b(a);
+ BOOST_CHECK(a.has_value());
+ BOOST_CHECK(a.value().size() == 4U);
+ BOOST_CHECK(b.has_value());
+ BOOST_CHECK(b.value().size() == 4U);
+
+ std::vector<outcome<std::vector<int>>> vect;
+ vect.push_back(std::vector<int>{5, 6, 7, 8});
+ vect.push_back(std::vector<int>{1, 2, 3, 4});
+ BOOST_REQUIRE(vect.size() == 2U); // NOLINT
+ BOOST_CHECK(vect[0].has_value());
+ BOOST_CHECK(vect[1].has_value());
+ BOOST_CHECK(vect[0].value().size() == 4U);
+ BOOST_CHECK(vect[1].value().size() == 4U);
+ BOOST_CHECK(vect[0].value().front() == 5);
+ BOOST_CHECK(vect[0].value().back() == 8);
+ BOOST_CHECK(vect[1].value().front() == 1);
+ BOOST_CHECK(vect[1].value().back() == 4);
+}
diff --git a/src/boost/libs/outcome/test/tests/core-outcome.cpp b/src/boost/libs/outcome/test/tests/core-outcome.cpp
new file mode 100644
index 000000000..dfa15d355
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/core-outcome.cpp
@@ -0,0 +1,258 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (18 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#include <iostream>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4702) // unreachable code
+#endif
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome, "Tests that the outcome works as intended")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+
+ static_assert(std::is_constructible<outcome<long>, int>::value, "Sanity check that monad can be constructed from a value_type");
+ static_assert(!std::is_constructible<outcome<outcome<long>>, int>::value, "Sanity check that outer monad can be constructed from an inner monad's value_type");
+ static_assert(!std::is_constructible<outcome<outcome<outcome<long>>>, int>::value, "Sanity check that outer monad can be constructed from an inner inner monad's value_type");
+ static_assert(!std::is_constructible<outcome<outcome<outcome<outcome<long>>>>, int>::value, "Sanity check that outer monad can be constructed from an inner inner monad's value_type");
+
+ static_assert(std::is_constructible<outcome<int>, outcome<long>>::value, "Sanity check that compatible monads can be constructed from one another");
+ static_assert(std::is_constructible<outcome<outcome<int>>, outcome<long>>::value, "Sanity check that outer monad can be constructed from a compatible monad");
+ static_assert(!std::is_constructible<outcome<outcome<outcome<int>>>, outcome<long>>::value, "Sanity check that outer monad can be constructed from a compatible monad up to two nestings deep");
+ static_assert(!std::is_constructible<outcome<outcome<outcome<outcome<int>>>>, outcome<long>>::value, "Sanity check that outer monad can be constructed from a compatible monad three or more nestings deep");
+ static_assert(!std::is_constructible<outcome<std::string>, outcome<int>>::value, "Sanity check that incompatible monads cannot be constructed from one another");
+
+ static_assert(std::is_constructible<outcome<int>, outcome<void>>::value, "Sanity check that all monads can be constructed from a void monad");
+ static_assert(std::is_constructible<outcome<outcome<int>>, outcome<void>>::value, "Sanity check that outer monad can be constructed from a compatible monad");
+ static_assert(std::is_constructible<outcome<outcome<outcome<int>>>, outcome<void>>::value, "Sanity check that outer monad can be constructed from a compatible monad up to two nestings deep");
+ static_assert(!std::is_constructible<outcome<void>, outcome<int>>::value, "Sanity check that incompatible monads cannot be constructed from one another");
+
+ static_assert(std::is_void<result<void>::value_type>::value, "Sanity check that result<void> has a void value_type");
+ static_assert(std::is_void<result<void, void>::error_type>::value, "Sanity check that result<void, void> has a void error_type");
+ // static_assert(std::is_void<outcome<void, void, void>::exception_type>::value, "Sanity check that outcome<void, void, void> has a void exception_type");
+
+ static_assert(std::is_same<outcome<int>::value_type, int>::value, "Sanity check that outcome<int> has a int value_type");
+ static_assert(std::is_same<outcome<int>::error_type, boost::system::error_code>::value, "Sanity check that outcome<int> has a error_code error_type");
+ static_assert(std::is_same<outcome<int>::exception_type, boost::exception_ptr>::value, "Sanity check that outcome<int> has a exception_ptr exception_type");
+
+
+ { // errored int
+ outcome<int> m(boost::system::errc::bad_address);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), boost::system::system_error);
+ BOOST_CHECK_NO_THROW(m.error());
+ BOOST_CHECK_THROW(m.exception(), bad_outcome_access);
+ BOOST_CHECK_THROW(boost::rethrow_exception(m.failure()), boost::system::system_error);
+ }
+ { // errored void
+ outcome<void> m(boost::system::errc::bad_address);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(([&m]() -> void { return m.value(); }()), boost::system::system_error);
+ BOOST_CHECK_NO_THROW(m.error());
+ BOOST_CHECK_THROW(m.exception(), bad_outcome_access);
+ BOOST_CHECK_THROW(boost::rethrow_exception(m.failure()), boost::system::system_error);
+ }
+ { // valued int
+ outcome<int> m(5);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == 5);
+ m.value() = 6;
+ BOOST_CHECK(m.value() == 6);
+ BOOST_CHECK_THROW(m.error(), bad_outcome_access);
+ BOOST_CHECK_THROW(m.exception(), bad_outcome_access);
+ BOOST_CHECK(!m.failure());
+ }
+ { // moves do not clear state
+ outcome<std::string> m("niall");
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == "niall");
+ m.value() = "NIALL";
+ BOOST_CHECK(m.value() == "NIALL");
+ auto temp(std::move(m).value());
+ BOOST_CHECK(temp == "NIALL");
+ BOOST_CHECK(m.value().empty()); // NOLINT
+ }
+ { // valued void
+ outcome<void> m(in_place_type<void>);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_NO_THROW(m.value()); // works, but type returned is unusable
+ BOOST_CHECK_THROW(m.error(), bad_outcome_access);
+ BOOST_CHECK_THROW(m.exception(), bad_outcome_access);
+ BOOST_CHECK(!m.failure());
+ }
+ { // errored
+ boost::system::error_code ec(5, boost::system::system_category());
+ outcome<int> m(ec);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), boost::system::system_error);
+ BOOST_CHECK(m.error() == ec);
+ BOOST_CHECK_THROW(m.exception(), bad_outcome_access);
+#ifndef BOOST_NO_EXCEPTIONS
+ BOOST_CHECK(m.failure());
+ try
+ {
+ boost::rethrow_exception(m.failure());
+ }
+ catch(const boost::system::system_error &ex)
+ {
+ BOOST_CHECK(ex.code() == ec);
+ BOOST_CHECK(ex.code().value() == 5);
+ }
+#endif
+ }
+#if !defined(__APPLE__) || defined(__cpp_exceptions)
+ { // excepted
+ boost::system::error_code ec(5, boost::system::system_category());
+ auto e = boost::copy_exception(boost::system::system_error(ec)); // NOLINT
+ outcome<int> m(e);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(m.has_exception());
+ BOOST_CHECK_THROW(m.value(), boost::system::system_error);
+ BOOST_CHECK_THROW(m.error(), bad_outcome_access);
+ BOOST_CHECK(m.exception() == e);
+#ifndef BOOST_NO_EXCEPTIONS
+ BOOST_CHECK(m.failure());
+ try
+ {
+ boost::rethrow_exception(m.failure());
+ }
+ catch(const boost::system::system_error &ex)
+ {
+ BOOST_CHECK(ex.code() == ec);
+ BOOST_CHECK(ex.code().value() == 5);
+ }
+#endif
+ }
+ { // custom error type
+ struct Foo
+ {
+ };
+ auto e = boost::copy_exception(Foo());
+ outcome<int> m(e);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(m.has_exception());
+ BOOST_CHECK_THROW(m.value(), Foo);
+ BOOST_CHECK_THROW(m.error(), bad_outcome_access);
+ BOOST_CHECK(m.exception() == e);
+ }
+ { // outcome<void, void> should work
+ boost::system::error_code ec(5, boost::system::system_category());
+ auto e = boost::copy_exception(boost::system::system_error(ec));
+ outcome<void, void> m(e);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(m.has_exception());
+ }
+#endif
+
+
+ {
+ outcome<int> a(5);
+ outcome<int> b(make_error_code(boost::system::errc::invalid_argument));
+ std::cout << sizeof(a) << std::endl; // 40 bytes
+ a.assume_value();
+ b.assume_error();
+#ifndef BOOST_NO_EXCEPTIONS
+ try
+ {
+ b.value();
+ std::cerr << "fail" << std::endl;
+ std::terminate();
+ }
+ catch(const boost::system::system_error & /*unused*/)
+ {
+ }
+#endif
+ static_assert(!std::is_default_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<decltype(a)>::value, "");
+ static_assert(std::is_copy_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<decltype(a)>::value, "");
+ static_assert(std::is_nothrow_copy_constructible<decltype(a)>::value, "");
+ static_assert(std::is_copy_assignable<decltype(a)>::value, "");
+ static_assert(!std::is_trivially_copy_assignable<decltype(a)>::value, "");
+ static_assert(std::is_nothrow_copy_assignable<decltype(a)>::value, "");
+ static_assert(!std::is_trivially_destructible<decltype(a)>::value, "");
+ static_assert(std::is_nothrow_destructible<decltype(a)>::value, "");
+
+ // Test void compiles
+ outcome<void> c(in_place_type<void>);
+ outcome<void> c2(c);
+ (void) c2;
+ // Test int, void compiles
+ outcome<int, void> d(in_place_type<boost::exception_ptr>);
+ }
+
+ {
+ // Can only be constructed via multiple args
+ struct udt3
+ {
+ udt3() = delete;
+ udt3(udt3 &&) = delete;
+ udt3(const udt3 &) = delete;
+ udt3 &operator=(udt3 &&) = delete;
+ udt3 &operator=(const udt3 &) = delete;
+ explicit udt3(int /*unused*/, const char * /*unused*/, std::nullptr_t /*unused*/) {}
+ ~udt3() = default;
+ };
+ // Test a udt which can only be constructed in place compiles
+ outcome<udt3> g(in_place_type<udt3>, 5, static_cast<const char *>("niall"), nullptr);
+ // Does converting inplace construction also work?
+ outcome<udt3> h(5, static_cast<const char *>("niall"), nullptr);
+ outcome<udt3> i(ENOMEM, boost::system::generic_category());
+ BOOST_CHECK(h.has_value());
+ BOOST_CHECK(i.has_error());
+ }
+}
diff --git a/src/boost/libs/outcome/test/tests/core-result.cpp b/src/boost/libs/outcome/test/tests/core-result.cpp
new file mode 100644
index 000000000..2ded9cb6a
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/core-result.cpp
@@ -0,0 +1,370 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (30 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef TESTING_WG21_EXPERIMENTAL_RESULT
+#include <boost/outcome/experimental/result.hpp>
+#define BOOST_OUTCOME_AUTO_TEST_CASE(...) BOOST_AUTO_TEST_CASE(__VA_ARGS__)
+#else
+#include <boost/outcome/result.hpp>
+#endif
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#include <iostream>
+
+#ifndef BOOST_NO_EXCEPTIONS
+// Custom error type with payload
+struct payload
+{
+ boost::system::error_code ec;
+ const char *str{nullptr};
+ payload() = default;
+ payload(boost::system::errc::errc_t _ec, const char *_str)
+ : ec(make_error_code(_ec))
+ , str(_str)
+ {
+ }
+};
+struct payload_exception : std::runtime_error
+{
+ explicit payload_exception(const char *what)
+ : std::runtime_error(what)
+ {
+ }
+};
+inline const boost::system::error_code &make_error_code(const payload &p)
+{
+ return p.ec;
+}
+inline void outcome_throw_as_system_error_with_payload(const payload &p)
+{
+ throw payload_exception(p.str);
+}
+#endif
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_result, "Tests that the result works as intended")
+{
+#ifdef TESTING_WG21_EXPERIMENTAL_RESULT
+ using namespace std::experimental;
+ using std::in_place_type;
+#else
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+#endif
+
+ static_assert(std::is_constructible<result<long>, int>::value, "Sanity check that monad can be constructed from a value_type");
+ static_assert(!std::is_constructible<result<result<long>>, int>::value, "Sanity check that outer monad can be constructed from an inner monad's value_type");
+ static_assert(!std::is_constructible<result<result<result<long>>>, int>::value, "Sanity check that outer monad can be constructed from an inner inner monad's value_type");
+ static_assert(!std::is_constructible<result<result<result<result<long>>>>, int>::value, "Sanity check that outer monad can be constructed from an inner inner monad's value_type");
+
+ static_assert(std::is_constructible<result<int>, result<long>>::value, "Sanity check that compatible monads can be constructed from one another");
+ static_assert(std::is_constructible<result<result<int>>, result<long>>::value, "Sanity check that outer monad can be constructed from a compatible monad");
+ static_assert(!std::is_constructible<result<result<result<int>>>, result<long>>::value, "Sanity check that outer monad can be constructed from a compatible monad up to two nestings deep");
+ static_assert(!std::is_constructible<result<result<result<result<int>>>>, result<long>>::value, "Sanity check that outer monad can be constructed from a compatible monad three or more nestings deep");
+ static_assert(!std::is_constructible<result<std::string>, result<int>>::value, "Sanity check that incompatible monads cannot be constructed from one another");
+
+#ifndef TESTING_WG21_EXPERIMENTAL_RESULT
+ static_assert(std::is_constructible<result<int>, result<void>>::value, "Sanity check that all monads can be constructed from a void monad");
+ static_assert(std::is_constructible<result<result<int>>, result<void>>::value, "Sanity check that outer monad can be constructed from a compatible monad");
+ static_assert(std::is_constructible<result<result<result<int>>>, result<void>>::value, "Sanity check that outer monad can be constructed from a compatible monad up to two nestings deep");
+ static_assert(!std::is_constructible<result<void>, result<int>>::value, "Sanity check that incompatible monads cannot be constructed from one another");
+#endif
+ static_assert(std::is_void<result<void>::value_type>::value, "Sanity check that result<void> has a void value_type");
+#ifndef TESTING_WG21_EXPERIMENTAL_RESULT
+ static_assert(std::is_void<result<void, void>::error_type>::value, "Sanity check that result<void, void> has a void error_type");
+#endif
+
+ static_assert(std::is_same<result<int>::value_type, int>::value, "Sanity check that result<int> has a int value_type");
+ static_assert(std::is_same<result<int>::error_type, boost::system::error_code>::value, "Sanity check that result<int> has a error_code error_type");
+
+
+ { // errored int
+ result<int> m(boost::system::errc::bad_address);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), boost::system::system_error);
+ BOOST_CHECK_NO_THROW(m.error());
+ }
+ { // errored void
+ result<void> m(boost::system::errc::bad_address);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+// BOOST_CHECK(!m.has_exception());
+#ifndef TESTING_WG21_EXPERIMENTAL_RESULT
+ BOOST_CHECK_THROW(([&m]() -> void { return m.value(); }()), boost::system::system_error);
+#endif
+ BOOST_CHECK_NO_THROW(m.error());
+ }
+ { // valued int
+ result<int> m(5);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == 5);
+ m.value() = 6;
+ BOOST_CHECK(m.value() == 6);
+ BOOST_CHECK_THROW(m.error(), bad_result_access);
+ }
+ { // valued bool
+ result<bool> m(false);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == false);
+ m.value() = true;
+ BOOST_CHECK(m.value() == true);
+ BOOST_CHECK_THROW(m.error(), bad_result_access);
+ }
+ { // moves do not clear state
+ result<std::string> m("niall");
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == "niall");
+ m.value() = "NIALL";
+ BOOST_CHECK(m.value() == "NIALL");
+ auto temp(std::move(m).value());
+ BOOST_CHECK(temp == "NIALL");
+ BOOST_CHECK(m.value().empty()); // NOLINT
+ }
+ { // valued void
+ result<void> m(in_place_type<void>);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_NO_THROW(m.value()); // works, but type returned is unusable
+ BOOST_CHECK_THROW(m.error(), bad_result_access);
+ }
+ { // errored
+ boost::system::error_code ec(5, boost::system::system_category());
+ result<int> m(ec);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), boost::system::system_error);
+ BOOST_CHECK(m.error() == ec);
+ }
+#if !defined(__APPLE__) || defined(__cpp_exceptions)
+ { // errored, custom
+ boost::system::error_code ec(5, boost::system::system_category());
+ auto e = boost::copy_exception(boost::system::system_error(ec)); // NOLINT
+ result<int, boost::exception_ptr> m(e);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), boost::system::system_error);
+ BOOST_CHECK(m.error() == e);
+ }
+#endif
+#ifndef TESTING_WG21_EXPERIMENTAL_RESULT
+ { // custom error type
+ struct Foo
+ {
+ };
+ result<int, Foo> m(in_place_type<Foo>);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ // BOOST_CHECK_NO_THROW(m.value());
+ // BOOST_CHECK_NO_THROW(m.error());
+ }
+ if(false) // NOLINT
+ { // void, void is permitted, but is not constructible
+ result<void, void> *m = nullptr;
+ m->value();
+ m->error();
+ }
+#endif
+
+ {
+ // Deliberately define non-trivial operations
+ struct udt
+ {
+ int _v{0};
+ udt() = default;
+ udt(udt &&o) noexcept : _v(o._v) {}
+ udt(const udt &o) // NOLINT
+ : _v(o._v)
+ {
+ }
+ udt &operator=(udt &&o) noexcept
+ {
+ _v = o._v;
+ return *this;
+ }
+ udt &operator=(const udt &o) // NOLINT
+ {
+ _v = o._v;
+ return *this;
+ }
+ ~udt() { _v = 0; }
+ };
+ // No default construction, no copy nor move
+ struct udt2
+ {
+ udt2() = delete;
+ udt2(udt2 &&) = delete;
+ udt2(const udt2 &) = delete;
+ udt2 &operator=(udt2 &&) = delete;
+ udt2 &operator=(const udt2 &) = delete;
+ explicit udt2(int /*unused*/) {}
+ ~udt2() = default;
+ };
+ // Can only be constructed via multiple args
+ struct udt3
+ {
+ udt3() = delete;
+ udt3(udt3 &&) = delete;
+ udt3(const udt3 &) = delete;
+ udt3 &operator=(udt3 &&) = delete;
+ udt3 &operator=(const udt3 &) = delete;
+ explicit udt3(int /*unused*/, const char * /*unused*/, std::nullptr_t /*unused*/) {}
+ ~udt3() = default;
+ };
+
+
+ result<int> a(5);
+ result<int> b(make_error_code(boost::system::errc::invalid_argument));
+ std::cout << sizeof(a) << std::endl; // 32 bytes
+ if(false) // NOLINT
+ {
+ b.assume_value();
+ a.assume_error();
+ }
+#ifndef BOOST_NO_EXCEPTIONS
+ try
+ {
+ b.value();
+ std::cerr << "fail" << std::endl;
+ std::terminate();
+ }
+ catch(const boost::system::system_error & /*unused*/)
+ {
+ }
+#endif
+ static_assert(!std::is_default_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<decltype(a)>::value, "");
+ static_assert(std::is_copy_constructible<decltype(a)>::value, "");
+// Quality of implementation of std::optional is poor :(
+#ifndef TESTING_WG21_EXPERIMENTAL_RESULT
+ static_assert(std::is_trivially_copy_constructible<decltype(a)>::value, "");
+ static_assert(std::is_nothrow_copy_constructible<decltype(a)>::value, "");
+ static_assert(std::is_copy_assignable<decltype(a)>::value, "");
+ static_assert(std::is_trivially_copy_assignable<decltype(a)>::value, "");
+ static_assert(std::is_nothrow_copy_assignable<decltype(a)>::value, "");
+#endif
+ static_assert(std::is_trivially_destructible<decltype(a)>::value, "");
+ static_assert(std::is_nothrow_destructible<decltype(a)>::value, "");
+
+ // Test void compiles
+ result<void> c(in_place_type<void>);
+ result<void> c2(c);
+ (void) c2;
+
+ // Test a standard udt compiles
+ result<udt> d(in_place_type<udt>);
+ result<udt> d2(d);
+ static_assert(!std::is_default_constructible<decltype(d)>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<decltype(d)>::value, "");
+ static_assert(std::is_copy_constructible<decltype(d)>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<decltype(d)>::value, "");
+ static_assert(!std::is_nothrow_copy_constructible<decltype(d)>::value, "");
+ static_assert(std::is_copy_assignable<decltype(d)>::value, "");
+ static_assert(!std::is_trivially_copy_assignable<decltype(d)>::value, "");
+ static_assert(!std::is_nothrow_copy_assignable<decltype(d)>::value, "");
+ static_assert(std::is_move_assignable<decltype(d)>::value, "");
+ static_assert(!std::is_trivially_move_assignable<decltype(d)>::value, "");
+ static_assert(std::is_nothrow_move_assignable<decltype(d)>::value, "");
+ static_assert(!std::is_trivially_destructible<decltype(d)>::value, "");
+ static_assert(std::is_nothrow_destructible<decltype(d)>::value, "");
+
+ // Test a highly pathological udt compiles
+ result<udt2> e(in_place_type<udt2>, 5);
+ // result<udt2> e2(e);
+ static_assert(!std::is_default_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_copy_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_nothrow_copy_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_copy_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_trivially_copy_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_nothrow_copy_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_move_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_trivially_move_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_nothrow_move_assignable<decltype(e)>::value, "");
+
+ // Test a udt which can only be constructed in place compiles
+ result<udt3> g(in_place_type<udt3>, 5, static_cast<const char *>("niall"), nullptr);
+ // Does converting inplace construction also work?
+ result<udt3> h(5, static_cast<const char *>("niall"), nullptr);
+ result<udt3> i(ENOMEM, boost::system::generic_category());
+ BOOST_CHECK(h.has_value());
+ BOOST_CHECK(i.has_error());
+ }
+
+ // Test direct use of error code enum works
+ {
+ constexpr result<int, boost::system::errc::errc_t> a(5), b(boost::system::errc::invalid_argument);
+ static_assert(a.value() == 5, "a is not 5");
+ static_assert(b.error() == boost::system::errc::invalid_argument, "b is not errored");
+ BOOST_CHECK_THROW(b.value(), boost::system::system_error);
+ }
+
+#ifndef TESTING_WG21_EXPERIMENTAL_RESULT
+#ifndef BOOST_NO_EXCEPTIONS
+ // Test payload facility
+ {
+ const char *niall = "niall";
+ result<int, payload> b{boost::system::errc::invalid_argument, niall};
+ try
+ {
+ b.value();
+ BOOST_CHECK(false);
+ }
+ catch(const payload_exception &e)
+ {
+ BOOST_CHECK(!strcmp(e.what(), niall));
+ }
+ catch(...)
+ {
+ BOOST_CHECK(false);
+ }
+ }
+#endif
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/coroutine-support.cpp b/src/boost/libs/outcome/test/tests/coroutine-support.cpp
new file mode 100644
index 000000000..43c46b09b
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/coroutine-support.cpp
@@ -0,0 +1,120 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#if defined(__cpp_coroutines)
+
+#include <boost/outcome/coroutine_support.hpp>
+#include <boost/outcome/outcome.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+namespace coroutines
+{
+ template <class T> using eager = BOOST_OUTCOME_V2_NAMESPACE::awaitables::eager<T>;
+ template <class T> using lazy = BOOST_OUTCOME_V2_NAMESPACE::awaitables::lazy<T>;
+ template <class T, class E = boost::system::error_code> using result = BOOST_OUTCOME_V2_NAMESPACE::result<T, E>;
+
+ inline eager<result<int>> eager_int(int x) { co_return x + 1; }
+ inline lazy<result<int>> lazy_int(int x) { co_return x + 1; }
+ inline eager<result<int>> eager_error() { co_return boost::system::errc::not_enough_memory; }
+ inline lazy<result<int>> lazy_error() { co_return boost::system::errc::not_enough_memory; }
+ inline eager<result<void>> eager_void() { co_return boost::system::errc::not_enough_memory; }
+ inline lazy<result<void>> lazy_void() { co_return boost::system::errc::not_enough_memory; }
+
+ template <class U, class... Args> inline eager<result<std::string>> eager_coawait(U &&f, Args... args)
+ {
+ BOOST_OUTCOME_CO_TRY(co_await f(args...));
+ co_return "hi";
+ }
+ template <class U, class... Args> inline lazy<result<std::string>> lazy_coawait(U &&f, Args... args)
+ {
+ BOOST_OUTCOME_CO_TRY(co_await f(args...));
+ co_return "hi";
+ }
+
+#ifndef BOOST_NO_EXCEPTIONS
+ struct custom_exception_type
+ {
+ };
+ inline lazy<result<int, boost::exception_ptr>> result_exception(boost::exception_ptr e)
+ {
+ boost::rethrow_exception(e);
+ co_return 5;
+ }
+
+ inline lazy<BOOST_OUTCOME_V2_NAMESPACE::outcome<int>> outcome_exception(boost::exception_ptr e)
+ {
+ boost::rethrow_exception(e);
+ co_return 5;
+ }
+#endif
+
+ inline eager<int> eager_int2(int x) { co_return x + 1; }
+ inline lazy<int> lazy_int2(int x) { co_return x + 1; }
+ inline eager<void> eager_void2() { co_return; }
+ inline lazy<void> lazy_void2() { co_return; }
+} // namespace coroutines
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_result_coroutine, "Tests that results are eager and lazy awaitable")
+{
+ using namespace coroutines;
+ auto eager_await = [](auto t) { return t.await_resume(); };
+ auto lazy_await = [](auto t) {
+ t.await_suspend({});
+ return t.await_resume();
+ };
+
+ BOOST_CHECK(eager_await(eager_int(5)).value() == 6);
+ BOOST_CHECK(lazy_await(lazy_int(5)).value() == 6);
+ BOOST_CHECK(eager_await(eager_error()).error() == boost::system::errc::not_enough_memory);
+ BOOST_CHECK(lazy_await(lazy_error()).error() == boost::system::errc::not_enough_memory);
+ BOOST_CHECK(eager_await(eager_void()).error() == boost::system::errc::not_enough_memory);
+ BOOST_CHECK(lazy_await(lazy_void()).error() == boost::system::errc::not_enough_memory);
+
+ BOOST_CHECK(eager_await(eager_coawait(eager_int, 5)).value() == "hi");
+ BOOST_CHECK(lazy_await(lazy_coawait(lazy_int, 5)).value() == "hi");
+
+#ifndef BOOST_NO_EXCEPTIONS
+ auto e = boost::copy_exception(custom_exception_type());
+ BOOST_CHECK_THROW(lazy_await(result_exception(e)).value(), custom_exception_type);
+ BOOST_CHECK_THROW(lazy_await(outcome_exception(e)).value(), custom_exception_type);
+#endif
+
+ BOOST_CHECK(eager_await(eager_int2(5)) == 6);
+ BOOST_CHECK(lazy_await(lazy_int2(5)) == 6);
+ eager_await(eager_void2());
+ lazy_await(lazy_void2());
+}
+#else
+int main(void)
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/outcome/test/tests/default-construction.cpp b/src/boost/libs/outcome/test/tests/default-construction.cpp
new file mode 100644
index 000000000..25726abb4
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/default-construction.cpp
@@ -0,0 +1,57 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_default_construction, "Tests that outcome default constructs when it ought to")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt
+ {
+ int _v{78};
+ udt() = default;
+ constexpr explicit udt(int v) noexcept : _v(v) {}
+ udt(udt &&o) = delete;
+ udt(const udt &) = delete;
+ udt &operator=(udt &&o) = delete;
+ udt &operator=(const udt &) = delete;
+ ~udt() = default;
+ constexpr int operator*() const noexcept { return _v; }
+ };
+ // One path is via success_type<void>
+ outcome<udt> a(success());
+ BOOST_CHECK(*a.value() == 78);
+
+ // Other path is via explicit conversion from void
+ outcome<void> c = success();
+ outcome<udt> d(c);
+ BOOST_CHECK(*d.value() == 78);
+}
diff --git a/src/boost/libs/outcome/test/tests/experimental-core-outcome-status.cpp b/src/boost/libs/outcome/test/tests/experimental-core-outcome-status.cpp
new file mode 100644
index 000000000..b7aed1d8c
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/experimental-core-outcome-status.cpp
@@ -0,0 +1,225 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/experimental/status_outcome.hpp>
+
+#define BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND std
+template <class T, class S = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::system_code, class P = BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::exception_ptr> using outcome = BOOST_OUTCOME_V2_NAMESPACE::experimental::status_outcome<T, S, P>;
+using BOOST_OUTCOME_V2_NAMESPACE::in_place_type;
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#include <iostream>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4702) // unreachable code
+#endif
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_status_code_outcome, "Tests that the outcome with status_code works as intended")
+{
+ using namespace BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE;
+
+ { // errored int
+ outcome<int> m(generic_code{errc::bad_address});
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), status_error<void>);
+ BOOST_CHECK_NO_THROW(m.error());
+ BOOST_CHECK_THROW(BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::rethrow_exception(m.failure()), generic_error);
+ }
+ { // errored void
+ outcome<void> m(generic_code{errc::bad_address});
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(([&m]() -> void { return m.value(); }()), generic_error);
+ BOOST_CHECK_NO_THROW(m.error());
+ BOOST_CHECK_THROW(BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::rethrow_exception(m.failure()), generic_error);
+ }
+ { // valued int
+ outcome<int> m(5);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == 5);
+ m.value() = 6;
+ BOOST_CHECK(m.value() == 6);
+ BOOST_CHECK(!m.failure());
+ }
+ { // moves do not clear state
+ outcome<std::string> m("niall");
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == "niall");
+ m.value() = "NIALL";
+ BOOST_CHECK(m.value() == "NIALL");
+ auto temp(std::move(m).value());
+ BOOST_CHECK(temp == "NIALL");
+ BOOST_CHECK(m.value().empty()); // NOLINT
+ }
+ { // valued void
+ outcome<void> m(in_place_type<void>);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_NO_THROW(m.value()); // works, but type returned is unusable
+ BOOST_CHECK(!m.failure());
+ }
+ { // errored
+ error ec(errc::no_link);
+ outcome<int> m(ec.clone());
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), generic_error);
+ BOOST_CHECK(m.error() == ec);
+#ifndef BOOST_NO_EXCEPTIONS
+ BOOST_CHECK(m.failure());
+ try
+ {
+ BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::rethrow_exception(m.failure());
+ }
+ catch(const generic_error &ex)
+ {
+ BOOST_CHECK(ex.code() == ec);
+ BOOST_CHECK(ex.code().value() == errc::no_link);
+ }
+#endif
+ }
+#if !defined(__APPLE__) || defined(__cpp_exceptions)
+ { // excepted
+ BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::error_code ec(5, BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::system_category());
+ auto e = BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::make_exception_ptr(BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::system_error(ec)); // NOLINT
+ outcome<int> m(e);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(m.has_exception());
+ BOOST_CHECK_THROW(m.value(), BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::system_error);
+ BOOST_CHECK(m.exception() == e);
+#ifndef BOOST_NO_EXCEPTIONS
+ BOOST_CHECK(m.failure());
+ try
+ {
+ BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::rethrow_exception(m.failure());
+ }
+ catch(const BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::system_error &ex)
+ {
+ BOOST_CHECK(ex.code() == ec);
+ BOOST_CHECK(ex.code().value() == 5);
+ }
+#endif
+ }
+ { // custom error type
+ struct Foo
+ {
+ };
+ auto e = BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::make_exception_ptr(Foo());
+ outcome<int> m(e);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(m.has_exception());
+ BOOST_CHECK_THROW(m.value(), Foo);
+ BOOST_CHECK(m.exception() == e);
+ }
+ { // outcome<void, void> should work
+ BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::error_code ec(5, BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::system_category());
+ auto e = BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::make_exception_ptr(BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::system_error(ec));
+ outcome<void, void> m(e);
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(!m.has_error());
+ BOOST_CHECK(m.has_exception());
+ }
+#endif
+
+
+ {
+ outcome<int> a(5);
+ outcome<int> b(generic_code{errc::invalid_argument});
+ std::cout << sizeof(a) << std::endl; // 40 bytes
+ a.assume_value();
+ b.assume_error();
+#ifndef BOOST_NO_EXCEPTIONS
+ try
+ {
+ b.value();
+ std::cerr << "fail" << std::endl;
+ std::terminate();
+ }
+ catch(const generic_error & /*unused*/)
+ {
+ }
+#endif
+ static_assert(!std::is_default_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_copy_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_nothrow_copy_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_copy_assignable<decltype(a)>::value, "");
+ static_assert(!std::is_trivially_copy_assignable<decltype(a)>::value, "");
+ static_assert(!std::is_nothrow_copy_assignable<decltype(a)>::value, "");
+ static_assert(!std::is_trivially_destructible<decltype(a)>::value, "");
+ static_assert(std::is_nothrow_destructible<decltype(a)>::value, "");
+
+ // Test void compiles
+ outcome<void> c(in_place_type<void>);
+ // Test int, void compiles
+ outcome<int, void> d(in_place_type<BOOST_OUTCOME_PREVENT_CONVERSION_WORKAROUND::exception_ptr>);
+ }
+
+ {
+ // Can only be constructed via multiple args
+ struct udt3
+ {
+ udt3() = delete;
+ udt3(udt3 &&) = delete;
+ udt3(const udt3 &) = delete;
+ udt3 &operator=(udt3 &&) = delete;
+ udt3 &operator=(const udt3 &) = delete;
+ explicit udt3(int /*unused*/, const char * /*unused*/, std::nullptr_t /*unused*/) {}
+ ~udt3() = default;
+ };
+ // Test a udt which can only be constructed in place compiles
+ outcome<udt3> g(in_place_type<udt3>, 5, static_cast<const char *>("niall"), nullptr);
+ // Does converting inplace construction also work?
+ outcome<udt3> h(5, static_cast<const char *>("niall"), nullptr);
+ BOOST_CHECK(h.has_value());
+ }
+}
diff --git a/src/boost/libs/outcome/test/tests/experimental-core-result-status.cpp b/src/boost/libs/outcome/test/tests/experimental-core-result-status.cpp
new file mode 100644
index 000000000..085c13dd2
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/experimental-core-result-status.cpp
@@ -0,0 +1,357 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (8 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/experimental/status_result.hpp>
+
+template <class T, class S = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::system_code, class NoValuePolicy = BOOST_OUTCOME_V2_NAMESPACE::experimental::policy::default_status_result_policy<T, S>> using result = BOOST_OUTCOME_V2_NAMESPACE::experimental::status_result<T, S, NoValuePolicy>;
+using BOOST_OUTCOME_V2_NAMESPACE::in_place_type;
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#include <exception>
+#include <iostream>
+
+#ifndef BOOST_NO_EXCEPTIONS
+// Custom error type with payload
+struct payload
+{
+ BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errc ec{BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errc::success};
+ const char *str{nullptr};
+ payload() = default;
+ payload(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errc _ec, const char *_str)
+ : ec(_ec)
+ , str(_str)
+ {
+ }
+};
+struct payload_exception : std::exception
+{
+ const char *_what{nullptr};
+ explicit payload_exception(const char *what)
+ : _what(what)
+ {
+ }
+ virtual const char *what() const noexcept override final { return _what; } // NOLINT
+};
+
+class _payload_domain;
+using status_code_payload = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<_payload_domain>;
+class _payload_domain : public BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code_domain
+{
+ template <class> friend class status_code;
+ using _base = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code_domain;
+
+public:
+ using value_type = payload;
+ using string_ref = _base::string_ref;
+
+public:
+ constexpr _payload_domain() noexcept : _base(0x7b782c8f935e34ba) {}
+
+ static inline constexpr const _payload_domain &get();
+
+ virtual _base::string_ref name() const noexcept override final { return string_ref("payload domain"); } // NOLINT
+protected:
+ virtual bool _do_failure(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override final // NOLINT
+ {
+ assert(code.domain() == *this); // NOLINT
+ return static_cast<const status_code_payload &>(code).value().ec != BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::errc::success; // NOLINT
+ }
+ virtual bool _do_equivalent(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code1, const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code2) const noexcept override final // NOLINT
+ {
+ assert(code1.domain() == *this); // NOLINT
+ const auto &c1 = static_cast<const status_code_payload &>(code1); // NOLINT
+ if(code2.domain() == *this)
+ {
+ const auto &c2 = static_cast<const status_code_payload &>(code2); // NOLINT
+ return c1.value().ec == c2.value().ec;
+ }
+ return false;
+ }
+ virtual BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::generic_code _generic_code(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override final // NOLINT
+ {
+ assert(code.domain() == *this); // NOLINT
+ return static_cast<const status_code_payload &>(code).value().ec; // NOLINT
+ }
+ virtual _base::string_ref _do_message(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override final // NOLINT
+ {
+ assert(code.domain() == *this); // NOLINT
+ const auto &c = static_cast<const status_code_payload &>(code); // NOLINT
+ return string_ref(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::detail::generic_code_message(c.value().ec));
+ }
+ virtual void _do_throw_exception(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const override final // NOLINT
+ {
+ assert(code.domain() == *this); // NOLINT
+ const auto &c = static_cast<const status_code_payload &>(code); // NOLINT
+ throw payload_exception(c.value().str);
+ }
+};
+constexpr _payload_domain payload_domain;
+inline constexpr const _payload_domain &_payload_domain::get()
+{
+ return payload_domain;
+}
+inline status_code_payload make_status_code(payload c) noexcept
+{
+ return status_code_payload(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::in_place, c);
+}
+#endif
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_status_code_result, "Tests that the result with status_code works as intended")
+{
+ using namespace BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE;
+
+ { // errored int
+ result<int> m(generic_code{errc::bad_address});
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), generic_error);
+ BOOST_CHECK_NO_THROW(m.error());
+ }
+ { // errored void
+ result<void> m(generic_code{errc::bad_address});
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(([&m]() -> void { return m.value(); }()), generic_error);
+ BOOST_CHECK_NO_THROW(m.error());
+ }
+ { // valued int
+ result<int> m(5);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == 5);
+ m.value() = 6;
+ BOOST_CHECK(m.value() == 6);
+ }
+ { // valued bool
+ result<bool> m(false);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == false);
+ m.value() = true;
+ BOOST_CHECK(m.value() == true);
+ }
+ { // moves do not clear state
+ result<std::string> m("niall");
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK(m.value() == "niall");
+ m.value() = "NIALL";
+ BOOST_CHECK(m.value() == "NIALL");
+ auto temp(std::move(m).value());
+ BOOST_CHECK(temp == "NIALL");
+ BOOST_CHECK(m.value().empty()); // NOLINT
+ }
+ { // valued void
+ result<void> m(in_place_type<void>);
+ BOOST_CHECK(m);
+ BOOST_CHECK(m.has_value());
+ BOOST_CHECK(!m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_NO_THROW(m.value()); // works, but type returned is unusable
+ }
+ { // errored
+ error ec(errc::no_link);
+ result<int> m(ec.clone());
+ BOOST_CHECK(!m);
+ BOOST_CHECK(!m.has_value());
+ BOOST_CHECK(m.has_error());
+ // BOOST_CHECK(!m.has_exception());
+ BOOST_CHECK_THROW(m.value(), generic_error);
+ BOOST_CHECK(m.error() == ec);
+ }
+ if(false) // NOLINT
+ { // void, void is permitted, but is not constructible
+ result<void, void> *m = nullptr;
+ m->value();
+ m->error();
+ }
+
+ {
+ // Deliberately define non-trivial operations
+ struct udt
+ {
+ int _v{0};
+ udt() = default;
+ udt(udt &&o) noexcept : _v(o._v) {}
+ udt(const udt &o) // NOLINT
+ : _v(o._v)
+ {
+ }
+ udt &operator=(udt &&o) noexcept
+ {
+ _v = o._v;
+ return *this;
+ }
+ udt &operator=(const udt &o) // NOLINT
+ {
+ _v = o._v;
+ return *this;
+ }
+ ~udt() { _v = 0; }
+ };
+ // No default construction, no copy nor move
+ struct udt2
+ {
+ udt2() = delete;
+ udt2(udt2 &&) = delete;
+ udt2(const udt2 &) = delete;
+ udt2 &operator=(udt2 &&) = delete;
+ udt2 &operator=(const udt2 &) = delete;
+ explicit udt2(int /*unused*/) {}
+ ~udt2() = default;
+ };
+ // Can only be constructed via multiple args
+ struct udt3
+ {
+ udt3() = delete;
+ udt3(udt3 &&) = delete;
+ udt3(const udt3 &) = delete;
+ udt3 &operator=(udt3 &&) = delete;
+ udt3 &operator=(const udt3 &) = delete;
+ explicit udt3(int /*unused*/, const char * /*unused*/, std::nullptr_t /*unused*/) {}
+ ~udt3() = default;
+ };
+
+ result<int> a(5);
+ result<int> b(generic_code{errc::invalid_argument});
+ std::cout << sizeof(a) << std::endl; // 32 bytes
+ if(false) // NOLINT
+ {
+ b.assume_value();
+ a.assume_error();
+ }
+#ifndef BOOST_NO_EXCEPTIONS
+ try
+ {
+ b.value();
+ std::cerr << "fail" << std::endl;
+ std::terminate();
+ }
+ catch(const generic_error &e)
+ {
+ BOOST_CHECK(!strcmp(e.what(), b.error().message().c_str()));
+ }
+#endif
+ static_assert(!std::is_default_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_copy_constructible<decltype(a)>::value, "");
+// Quality of implementation of std::optional is poor :(
+#ifndef TESTING_WG21_EXPERIMENTAL_RESULT
+ static_assert(!std::is_trivially_copy_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_nothrow_copy_constructible<decltype(a)>::value, "");
+ static_assert(!std::is_copy_assignable<decltype(a)>::value, "");
+ static_assert(!std::is_trivially_copy_assignable<decltype(a)>::value, "");
+ static_assert(!std::is_nothrow_copy_assignable<decltype(a)>::value, "");
+#endif
+ static_assert(!std::is_trivially_destructible<decltype(a)>::value, "");
+ static_assert(std::is_nothrow_destructible<decltype(a)>::value, "");
+
+ // Test void compiles
+ result<void> c(in_place_type<void>);
+
+ // Test a standard udt compiles
+ result<udt> d(in_place_type<udt>);
+ static_assert(!std::is_default_constructible<decltype(d)>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<decltype(d)>::value, "");
+ static_assert(!std::is_copy_constructible<decltype(d)>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<decltype(d)>::value, "");
+ static_assert(!std::is_nothrow_copy_constructible<decltype(d)>::value, "");
+ static_assert(!std::is_copy_assignable<decltype(d)>::value, "");
+ static_assert(!std::is_trivially_copy_assignable<decltype(d)>::value, "");
+ static_assert(!std::is_nothrow_copy_assignable<decltype(d)>::value, "");
+ static_assert(std::is_move_assignable<decltype(d)>::value, "");
+ static_assert(!std::is_trivially_move_assignable<decltype(d)>::value, "");
+ static_assert(std::is_nothrow_move_assignable<decltype(d)>::value, "");
+ static_assert(!std::is_trivially_destructible<decltype(d)>::value, "");
+ static_assert(std::is_nothrow_destructible<decltype(d)>::value, "");
+
+ // Test a highly pathological udt compiles
+ result<udt2> e(in_place_type<udt2>, 5);
+ // result<udt2> e2(e);
+ static_assert(!std::is_default_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_nothrow_default_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_copy_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_trivially_copy_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_nothrow_copy_constructible<decltype(e)>::value, "");
+ static_assert(!std::is_copy_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_trivially_copy_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_nothrow_copy_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_move_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_trivially_move_assignable<decltype(e)>::value, "");
+ static_assert(!std::is_nothrow_move_assignable<decltype(e)>::value, "");
+
+ // Test a udt which can only be constructed in place compiles
+ result<udt3> g(in_place_type<udt3>, 5, static_cast<const char *>("niall"), nullptr);
+ // Does converting inplace construction also work?
+ result<udt3> h(5, static_cast<const char *>("niall"), nullptr);
+ result<udt3> i(generic_code{errc::not_enough_memory});
+ BOOST_CHECK(h.has_value());
+ BOOST_CHECK(i.has_error());
+ }
+
+ // Test direct use of error code enum works
+ {
+ constexpr result<int, errc, BOOST_OUTCOME_V2_NAMESPACE::policy::all_narrow> a(5), b(errc::invalid_argument);
+ static_assert(a.value() == 5, "a is not 5");
+ static_assert(b.error() == errc::invalid_argument, "b is not errored");
+ }
+
+#ifndef BOOST_NO_EXCEPTIONS
+ // Test payload facility
+ {
+ const char *niall = "niall";
+ result<int, status_code_payload> b{payload{errc::invalid_argument, niall}};
+ try
+ {
+ b.value();
+ BOOST_CHECK(false);
+ }
+ catch(const payload_exception &e)
+ {
+ BOOST_CHECK(!strcmp(e.what(), niall));
+ }
+ catch(...)
+ {
+ BOOST_CHECK(false);
+ }
+ }
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/experimental-p0709a.cpp b/src/boost/libs/outcome/test/tests/experimental-p0709a.cpp
new file mode 100644
index 000000000..8823568ae
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/experimental-p0709a.cpp
@@ -0,0 +1,169 @@
+/* Unit testing for outcomes
+(C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/experimental/status_result.hpp>
+
+#include <climits> // for INT_MAX
+#include <cstdio>
+
+// status_code<erased<intptr_t>>
+using error = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::error;
+// Outcome's result must be told when it is dealing with an erased status code
+template <class T, class E> using result = BOOST_OUTCOME_V2_NAMESPACE::experimental::status_result<T, E, BOOST_OUTCOME_V2_NAMESPACE::policy::all_narrow>;
+
+enum class arithmetic_errc
+{
+ success,
+ divide_by_zero,
+ integer_divide_overflows,
+ not_integer_division
+};
+
+class _arithmetic_errc_domain;
+using arithmetic_errc_error = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<_arithmetic_errc_domain>;
+
+class _arithmetic_errc_domain : public BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code_domain
+{
+ using _base = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code_domain;
+
+public:
+ using value_type = arithmetic_errc;
+
+ constexpr explicit _arithmetic_errc_domain(typename _base::unique_id_type id = 0x290f170194f0c6c7) noexcept : _base(id) {}
+ static inline constexpr const _arithmetic_errc_domain &get();
+
+ virtual _base::string_ref name() const noexcept override final // NOLINT
+ {
+ static string_ref v("arithmetic error domain");
+ return v; // NOLINT
+ }
+
+protected:
+ virtual bool _do_failure(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override final // NOLINT
+ {
+ assert(code.domain() == *this); // NOLINT
+ const auto &c1 = static_cast<const arithmetic_errc_error &>(code); // NOLINT
+ return c1.value() != arithmetic_errc::success;
+ }
+ virtual bool _do_equivalent(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &, const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &) const noexcept override final { return false; } // NOLINT
+ virtual BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::generic_code _generic_code(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &) const noexcept override final { return {}; } // NOLINT
+ virtual _base::string_ref _do_message(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override final // NOLINT
+ {
+ assert(code.domain() == *this); // NOLINT
+ const auto &c1 = static_cast<const arithmetic_errc_error &>(code); // NOLINT
+ switch(c1.value())
+ {
+ case arithmetic_errc::success:
+ return _base::string_ref("success");
+ case arithmetic_errc::divide_by_zero:
+ return _base::string_ref("divide by zero");
+ case arithmetic_errc::integer_divide_overflows:
+ return _base::string_ref("integer divide overflows");
+ case arithmetic_errc::not_integer_division:
+ return _base::string_ref("not integer division");
+ }
+ return _base::string_ref("unknown");
+ }
+ BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &) const override final { abort(); } // NOLINT
+};
+
+constexpr _arithmetic_errc_domain arithmetic_errc_domain;
+inline constexpr const _arithmetic_errc_domain &_arithmetic_errc_domain::get()
+{
+ return arithmetic_errc_domain;
+}
+
+
+// Tell status code about the available implicit conversion
+inline arithmetic_errc_error make_status_code(arithmetic_errc e)
+{
+ return arithmetic_errc_error(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::in_place, e);
+}
+
+BOOST_OUTCOME_V2_NAMESPACE_BEGIN
+namespace trait
+{
+ // Tell Outcome that arithmetic_errc is convertible into std::error
+ template <> struct is_error_type_enum<error, arithmetic_errc>
+ {
+ static constexpr bool value = true;
+ };
+}
+BOOST_OUTCOME_V2_NAMESPACE_END
+// And tell Outcome how to perform the implicit conversion
+inline error make_error_code(arithmetic_errc e)
+{
+ return arithmetic_errc_error(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::in_place, e);
+}
+
+
+result<int, error> safe_divide(int i, int j)
+{
+ if(j == 0)
+ {
+ return arithmetic_errc::divide_by_zero;
+ }
+ if(i == INT_MIN && j == -1)
+ {
+ return arithmetic_errc::integer_divide_overflows;
+ }
+ if(i % j != 0)
+ {
+ return arithmetic_errc::not_integer_division;
+ }
+ return i / j;
+}
+
+int caller2(int i, int j)
+{
+ auto r = safe_divide(i, j);
+ if(r)
+ {
+ return r.value();
+ }
+ if(r.error() == arithmetic_errc::divide_by_zero)
+ {
+ return 0;
+ }
+ if(r.error() == arithmetic_errc::not_integer_division)
+ {
+ return i / j; // ignore
+ }
+ if(r.error() == arithmetic_errc::integer_divide_overflows)
+ {
+ return INT_MIN;
+ }
+ return 0;
+}
+
+int main()
+{
+ printf("%d\n", caller2(5, 6)); // NOLINT
+ return 0;
+}
diff --git a/src/boost/libs/outcome/test/tests/fileopen.cpp b/src/boost/libs/outcome/test/tests/fileopen.cpp
new file mode 100644
index 000000000..f2634d4fd
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/fileopen.cpp
@@ -0,0 +1,87 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <boost/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#ifndef BOOST_NO_EXCEPTIONS
+
+#ifdef _MSC_VER
+#define BOOST_OUTCOME_POSIX_OPEN ::_open
+#include <io.h>
+#else
+#define BOOST_OUTCOME_POSIX_OPEN ::open
+#include <fcntl.h>
+#endif
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_fileopen, "Tests that the outcome semantically represents opening a file")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+
+ //! [file_open_example]
+ auto openfile = [](std::string path) noexcept->outcome<int>
+ {
+ int fd;
+ do
+ {
+ fd = BOOST_OUTCOME_POSIX_OPEN(path.c_str(), 0); // NOLINT
+ } while(-1 == fd && EINTR == errno);
+ try
+ {
+ if(-1 == fd)
+ {
+ int code = errno;
+ // If a temporary failure, this is an expected unexpected outcome
+ if(EBUSY == code || EISDIR == code || ELOOP == code || ENOENT == code || ENOTDIR == code || EPERM == code || EACCES == code)
+ {
+ return boost::system::error_code(code, boost::system::generic_category());
+ }
+ // If a non-temporary failure, this is an unexpected outcome
+ return boost::copy_exception(boost::system::system_error(code, boost::system::generic_category(), strerror(code)));
+ }
+ return fd;
+ }
+ catch(...)
+ {
+ // Any exception thrown is truly unexpected
+ return boost::current_exception();
+ }
+ };
+ auto a = openfile("shouldneverexistnotever");
+ BOOST_CHECK(!a);
+ BOOST_CHECK(!a.has_value());
+ BOOST_CHECK(!a.has_exception());
+ BOOST_CHECK(a.has_error());
+ BOOST_CHECK(a.error() == boost::system::error_code(ENOENT, boost::system::generic_category()));
+ //! [file_open_example]
+}
+#endif
diff --git a/src/boost/libs/outcome/test/tests/hooks.cpp b/src/boost/libs/outcome/test/tests/hooks.cpp
new file mode 100644
index 000000000..857113cde
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/hooks.cpp
@@ -0,0 +1,114 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (14 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#include <iostream>
+
+namespace hook_test
+{
+ using BOOST_OUTCOME_V2_NAMESPACE::in_place_type;
+ // Use static storage to convey extended error info from result construction to outcome conversion
+ static char extended_error_info[256];
+
+ // Use the error_code type as the ADL bridge for the hooks by creating a type here
+ struct error_code : public boost::system::error_code
+ {
+ using boost::system::error_code::error_code;
+ error_code() = default;
+ error_code(boost::system::error_code ec) // NOLINT
+ : boost::system::error_code(ec)
+ {
+ }
+ };
+ // Localise result to using the local error_code so this namespace gets looked up for the hooks
+ template <class R> using result = BOOST_OUTCOME_V2_NAMESPACE::result<R, error_code>;
+ // Specialise the result construction hook for our localised result
+ template <class U> constexpr inline void hook_result_construction(result<int> *res, U && /*unused*/) noexcept
+ {
+ // Write the value in the result into the static storage
+ snprintf(extended_error_info, sizeof(extended_error_info), "%d", res->assume_value()); // NOLINT
+ }
+ template <class U> constexpr inline void hook_result_construction(result<std::string> *res, U && /*unused*/) noexcept
+ {
+ // Write the value in the result into the static storage
+ snprintf(extended_error_info, sizeof(extended_error_info), "%s", res->assume_value().c_str()); // NOLINT
+ }
+} // namespace hook_test
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_result_hooks, "Tests that you can hook result's construction")
+{
+ using namespace hook_test;
+ result<int> a(5);
+ BOOST_CHECK(!strcmp(extended_error_info, "5")); // NOLINT
+ result<std::string> b("niall");
+ BOOST_CHECK(!strcmp(extended_error_info, "niall")); // NOLINT
+}
+
+//! [extended_error_coding2]
+namespace hook_test
+{
+ // Localise outcome to using the local error_code so this namespace gets looked up for the hooks
+ template <class R> using outcome = BOOST_OUTCOME_V2_NAMESPACE::outcome<R, error_code, std::string>;
+
+ // Specialise the outcome copy and move conversion hook for our localised result
+ template <class T, class U> constexpr inline void hook_outcome_copy_construction(outcome<T> *res, const result<U> & /*unused*/) noexcept
+ {
+ // when copy constructing from a result<T>, place extended_error_coding::extended_error_info into the payload
+ std::cout << "hook_outcome_copy_construction fires" << std::endl;
+ BOOST_OUTCOME_V2_NAMESPACE::hooks::override_outcome_exception(res, extended_error_info);
+ }
+ template <class T, class U> constexpr inline void hook_outcome_move_construction(outcome<T> *res, result<U> && /*unused*/) noexcept
+ {
+ // when move constructing from a result<T>, place extended_error_coding::extended_error_info into the payload
+ std::cout << "hook_outcome_move_construction fires" << std::endl;
+ BOOST_OUTCOME_V2_NAMESPACE::hooks::override_outcome_exception(res, extended_error_info);
+ }
+} // namespace hook_test
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_hooks, "Tests that you can hook outcome's conversion from a result")
+{
+ using namespace hook_test;
+ outcome<int> a(result<int>(5));
+ BOOST_REQUIRE(a.has_exception()); // NOLINT
+ BOOST_CHECK(a.exception() == "5");
+ outcome<std::string> b(result<std::string>("niall"));
+ BOOST_CHECK(b.exception() == "niall");
+
+ // Make sure hook does not fire for any other kind of outcome copy or move, only when converting from our custom result only
+ outcome<int> c(5);
+ outcome<long> d(c); // can't be the same type as source, else copy elision takes place and no ADL hook calling
+ BOOST_CHECK(!d.has_exception());
+ outcome<int> e(BOOST_OUTCOME_V2_NAMESPACE::result<int>(5));
+ BOOST_CHECK(!e.has_exception());
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0007.cpp b/src/boost/libs/outcome/test/tests/issue0007.cpp
new file mode 100644
index 000000000..d890c333e
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0007.cpp
@@ -0,0 +1,81 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0007_test, "BOOST_OUTCOME_TRYV(expr) in a function whose return outcome's type has no default constructor fails to compile")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt // NOLINT
+ {
+ explicit udt(int /*unused*/) {}
+ // udt() = delete;
+ udt(const udt &) = default;
+ udt(udt &&) = default;
+ };
+ {
+ auto f = []() -> result<udt> {
+ auto g = [] { return result<int>(5); };
+ /* This fails because BOOST_OUTCOME_TRYV() returns a result<void>
+ which if it were valued void, would implicitly convert into a
+ default constructed udt which is not possible, hence the compile error.
+ */
+ BOOST_OUTCOME_TRYV(g());
+ return udt(5);
+ };
+ (void) f();
+ }
+ {
+ auto f = []() -> outcome<udt> {
+ auto g = [] { return outcome<int>(5); };
+ /* This fails because BOOST_OUTCOME_TRYV() returns a result<void>
+ which if it were valued void, would implicitly convert into a
+ default constructed udt which is not possible, hence the compile error.
+ */
+ BOOST_OUTCOME_TRYV(g());
+ return udt(5);
+ };
+ (void) f();
+ }
+ {
+ auto f = []() -> outcome<udt> {
+ auto g = [] { return result<int>(5); };
+ /* This fails because BOOST_OUTCOME_TRYV() returns a result<void>
+ which if it were valued void, would implicitly convert into a
+ default constructed udt which is not possible, hence the compile error.
+ */
+ BOOST_OUTCOME_TRYV(g());
+ return udt(5);
+ };
+ (void) f();
+ }
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0009.cpp b/src/boost/libs/outcome/test/tests/issue0009.cpp
new file mode 100644
index 000000000..7a61cfc92
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0009.cpp
@@ -0,0 +1,52 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0009_test, "Alternative TRY macros?")
+{
+#ifdef BOOST_OUTCOME_TRYX
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt // NOLINT
+ {
+ explicit udt(int /*unused*/) {}
+ // udt() = delete;
+ udt(const udt &) = default;
+ udt(udt &&) = default;
+ };
+ auto f = []() -> result<udt> {
+ auto g = [] { return result<int>(5); };
+ return udt(BOOST_OUTCOME_TRYX(g()));
+ };
+ (void) f();
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0010.cpp b/src/boost/libs/outcome/test/tests/issue0010.cpp
new file mode 100644
index 000000000..84a897773
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0010.cpp
@@ -0,0 +1,88 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (9 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0010_test, "Expected's operator->(), operator*() and .error() throw exceptions when they should not")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ const char *a = "hi", *b = "bye";
+ struct udt1 // NOLINT
+ {
+ const char *_v{nullptr};
+ udt1() = default;
+ constexpr explicit udt1(const char *v) noexcept : _v(v) {}
+ constexpr udt1(udt1 &&o) noexcept : _v(o._v) { o._v = nullptr; }
+ udt1(const udt1 &) = default;
+ constexpr udt1 &operator=(udt1 &&o) noexcept
+ {
+ _v = o._v;
+ o._v = nullptr;
+ return *this;
+ }
+ udt1 &operator=(const udt1 &) = delete;
+ constexpr const char *operator*() const noexcept { return _v; }
+ };
+ struct udt2 // NOLINT
+ {
+ const char *_v{nullptr};
+ udt2() = default;
+ constexpr explicit udt2(const char *v) noexcept : _v(v) {}
+ constexpr udt2(udt2 &&o) noexcept : _v(o._v) { o._v = nullptr; }
+ udt2(const udt2 &) = default;
+ constexpr udt2 &operator=(udt2 &&o) noexcept
+ {
+ _v = o._v;
+ o._v = nullptr;
+ return *this;
+ }
+ udt1 &operator=(const udt1 &) = delete;
+ constexpr const char *operator*() const noexcept { return _v; }
+ };
+ result<udt1, udt2> p(udt1{a});
+ result<udt1, udt2> n(udt2{b});
+ // State check
+ BOOST_CHECK(p.has_value());
+ BOOST_CHECK(!n.has_value());
+ // These should behave as expected (!)
+ // BOOST_CHECK_NO_THROW(p.value());
+ // BOOST_CHECK_NO_THROW(n.value());
+ // And state is not destroyed
+ BOOST_CHECK(p.has_value() && *p.assume_value() == a);
+ BOOST_CHECK(!n.has_value() && *n.assume_error() == b);
+ // LEWG Expected provides rvalue ref semantics for operator*(), error() and error_or()
+ udt1 a1(std::move(p.assume_value()));
+ BOOST_CHECK(*a1 == a);
+ BOOST_CHECK(*p.assume_value() == nullptr);
+ udt2 e2(std::move(n).assume_error());
+ BOOST_CHECK(*e2 == b);
+ BOOST_CHECK(*n.assume_error() == nullptr); // NOLINT
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0012.cpp b/src/boost/libs/outcome/test/tests/issue0012.cpp
new file mode 100644
index 000000000..ff5d3c83e
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0012.cpp
@@ -0,0 +1,59 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0012_test, "outcome's copy assignment gets instantiated even when type T cannot be copied")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ const char *s = "hi";
+ struct udt // NOLINT
+ {
+ const char *_v{nullptr};
+ udt() = default;
+ constexpr explicit udt(const char *v) noexcept : _v(v) {}
+ constexpr udt(udt &&o) noexcept : _v(o._v) { o._v = nullptr; }
+ udt(const udt &) = delete;
+ constexpr udt &operator=(udt &&o) noexcept
+ {
+ _v = o._v;
+ o._v = nullptr;
+ return *this;
+ }
+ udt &operator=(const udt &) = delete;
+ constexpr const char *operator*() const noexcept { return _v; }
+ };
+ static_assert(std::is_move_constructible<outcome<udt>>::value, "expected<udt> is not move constructible!");
+ static_assert(!std::is_copy_constructible<outcome<udt>>::value, "expected<udt> is copy constructible!");
+ outcome<udt> p(udt{s}), n(boost::system::error_code(ENOMEM, boost::system::generic_category()));
+ n = boost::system::error_code(EINVAL, boost::system::generic_category());
+ BOOST_CHECK(n.error().value() == EINVAL);
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0016.cpp b/src/boost/libs/outcome/test/tests/issue0016.cpp
new file mode 100644
index 000000000..ddf5dd158
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0016.cpp
@@ -0,0 +1,56 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0016_test, "Default constructor of T is sometimes compiled when T has no default constructor")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt
+ {
+ const char *_v{nullptr};
+ udt() = delete;
+ constexpr explicit udt(const char *v) noexcept : _v(v) {}
+ constexpr udt(udt &&o) noexcept : _v(o._v) { o._v = nullptr; }
+ udt(const udt &) = delete;
+ constexpr udt &operator=(udt &&o) noexcept
+ {
+ _v = o._v;
+ o._v = nullptr;
+ return *this;
+ }
+ udt &operator=(const udt &) = delete;
+ ~udt() = default;
+ constexpr const char *operator*() const noexcept { return _v; }
+ };
+ result<udt> n(boost::system::error_code(ENOMEM, boost::system::generic_category()));
+ (void) n;
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0059.cpp b/src/boost/libs/outcome/test/tests/issue0059.cpp
new file mode 100644
index 000000000..867ec6670
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0059.cpp
@@ -0,0 +1,60 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (8 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/result.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0059_test, "result<NonMovable> supported?")
+{
+#if defined(_MSC_VER) || __cplusplus >= 201700
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt
+ {
+ const char *_v{nullptr};
+ udt() = delete;
+ constexpr udt(const char *v) noexcept : _v(v) {} // NOLINT
+ udt(udt &&o) = delete;
+ udt(const udt &) = delete;
+ udt &operator=(udt &&o) = delete;
+ udt &operator=(const udt &) = delete;
+ ~udt() = default;
+ constexpr const char *operator*() const noexcept { return _v; }
+ };
+ const char *niall = "niall";
+ auto f = [niall]() -> result<void> {
+ auto g = [niall]() -> result<udt> { return {niall}; };
+ BOOST_OUTCOME_TRY(v, g()); // this must never copy nor move
+ BOOST_CHECK(*v == niall);
+ return success();
+ };
+ (void) f();
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0061.cpp b/src/boost/libs/outcome/test/tests/issue0061.cpp
new file mode 100644
index 000000000..aab9a3bff
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0061.cpp
@@ -0,0 +1,128 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0061_result, "result<T1, E1> does not compare to incompatible result<T2, E2>")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt1
+ {
+ const char *_v{nullptr};
+ udt1() = default;
+ constexpr udt1(const char *v) noexcept : _v(v) {} // NOLINT
+ udt1(udt1 &&o) = delete;
+ udt1(const udt1 &) = delete;
+ udt1 &operator=(udt1 &&o) = delete;
+ udt1 &operator=(const udt1 &) = delete;
+ ~udt1() = default;
+ constexpr const char *operator*() const noexcept { return _v; }
+ };
+ struct udt2
+ {
+ const char *_v{nullptr};
+ udt2() = default;
+ constexpr explicit udt2(const char *v) noexcept : _v(v) {}
+ udt2(udt2 &&o) = delete;
+ udt2(const udt2 &) = delete;
+ udt2 &operator=(udt2 &&o) = delete;
+ udt2 &operator=(const udt2 &) = delete;
+ ~udt2() = default;
+ constexpr const char *operator*() const noexcept { return _v; }
+ bool operator==(const udt1 &o) const noexcept { return _v == *o; }
+ bool operator!=(const udt1 &o) const noexcept { return _v != *o; }
+ };
+ using result1 = result<int, udt1>;
+ using result2 = result<int, udt2>;
+
+ result1 a(5);
+ result2 b(5);
+ BOOST_CHECK(b == a); // udt2 will compare to udt1
+ BOOST_CHECK(!(b != a)); // udt2 will compare to udt1
+
+ result<void> c = success();
+ result<void> d = success();
+ BOOST_CHECK(c == d);
+ BOOST_CHECK(!(c != d));
+
+ BOOST_CHECK(a == success());
+ BOOST_CHECK(success() == a);
+ BOOST_CHECK(b != failure("foo"));
+ BOOST_CHECK(failure("foo") != b);
+}
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0061_outcome, "outcome<T1, E1, P1> does not compare to incompatible outcome<T2, E2, P2>")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt1
+ {
+ const char *_v{nullptr};
+ udt1() = default;
+ constexpr udt1(const char *v) noexcept : _v(v) {} // NOLINT
+ udt1(udt1 &&o) = delete;
+ udt1(const udt1 &) = delete;
+ udt1 &operator=(udt1 &&o) = delete;
+ udt1 &operator=(const udt1 &) = delete;
+ ~udt1() = default;
+ constexpr const char *operator*() const noexcept { return _v; }
+ };
+ struct udt2
+ {
+ const char *_v{nullptr};
+ udt2() = default;
+ constexpr explicit udt2(const char *v) noexcept : _v(v) {}
+ udt2(udt2 &&o) = delete;
+ udt2(const udt2 &) = delete;
+ udt2 &operator=(udt2 &&o) = delete;
+ udt2 &operator=(const udt2 &) = delete;
+ ~udt2() = default;
+ constexpr const char *operator*() const noexcept { return _v; }
+ bool operator==(const udt1 &o) const noexcept { return _v == *o; }
+ bool operator!=(const udt1 &o) const noexcept { return _v != *o; }
+ };
+ using outcome1 = outcome<int, udt1>;
+ using outcome2 = outcome<int, udt2>;
+
+ outcome1 a(5), _a(6);
+ outcome2 b(5);
+ BOOST_CHECK(b == a); // udt2 will compare to udt1
+ BOOST_CHECK(!(b != a)); // udt2 will compare to udt1
+
+ outcome<void> c = success();
+ outcome<void> d = success();
+ BOOST_CHECK(c == d);
+ BOOST_CHECK(!(c != d));
+
+ BOOST_CHECK(a == success());
+ BOOST_CHECK(success() == a);
+ BOOST_CHECK(b != failure("foo"));
+ BOOST_CHECK(failure("foo") != b);
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0064.cpp b/src/boost/libs/outcome/test/tests/issue0064.cpp
new file mode 100644
index 000000000..6dbdcd91c
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0064.cpp
@@ -0,0 +1,50 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/iostream_support.hpp>
+#include <boost/outcome/outcome.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0064_outcome, "BOOST_OUTCOME_TRY on excepted outcome is propagating a null error rather than just an exception")
+{
+#ifndef BOOST_NO_EXCEPTIONS
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ auto f = []() -> outcome<int> {
+ auto h = []() -> outcome<int> { return boost::copy_exception(std::runtime_error("hello")); };
+ BOOST_OUTCOME_TRY((h()));
+ return 0;
+ }();
+ std::cout << print(f) << std::endl;
+ BOOST_CHECK(!f.has_value());
+ BOOST_CHECK(!f.has_error());
+ BOOST_CHECK(f.has_exception());
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0065.cpp b/src/boost/libs/outcome/test/tests/issue0065.cpp
new file mode 100644
index 000000000..c537a38a7
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0065.cpp
@@ -0,0 +1,66 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (3 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0065_outcome, "BOOST_OUTCOME_TRY does not preserve the exception_ptr")
+{
+#ifndef BOOST_NO_EXCEPTIONS
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ auto g = []() -> outcome<int> {
+ auto f = []() -> outcome<int> {
+ try
+ {
+ throw std::runtime_error{"XXX"};
+ }
+ catch(...)
+ {
+ return boost::current_exception();
+ }
+ };
+ BOOST_OUTCOME_TRY(ans, (f()));
+ return ans;
+ };
+ outcome<int> o = g();
+ BOOST_CHECK(!o);
+ BOOST_CHECK(o.has_exception());
+ try
+ {
+ o.value();
+ BOOST_CHECK(false);
+ }
+ catch(const std::runtime_error &e)
+ {
+ BOOST_CHECK(!strcmp(e.what(), "XXX"));
+ }
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0071.cpp b/src/boost/libs/outcome/test/tests/issue0071.cpp
new file mode 100644
index 000000000..333fb2088
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0071.cpp
@@ -0,0 +1,45 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (4 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/result.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0071_outcome, "Implicit construction is over eager")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt
+ {
+ int v;
+ explicit udt(int a)
+ : v(a){};
+ };
+ result<udt> m = udt{5};
+ BOOST_CHECK(m.value().v == 5);
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0095.cpp b/src/boost/libs/outcome/test/tests/issue0095.cpp
new file mode 100644
index 000000000..c1ed1d460
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0095.cpp
@@ -0,0 +1,58 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/result.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+namespace issue0095
+{
+ namespace out = BOOST_OUTCOME_V2_NAMESPACE;
+
+ struct E
+ {
+ };
+ // struct F : E {};
+ struct F
+ {
+ operator E() const { return E{}; } // NOLINT
+ };
+
+ out::result<int, F> f() { return F{}; }
+ out::result<int, E> e()
+ {
+ BOOST_OUTCOME_TRY(i, (f()));
+ return i;
+ }
+} // namespace issue0095
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0095_outcome, "operator conversions on E type cause TRY to fail")
+{
+ BOOST_CHECK(issue0095::e().has_error());
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0115.cpp b/src/boost/libs/outcome/test/tests/issue0115.cpp
new file mode 100644
index 000000000..17d852274
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0115.cpp
@@ -0,0 +1,57 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (1 commit)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0115_outcome, "Initialization from `failure_type` drops default-constructed values")
+{
+ namespace out = BOOST_OUTCOME_V2_NAMESPACE;
+
+ out::outcome<int> o1 = boost::system::error_code{};
+ BOOST_CHECK(o1.has_error());
+ BOOST_CHECK(!o1.has_exception());
+
+ out::outcome<int> o2 = out::failure(boost::system::error_code{});
+ BOOST_CHECK(o2.has_error());
+ BOOST_CHECK(!o2.has_exception());
+
+ out::outcome<int> o3(boost::system::error_code{}, boost::exception_ptr{});
+ BOOST_CHECK(o3.has_error());
+ BOOST_CHECK(o3.has_exception());
+
+ out::outcome<int> o4 = out::failure(boost::system::error_code{}, boost::exception_ptr{});
+ BOOST_CHECK(o4.has_error());
+ BOOST_CHECK(o4.has_exception());
+
+ out::outcome<int> o5 = out::failure(boost::exception_ptr{});
+ BOOST_CHECK(!o5.has_error());
+ BOOST_CHECK(o5.has_exception());
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0116.cpp b/src/boost/libs/outcome/test/tests/issue0116.cpp
new file mode 100644
index 000000000..168c3e5c4
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0116.cpp
@@ -0,0 +1,45 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (2 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0116_outcome, "Bad implementation of outcome::operator==")
+{
+ namespace out = BOOST_OUTCOME_V2_NAMESPACE;
+
+ out::outcome<int> o1 = 1;
+ BOOST_CHECK(!o1.has_error());
+
+ out::outcome<int> o2 = out::failure(boost::system::error_code{EINVAL, boost::system::generic_category()});
+ BOOST_CHECK(o2.has_error());
+
+ BOOST_CHECK(o1 != o2);
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0140.cpp b/src/boost/libs/outcome/test/tests/issue0140.cpp
new file mode 100644
index 000000000..bb86f0619
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0140.cpp
@@ -0,0 +1,96 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (2 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0140_result, "Construction of non copy constructible value_type fails to not compile")
+{
+ namespace out = BOOST_OUTCOME_V2_NAMESPACE;
+
+ enum op
+ {
+ constructed,
+ moved,
+ copied
+ };
+ struct NotCopyMoveConstructible
+ {
+ op v{op::constructed};
+ NotCopyMoveConstructible() = default;
+ NotCopyMoveConstructible(const NotCopyMoveConstructible &o) = delete;
+ NotCopyMoveConstructible(NotCopyMoveConstructible &&) = delete;
+ NotCopyMoveConstructible &operator=(const NotCopyMoveConstructible &) = delete;
+ NotCopyMoveConstructible &operator=(NotCopyMoveConstructible &&) = delete;
+ ~NotCopyMoveConstructible() = default;
+ };
+ struct NotMoveConstructible
+ {
+ op v{op::constructed};
+ NotMoveConstructible() = default;
+ NotMoveConstructible(const NotMoveConstructible & /*unused*/)
+ : v(op::copied)
+ {
+ }
+ NotMoveConstructible(NotMoveConstructible &&) = delete;
+ NotMoveConstructible &operator=(const NotMoveConstructible &) = delete;
+ NotMoveConstructible &operator=(NotMoveConstructible &&) = delete;
+ ~NotMoveConstructible() = default;
+ };
+ struct NotCopyConstructible
+ {
+ op v{op::constructed};
+ NotCopyConstructible() = default;
+ NotCopyConstructible(NotCopyConstructible && /*unused*/) noexcept : v(op::moved) {}
+ NotCopyConstructible(const NotCopyConstructible & /*unused*/) = delete;
+ NotCopyConstructible &operator=(const NotCopyConstructible &) = delete;
+ NotCopyConstructible &operator=(NotCopyConstructible &&) = delete;
+ ~NotCopyConstructible() = default;
+ };
+
+ // Uncopyable and immovable items should be neither copyable nor moveable
+ static_assert(!std::is_copy_constructible<out::result<NotCopyMoveConstructible>>::value, "result<NotCopyMoveConstructible> is copy constructible!");
+ static_assert(!std::is_move_constructible<out::result<NotCopyMoveConstructible>>::value, "result<NotCopyMoveConstructible> is move constructible!");
+ static_assert(!std::is_convertible<const NotCopyMoveConstructible &, NotCopyMoveConstructible>::value, "");
+ static_assert(!std::is_convertible<NotCopyMoveConstructible &&, NotCopyMoveConstructible>::value, "");
+ static_assert(!std::is_constructible<out::result<NotCopyMoveConstructible>, const NotCopyMoveConstructible &>::value, "result<NotCopyMoveConstructible> is constructible from const NotCopyMoveConstructible&!");
+ static_assert(!std::is_constructible<out::result<NotCopyMoveConstructible>, NotCopyMoveConstructible &&>::value, "result<NotCopyMoveConstructible> is constructible from NotCopyMoveConstructible&&!");
+
+ // Immovable items should fall back to copy
+ static_assert(!std::is_move_constructible<NotMoveConstructible>::value, "NotMoveConstructible is move constructible!");
+ static_assert(std::is_move_constructible<out::result<NotMoveConstructible>>::value, "result<NotMoveConstructible> is not move constructible!");
+ static_assert(std::is_constructible<out::result<NotMoveConstructible>, const NotMoveConstructible &>::value, "result<NotMoveConstructible> is not constructible from NotMoveConstructible&&!");
+
+ // Uncopyable items should never move (this was the bug report)
+ static_assert(!std::is_copy_constructible<out::result<NotCopyConstructible>>::value, "result<NotCopyConstructible> is copy constructible!");
+ static_assert(!std::is_constructible<out::result<NotCopyConstructible>, const NotCopyConstructible &>::value, "result<NotCopyConstructible> is constructible from const NotCopyConstructible&!");
+
+ BOOST_CHECK(true);
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0182.cpp b/src/boost/libs/outcome/test/tests/issue0182.cpp
new file mode 100644
index 000000000..7bf06d424
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0182.cpp
@@ -0,0 +1,42 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (1 commit)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0189_test, "result<void, int>.value() compiles without tripping fail_to_compile_observers")
+{
+ namespace outcome = BOOST_OUTCOME_V2_NAMESPACE;
+ static_assert(!outcome::trait::is_error_code_available<int>::value, "int is clearly not a source for make_error_code()");
+ static_assert(!outcome::trait::is_exception_ptr_available<int>::value, "int is clearly not a source for make_exception_ptr()");
+ //outcome::result<void, int> r(5);
+ //r.value();
+ BOOST_CHECK(true);
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0203.cpp b/src/boost/libs/outcome/test/tests/issue0203.cpp
new file mode 100644
index 000000000..800fa8373
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0203.cpp
@@ -0,0 +1,103 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (1 commit)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/std_result.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+namespace outcome = BOOST_OUTCOME_V2_NAMESPACE;
+
+enum class error
+{
+ test,
+ abcde
+};
+
+class error_category_impl : public std::error_category
+{
+public:
+ const char *name() const noexcept override { return "test"; }
+
+ std::string message(int code) const noexcept override
+ {
+ switch(static_cast<error>(code))
+ {
+ case error::test:
+ return "test";
+ case error::abcde:
+ return "abcde";
+ }
+ return "unknown";
+ }
+};
+const std::error_category &error_category() noexcept
+{
+ static error_category_impl instance;
+ return instance;
+}
+
+boost::system::error_code make_error_code(error error) noexcept
+{
+ return {static_cast<int>(error), error_category()};
+}
+
+namespace std
+{
+ template <> struct is_error_code_enum<error> : true_type
+ {
+ };
+} // namespace std
+
+template <typename T> using enum_result = outcome::basic_result<T, error, outcome::policy::default_policy<T, error, void>>;
+
+enum_result<int> test()
+{
+ return 5;
+}
+
+outcome::std_result<int> abc()
+{
+ static_assert(std::is_error_code_enum<error>::value, "custom enum is not marked convertible to error code");
+ static_assert(std::is_constructible<boost::system::error_code, error>::value, "error code is not explicitly constructible from custom enum");
+ static_assert(std::is_convertible<error, boost::system::error_code>::value, "error code is not implicitly constructible from custom enum");
+ boost::system::error_code ec = error::test; // custom enum is definitely convertible to error code
+ BOOST_OUTCOME_TRY(test()); // hence this should compile, as implicit conversions work here
+ (void) ec;
+
+ // But explicit conversions are required between dissimilar basic_result, implicit conversions are disabled
+ static_assert(std::is_constructible<outcome::std_result<int>, enum_result<int>>::value, "basic_result with error code is not explicitly constructible from basic_result with custom enum");
+ static_assert(!std::is_convertible<enum_result<int>, outcome::std_result<int>>::value, "basic_result with error code is implicitly constructible from basic_result with custom enum");
+ return 5;
+}
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0203_test, "enum convertible to error code works as designed")
+{
+ BOOST_CHECK(abc().value() == 5);
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0210.cpp b/src/boost/libs/outcome/test/tests/issue0210.cpp
new file mode 100644
index 000000000..0ac1b759a
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0210.cpp
@@ -0,0 +1,78 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (1 commit)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+namespace issues210
+{
+ namespace outcome = BOOST_OUTCOME_V2_NAMESPACE;
+
+ struct error
+ {
+ boost::system::error_code code;
+ };
+
+ // say that my custom error code type is error code compatible
+ inline boost::system::error_code make_error_code(error error) noexcept { return error.code; }
+
+ template <typename T> using custom_result = outcome::basic_result<T, error, outcome::policy::default_policy<T, error, void>>;
+
+ // source of custom result type with error code compatible error type
+ inline custom_result<int> funcA(int x) { return x; }
+
+ // Is the custom result type explicitly constructible to an ordinary result type?
+ inline outcome::result<int> funcB(int x) { return outcome::result<int>(funcA(x)); }
+
+ // Does the custom result type TRY-convert to an ordinary result type?
+ inline outcome::result<int> func1(int x)
+ {
+ BOOST_OUTCOME_TRY(y, funcA(x));
+ return funcB(y);
+ }
+
+ // Is the custom result type explicitly constructible to an ordinary outcome type?
+ inline outcome::outcome<int> funcC(int x) { return outcome::outcome<int>(funcA(x)); }
+
+ // Does the custom result type TRY-convert to an ordinary outcome type?
+ inline outcome::outcome<int> func2(int x)
+ {
+ BOOST_OUTCOME_TRY(y, funcA(x));
+ return funcC(y);
+ }
+} // namespace issues210
+
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0210_test, "result<int, E> with error code compatible custom E does not TRY into a result<int, boost::system::error_code> function")
+{
+ BOOST_CHECK(issues210::func1(5).value() == 5);
+ BOOST_CHECK(issues210::func2(5).value() == 5);
+}
diff --git a/src/boost/libs/outcome/test/tests/issue0220.cpp b/src/boost/libs/outcome/test/tests/issue0220.cpp
new file mode 100644
index 000000000..0da6eaf16
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/issue0220.cpp
@@ -0,0 +1,55 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (1 commit)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/experimental/status_result.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX
+namespace issues220
+{
+ namespace outcome_e = BOOST_OUTCOME_V2_NAMESPACE::experimental;
+
+ template <class T, class E = outcome_e::error> using Result = outcome_e::status_result<T, E>;
+
+ template <class T> using PosixResult = outcome_e::status_result<T, outcome_e::posix_code>;
+
+ Result<int> convert(const PosixResult<int> &posix_result) { return Result<int>(posix_result); }
+} // namespace issues220
+#endif
+
+
+BOOST_OUTCOME_AUTO_TEST_CASE(issues_0220_test, "ubsan reports reference binding to null pointer")
+{
+#ifndef BOOST_OUTCOME_SYSTEM_ERROR2_NOT_POSIX
+ using namespace issues220;
+ BOOST_CHECK(convert(PosixResult<int>(0)).value() == 0);
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/noexcept-propagation.cpp b/src/boost/libs/outcome/test/tests/noexcept-propagation.cpp
new file mode 100644
index 000000000..3754ff44d
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/noexcept-propagation.cpp
@@ -0,0 +1,84 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (6 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4127) // conditional expression is constant
+#endif
+
+#ifndef BOOST_NO_EXCEPTIONS
+// std nothrow traits seem to return random values if exceptions are disabled on MSVC
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_noexcept, "Tests that the outcome correctly inherits noexcept from its type R")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ {
+ using type = outcome<int>;
+ BOOST_CHECK(std::is_nothrow_copy_constructible<type>::value);
+ BOOST_CHECK(std::is_nothrow_move_constructible<type>::value);
+ BOOST_CHECK(std::is_nothrow_copy_assignable<type>::value);
+ BOOST_CHECK(std::is_nothrow_move_assignable<type>::value);
+ BOOST_CHECK(std::is_nothrow_destructible<type>::value);
+ }
+ {
+ using type = outcome<std::string>;
+ BOOST_CHECK(std::is_nothrow_copy_constructible<type>::value == std::is_nothrow_copy_constructible<std::string>::value);
+ BOOST_CHECK(std::is_nothrow_move_constructible<type>::value == std::is_nothrow_move_constructible<std::string>::value);
+ BOOST_CHECK(std::is_nothrow_copy_assignable<type>::value == std::is_nothrow_copy_assignable<std::string>::value);
+ BOOST_CHECK(std::is_nothrow_move_assignable<type>::value == std::is_nothrow_move_assignable<std::string>::value);
+ BOOST_CHECK(std::is_nothrow_destructible<type>::value == std::is_nothrow_destructible<std::string>::value);
+ }
+ {
+ struct Except
+ {
+ int n;
+ Except() = delete;
+ Except(const Except & /*unused*/) noexcept(false)
+ : n(0)
+ {
+ }
+ Except(Except && /*unused*/) noexcept(false)
+ : n(0)
+ {
+ }
+ Except &operator=(const Except & /*unused*/) noexcept(false) { return *this; }
+ Except &operator=(Except && /*unused*/) noexcept(false) { return *this; }
+ ~Except() noexcept(false) { n = 0; }
+ };
+ using type = outcome<Except>;
+ BOOST_CHECK(!std::is_nothrow_copy_constructible<type>::value);
+ BOOST_CHECK(!std::is_nothrow_move_constructible<type>::value);
+ BOOST_CHECK(!std::is_nothrow_copy_assignable<type>::value);
+ BOOST_CHECK(!std::is_nothrow_move_assignable<type>::value);
+ BOOST_CHECK(!std::is_nothrow_destructible<type>::value);
+ }
+}
+#endif
diff --git a/src/boost/libs/outcome/test/tests/propagate.cpp b/src/boost/libs/outcome/test/tests/propagate.cpp
new file mode 100644
index 000000000..0e3cbb545
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/propagate.cpp
@@ -0,0 +1,90 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/outcome/try.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_propagate, "Tests that the outcome propagates errors between different editions of itself")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ {
+ auto t0 = [&](int a) { return result<long>(boost::system::error_code(a, boost::system::generic_category())); };
+ auto t1 = [&](int a) {
+ result<double> f(t0(a)); // double is constructible from long
+ BOOST_CHECK(!f.has_value());
+ BOOST_CHECK(f.has_error());
+ return f;
+ };
+ auto t2 = [&](int a) {
+ result<void> f(t1(a).error());
+ BOOST_CHECK(!f.has_value());
+ BOOST_CHECK(f.has_error());
+ return f;
+ };
+ auto t3 = [&](int a) {
+ outcome<std::string> f(t2(a));
+ BOOST_CHECK(!f.has_value());
+ BOOST_CHECK(f.has_error());
+ return f;
+ };
+ BOOST_CHECK(t3(5).error().value() == 5);
+ result<int> a2{result<void>(in_place_type<void>)};
+ result<int> a3{result<void>(boost::system::error_code(5, boost::system::generic_category()))};
+ BOOST_CHECK(a2.has_value());
+ BOOST_CHECK(!a2.has_error());
+ BOOST_CHECK(!a3.has_value());
+ BOOST_CHECK(a3.has_error());
+ }
+ {
+ auto t0 = [&](int a) { return result<long>(a); };
+ auto t1 = [&](int a) -> result<std::string> {
+ BOOST_OUTCOME_TRY(f, (t0(a)));
+ return std::to_string(f);
+ };
+ BOOST_CHECK(t1(5).value() == "5");
+ }
+ {
+ auto t0 = [&](int a) { return result<long>(a); };
+ auto t1 = [&](int a) -> outcome<std::string> {
+ BOOST_OUTCOME_TRY(f, (t0(a)));
+ return std::to_string(f);
+ };
+ BOOST_CHECK(t1(5).value() == "5");
+ }
+ {
+ auto t0 = [&](int a) -> result<long> { return result<long>(a); };
+ auto t1 = [&](int a) -> outcome<void> {
+ BOOST_OUTCOME_TRY((t0(a)));
+ return outcome<void>(in_place_type<void>);
+ };
+ (void) t1(5);
+ }
+}
diff --git a/src/boost/libs/outcome/test/tests/serialisation.cpp b/src/boost/libs/outcome/test/tests/serialisation.cpp
new file mode 100644
index 000000000..55d978dd5
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/serialisation.cpp
@@ -0,0 +1,49 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/iostream_support.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_serialisation, "Tests that the outcome serialises and deserialises as intended")
+{
+#if !defined(__APPLE__) || defined(__cpp_exceptions)
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ outcome<std::string> a("niall"), b(boost::system::error_code(5, boost::system::generic_category())), c(boost::copy_exception(std::ios_base::failure("A test failure message")));
+ std::cout << "a contains " << print(a) << " and b contains " << print(b) << " and c contains " << print(c) << std::endl;
+
+ std::stringstream ss;
+ outcome<int, std::string, long> d(success(5));
+ ss << d;
+ ss.seekg(0);
+ outcome<int, std::string, long> e(failure(""));
+ ss >> e;
+ BOOST_CHECK(d == e);
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/success-failure.cpp b/src/boost/libs/outcome/test/tests/success-failure.cpp
new file mode 100644
index 000000000..af1c3e46d
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/success-failure.cpp
@@ -0,0 +1,69 @@
+/* Unit testing for outcomes
+(C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (10 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/result.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#include <iostream>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_success_failure, "Tests that the success and failure type sugars work as intended")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+#ifdef __cpp_deduction_guides
+ std::cout << "__cpp_deduction_guides = 1" << std::endl;
+#endif
+ {
+ auto a = success(5);
+ auto b = success();
+ auto c = success("hello");
+ static_assert(std::is_same<decltype(a), success_type<int>>::value, "");
+ static_assert(std::is_same<decltype(b), success_type<void>>::value, "");
+ static_assert(std::is_same<decltype(c), success_type<const char *>>::value, "");
+ static_assert(std::is_same<decltype(a)::value_type, int>::value, "");
+ // static_assert(std::is_same<decltype(b.value), int>::value, "");
+ static_assert(std::is_same<decltype(c)::value_type, const char *>::value, "");
+ }
+#if !defined(__APPLE__) || defined(__cpp_exceptions)
+ {
+ auto e = boost::copy_exception(std::exception());
+ auto a = failure(5);
+ auto b = failure(5, e);
+ auto c = failure(5, 5);
+ static_assert(std::is_same<decltype(a), failure_type<int, void>>::value, "");
+ static_assert(std::is_same<decltype(b), failure_type<int, boost::exception_ptr>>::value, "");
+ static_assert(std::is_same<decltype(c), failure_type<int, int>>::value, "");
+ static_assert(std::is_same<decltype(a)::error_type, int>::value, "");
+ static_assert(std::is_same<decltype(b)::error_type, int>::value, "");
+ static_assert(std::is_same<decltype(b)::exception_type, boost::exception_ptr>::value, "");
+ static_assert(std::is_same<decltype(c)::error_type, int>::value, "");
+ static_assert(std::is_same<decltype(c)::exception_type, int>::value, "");
+ }
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/swap.cpp b/src/boost/libs/outcome/test/tests/swap.cpp
new file mode 100644
index 000000000..0bcba3802
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/swap.cpp
@@ -0,0 +1,432 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+/* Should be this:
+
+78 move constructor count = 2
+65 move assignment count = 3
+78 move assignment count = 1
+65 move constructor count = 2
+78 move assignment count = 0
+65 move assignment count = 1
+
+78 move constructor count = 1
+65 move assignment count = 2
+78 move assignment count = 0
+65 move assignment count = 1
+78 move assignment count = 0
+
+78 move constructor count = 2
+65 move assignment count = 3
+78 move assignment count = 1
+65 move constructor count = 2
+78 move assignment count = 0
+65 move assignment count = 1
+
+78 move constructor count = 1
+65 move assignment count = 2
+78 move assignment count = 0
+65 move assignment count = 1
+78 move assignment count = 0
+
+78 move constructor count = 2
+65 move assignment count = 3
+78 move assignment count = 1
+65 move constructor count = 2
+78 move assignment count = 0
+65 move assignment count = 1
+
+78 move constructor count = 1
+65 move assignment count = 2
+78 move assignment count = 0
+65 move assignment count = 1
+78 move assignment count = 0
+
+78 move constructor count = 2
+65 move assignment count = 3
+78 move assignment count = 1
+65 move constructor count = 2
+78 move assignment count = 0
+65 move assignment count = 1
+
+78 move constructor count = 1
+65 move assignment count = 2
+78 move assignment count = 0
+65 move assignment count = 1
+78 move assignment count = 0
+*/
+
+#ifndef BOOST_NO_EXCEPTIONS
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4297) // function assumed not to throw an exception but does
+#endif
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wterminate"
+#endif
+template <bool mc, bool ma> struct Throwy
+{
+ int count{0}, inc{0}, id{0};
+ Throwy() = default;
+ Throwy(int c, int d, int i = 1) noexcept
+ : count(c)
+ , inc(i)
+ , id(d)
+ {
+ }
+ Throwy(const Throwy &) = delete;
+ Throwy &operator=(const Throwy &) = delete;
+ Throwy(Throwy &&o) noexcept(!mc)
+ : count(o.count - o.inc)
+ , inc(o.inc)
+ , id(o.id) // NOLINT
+ {
+ if(mc)
+ {
+ std::cout << " " << id << " move constructor count = " << count << std::endl;
+ if(!count)
+ {
+ std::cout << " " << id << " move constructor throws!" << std::endl;
+ throw std::bad_alloc();
+ }
+ }
+ o.count = 0;
+ o.inc = 0;
+ o.id = 0;
+ }
+ Throwy &operator=(Throwy &&o) noexcept(!ma)
+ {
+ count = o.count - o.inc;
+ if(ma)
+ {
+ std::cout << " " << o.id << " move assignment count = " << count << std::endl;
+ if(!count)
+ {
+ std::cout << " " << o.id << " move assignment throws!" << std::endl;
+ throw std::bad_alloc();
+ }
+ }
+ inc = o.inc;
+ id = o.id;
+ o.count = 0;
+ o.inc = 0;
+ o.id = 0;
+ return *this;
+ }
+ ~Throwy() = default;
+};
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+enum class ErrorCode
+{
+ dummy
+};
+enum class ErrorCode2
+{
+ dummy
+};
+template <bool mc, bool ma> using resulty1 = BOOST_OUTCOME_V2_NAMESPACE::result<Throwy<mc, ma>, ErrorCode, BOOST_OUTCOME_V2_NAMESPACE::policy::all_narrow>;
+template <bool mc, bool ma> using resulty2 = BOOST_OUTCOME_V2_NAMESPACE::result<ErrorCode, Throwy<mc, ma>, BOOST_OUTCOME_V2_NAMESPACE::policy::all_narrow>;
+template <bool mc, bool ma> using outcomey1 = BOOST_OUTCOME_V2_NAMESPACE::outcome<ErrorCode, Throwy<mc, ma>, ErrorCode2, BOOST_OUTCOME_V2_NAMESPACE::policy::all_narrow>;
+template <bool mc, bool ma> using outcomey2 = BOOST_OUTCOME_V2_NAMESPACE::outcome<ErrorCode, ErrorCode2, Throwy<mc, ma>, BOOST_OUTCOME_V2_NAMESPACE::policy::all_narrow>;
+#endif
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_swap, "Tests that the outcome swaps as intended")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ { // Does swap actually swap?
+ outcome<std::string> a("niall"), b("douglas");
+ BOOST_CHECK(a.value() == "niall");
+ BOOST_CHECK(b.value() == "douglas");
+ swap(a, b);
+ BOOST_CHECK(a.value() == "douglas");
+ BOOST_CHECK(b.value() == "niall");
+ a = boost::system::errc::not_enough_memory;
+ swap(a, b);
+ BOOST_CHECK(a.value() == "niall");
+ BOOST_CHECK(b.error() == boost::system::errc::not_enough_memory);
+ BOOST_CHECK(!a.has_lost_consistency());
+ BOOST_CHECK(!b.has_lost_consistency());
+ }
+#ifndef BOOST_NO_EXCEPTIONS
+ { // Is noexcept propagated?
+ using nothrow_t = Throwy<false, false>;
+ using nothrow = resulty1<false, false>;
+ static_assert(std::is_nothrow_move_constructible<nothrow_t>::value, "throwy not correct!");
+ static_assert(std::is_nothrow_move_assignable<nothrow_t>::value, "throwy not correct!");
+ static_assert(std::is_nothrow_move_constructible<nothrow>::value, "type not correct!");
+ static_assert(std::is_nothrow_move_assignable<nothrow>::value, "type not correct!");
+
+ static_assert(detail::is_nothrow_swappable<nothrow_t>::value, "is_nothrow_swappable is not correct!");
+
+ static_assert(noexcept(nothrow(0, 0)), "type has a throwing value constructor!");
+ nothrow a(1, 78), b(1, 65);
+ a.swap(b);
+ static_assert(noexcept(a.swap(b)), "type has a throwing swap!");
+ }
+ { // Is noexcept propagated?
+ using nothrow_t = Throwy<false, false>;
+ using nothrow = resulty2<false, false>;
+ static_assert(std::is_nothrow_move_constructible<nothrow_t>::value, "throwy not correct!");
+ static_assert(std::is_nothrow_move_assignable<nothrow_t>::value, "throwy not correct!");
+ static_assert(std::is_nothrow_move_constructible<nothrow>::value, "type not correct!");
+ static_assert(std::is_nothrow_move_assignable<nothrow>::value, "type not correct!");
+
+ static_assert(detail::is_nothrow_swappable<nothrow_t>::value, "is_nothrow_swappable is not correct!");
+
+ static_assert(noexcept(nothrow(0, 0)), "type has a throwing value constructor!");
+ nothrow a(1, 78), b(1, 65);
+ a.swap(b);
+ static_assert(noexcept(a.swap(b)), "type has a throwing swap!");
+ }
+
+ { // Does swap implement the strong guarantee?
+ using throwy_t = Throwy<true, true>;
+ using throwy = resulty1<true, true>;
+ static_assert(!std::is_nothrow_move_constructible<throwy_t>::value, "throwy not correct!");
+ static_assert(!std::is_nothrow_move_assignable<throwy_t>::value, "throwy not correct!");
+ static_assert(!std::is_nothrow_move_constructible<throwy>::value, "type not correct!");
+ static_assert(!std::is_nothrow_move_assignable<throwy>::value, "type not correct!");
+
+ static_assert(!detail::is_nothrow_swappable<throwy_t>::value, "is_nothrow_swappable is not correct!");
+
+ std::cout << "Result value first swap succeeds, second swap second move assignment throws:" << std::endl;
+ {
+ throwy a(3, 78), b(4, 65);
+ a.swap(b);
+ static_assert(!noexcept(a.swap(b)), "type has a non-throwing swap!");
+ BOOST_CHECK(a.value().id == 65);
+ BOOST_CHECK(b.value().id == 78);
+ try
+ {
+ a.swap(b); // fails on first assignment
+ BOOST_REQUIRE(false);
+ }
+ catch(const std::bad_alloc & /*unused*/)
+ {
+ BOOST_CHECK(a.value().id == 65); // ensure it is perfectly restored
+ BOOST_CHECK(b.value().id == 78);
+ }
+ BOOST_CHECK(!a.has_lost_consistency());
+ BOOST_CHECK(!b.has_lost_consistency());
+ }
+ std::cout << "\nResult value second move assignment throws, on recover second move assignment throws:" << std::endl;
+ {
+ throwy a(2, 78), b(3, 65); // fails on second assignment, cannot restore
+ try
+ {
+ a.swap(b);
+ BOOST_REQUIRE(false);
+ }
+ catch(const std::bad_alloc & /*unused*/)
+ {
+ BOOST_CHECK(a.has_lost_consistency()); // both must be marked tainted
+ BOOST_CHECK(b.has_lost_consistency());
+ }
+ }
+ }
+ std::cout << "\nResult error first swap succeeds, second swap first move assignment throws:" << std::endl;
+ { // Does swap implement the strong guarantee?
+ using throwy_t = Throwy<true, true>;
+ using throwy = resulty2<true, true>;
+ static_assert(!std::is_nothrow_move_constructible<throwy_t>::value, "throwy not correct!");
+ static_assert(!std::is_nothrow_move_assignable<throwy_t>::value, "throwy not correct!");
+ static_assert(!std::is_nothrow_move_constructible<throwy>::value, "type not correct!");
+ static_assert(!std::is_nothrow_move_assignable<throwy>::value, "type not correct!");
+
+ static_assert(!detail::is_nothrow_swappable<throwy_t>::value, "is_nothrow_swappable is not correct!");
+
+ {
+ throwy a(3, 78), b(4, 65);
+ a.swap(b);
+ static_assert(!noexcept(a.swap(b)), "type has a non-throwing swap!");
+ BOOST_CHECK(a.error().id == 65);
+ BOOST_CHECK(b.error().id == 78);
+ try
+ {
+ a.swap(b); // fails on first assignment
+ BOOST_REQUIRE(false);
+ }
+ catch(const std::bad_alloc & /*unused*/)
+ {
+ BOOST_CHECK(a.error().id == 65); // ensure it is perfectly restored
+ BOOST_CHECK(b.error().id == 78);
+ }
+ BOOST_CHECK(!a.has_lost_consistency());
+ BOOST_CHECK(!b.has_lost_consistency());
+ }
+ std::cout << "\nResult error second move assignment throws, on recover second move assignment throws:" << std::endl;
+ {
+ throwy a(2, 78), b(3, 65); // fails on second assignment, cannot restore
+ try
+ {
+ a.swap(b);
+ BOOST_REQUIRE(false);
+ }
+ catch(const std::bad_alloc & /*unused*/)
+ {
+ BOOST_CHECK(a.has_lost_consistency()); // both must be marked tainted
+ BOOST_CHECK(b.has_lost_consistency());
+ }
+ }
+ }
+
+ { // Is noexcept propagated?
+ using nothrow_t = Throwy<false, false>;
+ using nothrow = outcomey1<false, false>;
+ static_assert(std::is_nothrow_move_constructible<nothrow_t>::value, "throwy not correct!");
+ static_assert(std::is_nothrow_move_assignable<nothrow_t>::value, "throwy not correct!");
+ static_assert(std::is_nothrow_move_constructible<nothrow>::value, "type not correct!");
+ static_assert(std::is_nothrow_move_assignable<nothrow>::value, "type not correct!");
+
+ static_assert(detail::is_nothrow_swappable<nothrow_t>::value, "is_nothrow_swappable is not correct!");
+
+ static_assert(noexcept(nothrow(0, 0)), "type has a throwing value constructor!");
+ nothrow a(1, 78), b(1, 65);
+ a.swap(b);
+ static_assert(noexcept(a.swap(b)), "type has a throwing swap!");
+ }
+ { // Is noexcept propagated?
+ using nothrow_t = Throwy<false, false>;
+ using nothrow = outcomey1<false, false>;
+ static_assert(std::is_nothrow_move_constructible<nothrow_t>::value, "throwy not correct!");
+ static_assert(std::is_nothrow_move_assignable<nothrow_t>::value, "throwy not correct!");
+ static_assert(std::is_nothrow_move_constructible<nothrow>::value, "type not correct!");
+ static_assert(std::is_nothrow_move_assignable<nothrow>::value, "type not correct!");
+
+ static_assert(detail::is_nothrow_swappable<nothrow_t>::value, "is_nothrow_swappable is not correct!");
+
+ static_assert(noexcept(nothrow(0, 0)), "type has a throwing value constructor!");
+ nothrow a(1, 78), b(1, 65);
+ a.swap(b);
+ static_assert(noexcept(a.swap(b)), "type has a throwing swap!");
+ }
+
+ std::cout << "\n\nOutcome value first swap succeeds, second swap first move assignment throws:" << std::endl;
+ { // Does swap implement the strong guarantee?
+ using throwy_t = Throwy<true, true>;
+ using throwy = outcomey1<true, true>;
+ static_assert(!std::is_nothrow_move_constructible<throwy_t>::value, "throwy not correct!");
+ static_assert(!std::is_nothrow_move_assignable<throwy_t>::value, "throwy not correct!");
+ static_assert(!std::is_nothrow_move_constructible<throwy>::value, "type not correct!");
+ static_assert(!std::is_nothrow_move_assignable<throwy>::value, "type not correct!");
+
+ static_assert(!detail::is_nothrow_swappable<throwy_t>::value, "is_nothrow_swappable is not correct!");
+
+ {
+ throwy a(3, 78), b(4, 65);
+ a.swap(b);
+ static_assert(!noexcept(a.swap(b)), "type has a non-throwing swap!");
+ BOOST_CHECK(a.error().id == 65);
+ BOOST_CHECK(b.error().id == 78);
+ try
+ {
+ a.swap(b); // fails on first assignment
+ BOOST_REQUIRE(false);
+ }
+ catch(const std::bad_alloc & /*unused*/)
+ {
+ BOOST_CHECK(a.error().id == 65); // ensure it is perfectly restored
+ BOOST_CHECK(b.error().id == 78);
+ }
+ BOOST_CHECK(!a.has_lost_consistency());
+ BOOST_CHECK(!b.has_lost_consistency());
+ }
+ std::cout << "\nOutcome value second move assignment throws, on recover second move assignment throws:" << std::endl;
+ {
+ throwy a(2, 78), b(3, 65); // fails on second assignment, cannot restore
+ try
+ {
+ a.swap(b);
+ BOOST_REQUIRE(false);
+ }
+ catch(const std::bad_alloc & /*unused*/)
+ {
+ BOOST_CHECK(a.has_lost_consistency()); // both must be marked tainted
+ BOOST_CHECK(b.has_lost_consistency());
+ }
+ }
+ }
+ std::cout << "\nOutcome error first swap succeeds, second swap first move assignment throws:" << std::endl;
+ { // Does swap implement the strong guarantee?
+ using throwy_t = Throwy<true, true>;
+ using throwy = outcomey2<true, true>;
+ static_assert(!std::is_nothrow_move_constructible<throwy_t>::value, "throwy not correct!");
+ static_assert(!std::is_nothrow_move_assignable<throwy_t>::value, "throwy not correct!");
+ static_assert(!std::is_nothrow_move_constructible<throwy>::value, "type not correct!");
+ static_assert(!std::is_nothrow_move_assignable<throwy>::value, "type not correct!");
+
+ static_assert(!detail::is_nothrow_swappable<throwy_t>::value, "is_nothrow_swappable is not correct!");
+
+ {
+ throwy a(3, 78), b(4, 65);
+ a.swap(b);
+ static_assert(!noexcept(a.swap(b)), "type has a non-throwing swap!");
+ BOOST_CHECK(a.exception().id == 65);
+ BOOST_CHECK(b.exception().id == 78);
+ try
+ {
+ a.swap(b); // fails on first assignment
+ BOOST_REQUIRE(false);
+ }
+ catch(const std::bad_alloc & /*unused*/)
+ {
+ BOOST_CHECK(a.exception().id == 65); // ensure it is perfectly restored
+ BOOST_CHECK(b.exception().id == 78);
+ }
+ BOOST_CHECK(!a.has_lost_consistency());
+ BOOST_CHECK(!b.has_lost_consistency());
+ }
+ std::cout << "\nOutcome error second move assignment throws, on recover second move assignment throws:" << std::endl;
+ {
+ throwy a(2, 78), b(3, 65); // fails on second assignment, cannot restore
+ try
+ {
+ a.swap(b);
+ BOOST_REQUIRE(false);
+ }
+ catch(const std::bad_alloc & /*unused*/)
+ {
+ BOOST_CHECK(a.has_lost_consistency()); // both must be marked tainted
+ BOOST_CHECK(b.has_lost_consistency());
+ }
+ }
+ std::cout << std::endl;
+ }
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/udts.cpp b/src/boost/libs/outcome/test/tests/udts.cpp
new file mode 100644
index 000000000..740ca51d2
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/udts.cpp
@@ -0,0 +1,154 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (7 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4702) // unreachable code
+#endif
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_udts, "Tests that the outcome works as intended with user-defined types")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ // No default constructor, no copy/move, no assignment
+ {
+ struct udt
+ {
+ int a;
+ explicit udt(int _a)
+ : a(_a)
+ {
+ }
+ udt() = delete;
+ udt(const udt &) = delete;
+ udt(udt &&) = delete;
+ udt &operator=(const udt &) = delete;
+ udt &operator=(udt &&) = delete;
+ ~udt() = default;
+ };
+ outcome<udt> foo(in_place_type<udt>, 5);
+ BOOST_CHECK(5 == foo.value().a);
+ }
+#ifndef BOOST_NO_EXCEPTIONS
+ // Emplace construct, throws during move and copy
+ {
+ struct udt
+ {
+ std::string a;
+ explicit udt(std::string _a)
+ : a(std::move(_a))
+ {
+ }
+ udt() = delete;
+ udt(const udt & /*unused*/) { throw std::logic_error("copy"); }
+ udt(udt && /*unused*/) noexcept(false) { throw std::logic_error("move"); } // NOLINT
+ udt &operator=(const udt & /*unused*/) { throw std::logic_error("copy"); }
+ udt &operator=(udt && /*unused*/) noexcept(false) { throw std::logic_error("move"); } // NOLINT
+ ~udt() { a.clear(); }
+ };
+ static_assert(!std::is_default_constructible<udt>::value, "udt is default constructible");
+ static_assert(std::is_copy_constructible<udt>::value, "udt is not copy constructible");
+ static_assert(std::is_move_constructible<udt>::value, "udt is not move constructible");
+ static_assert(!std::is_default_constructible<outcome<udt>>::value, "outcome<udt> is default constructible");
+ static_assert(std::is_copy_constructible<outcome<udt>>::value, "outcome<udt> is not copy constructible");
+ static_assert(std::is_move_constructible<outcome<udt>>::value, "outcome<udt> is not move constructible");
+ // Emplace constructs
+ outcome<udt> foo(in_place_type<udt>, "niall");
+ BOOST_CHECK("niall" == foo.value().a);
+ try
+ {
+ auto foo2(foo); // NOLINT
+ BOOST_CHECK(false);
+ }
+ catch(const std::logic_error &e)
+ {
+ BOOST_CHECK(!strcmp(e.what(), "copy"));
+ }
+ catch(...)
+ {
+ BOOST_CHECK(false);
+ }
+ BOOST_CHECK("niall" == foo.value().a);
+ try
+ {
+ auto foo2(std::move(foo));
+ BOOST_CHECK(false);
+ }
+ catch(const std::logic_error &e)
+ {
+ BOOST_CHECK(!strcmp(e.what(), "move"));
+ }
+ catch(...)
+ {
+ BOOST_CHECK(false);
+ }
+ BOOST_CHECK("niall" == foo.value().a); // NOLINT
+ // Does throwing during copy assignment work?
+ {
+ outcome<udt> foo2(in_place_type<udt>, "douglas");
+ try
+ {
+ foo2 = foo;
+ BOOST_CHECK(false);
+ }
+ catch(const std::logic_error &e)
+ {
+ BOOST_CHECK(!strcmp(e.what(), "copy"));
+ BOOST_CHECK(foo2.value().a == "douglas");
+ }
+ catch(...)
+ {
+ BOOST_CHECK(false);
+ }
+ BOOST_CHECK("niall" == foo.value().a);
+ }
+ // Does throwing during move assignment work?
+ {
+ outcome<udt> foo2(in_place_type<udt>, "douglas");
+ try
+ {
+ foo2 = std::move(foo);
+ BOOST_CHECK(false);
+ }
+ catch(const std::logic_error &e)
+ {
+ BOOST_CHECK(!strcmp(e.what(), "move"));
+ BOOST_CHECK(foo2.value().a == "douglas");
+ }
+ catch(...)
+ {
+ BOOST_CHECK(false);
+ }
+ BOOST_CHECK("niall" == foo.value().a); // NOLINT
+ }
+ }
+#endif
+}
diff --git a/src/boost/libs/outcome/test/tests/value-or-error.cpp b/src/boost/libs/outcome/test/tests/value-or-error.cpp
new file mode 100644
index 000000000..558e229a7
--- /dev/null
+++ b/src/boost/libs/outcome/test/tests/value-or-error.cpp
@@ -0,0 +1,54 @@
+/* Unit testing for outcomes
+(C) 2013-2020 Niall Douglas <http://www.nedproductions.biz/> (3 commits)
+
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+#include <boost/outcome/outcome.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+BOOST_OUTCOME_AUTO_TEST_CASE(works_outcome_valueorerror, "Tests that outcome constructs from ValueOrError and ValueOrNone concept inputs")
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ {
+ struct value_or_error
+ {
+ using value_type = int;
+ using error_type = void;
+ bool has_value() const { return true; }
+ int value() const { return 78; }
+ void error() const {}
+ } a;
+ static_assert(convert::ValueOrNone<value_or_error>, "");
+ static_assert(convert::ValueOrError<value_or_error>, "");
+ BOOST_CHECK((convert::value_or_error<result<long>, value_or_error>{}(a).value() == 78));
+
+ result<long> b(a);
+ BOOST_CHECK(b.has_value());
+ BOOST_CHECK(b.value() == 78);
+ }
+}