summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/outcome/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/outcome/test')
-rw-r--r--src/boost/libs/outcome/test/Jamfile.v267
-rw-r--r--src/boost/libs/outcome/test/compile-fail/issue0071-fail.cpp37
-rw-r--r--src/boost/libs/outcome/test/compile-fail/outcome-int-int-1.cpp33
-rw-r--r--src/boost/libs/outcome/test/compile-fail/result-int-int-1.cpp33
-rw-r--r--src/boost/libs/outcome/test/compile-fail/result-int-int-2.cpp33
-rw-r--r--src/boost/libs/outcome/test/expected-pass.cpp2015
-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
43 files changed, 6404 insertions, 0 deletions
diff --git a/src/boost/libs/outcome/test/Jamfile.v2 b/src/boost/libs/outcome/test/Jamfile.v2
new file mode 100644
index 000000000..4b11a3805
--- /dev/null
+++ b/src/boost/libs/outcome/test/Jamfile.v2
@@ -0,0 +1,67 @@
+# Boost.Outcome Library test Jamfile
+#
+# Copyright (C) 2017-2019 Niall Douglas
+#
+# Use, modification, and distribution is subject to the Boost Software
+# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+#
+# See http://www.boost.org/libs/outcome for documentation.
+
+import testing ;
+import ../../config/checks/config : requires ;
+import ../../predef/tools/check/predef : check require : predef-check predef-require ;
+
+project
+ : requirements
+ [ requires cxx14_variable_templates cxx14_constexpr ]
+ [ predef-require "!BOOST_COMP_GNUC" or "BOOST_COMP_GNUC >= 6.0" ]
+ [ predef-require "!BOOST_COMP_CLANG" or "BOOST_COMP_CLANG >= 4.0" ]
+ <define>BOOST_TEST_MODULE=Outcome
+ <library>../../test/build//boost_unit_test_framework
+ ;
+
+{
+ test-suite outcome :
+
+ [ compile-fail compile-fail/outcome-int-int-1.cpp ]
+ [ compile-fail compile-fail/result-int-int-1.cpp ]
+ [ compile-fail compile-fail/result-int-int-2.cpp ]
+
+ [ run tests/comparison.cpp ]
+ [ run tests/constexpr.cpp ]
+ [ run tests/containers.cpp ]
+ [ run tests/core-outcome.cpp ]
+ [ run tests/core-result.cpp ]
+ [ run tests/default-construction.cpp ]
+ [ run tests/experimental-core-outcome-status.cpp ]
+ [ run tests/experimental-core-result-status.cpp ]
+ [ run tests/experimental-p0709a.cpp ]
+ [ run tests/fileopen.cpp ]
+ [ run tests/hooks.cpp ]
+ [ run tests/issue0007.cpp ]
+ [ run tests/issue0009.cpp ]
+ [ run tests/issue0010.cpp ]
+ [ run tests/issue0012.cpp ]
+ [ run tests/issue0016.cpp ]
+ [ run tests/issue0059.cpp ]
+ [ run tests/issue0061.cpp ]
+ [ run tests/issue0064.cpp ]
+ [ run tests/issue0065.cpp ]
+ [ run tests/issue0071.cpp ]
+ [ run tests/issue0095.cpp ]
+ [ run tests/issue0115.cpp ]
+ [ run tests/issue0116.cpp ]
+ [ run tests/issue0140.cpp ]
+ [ run tests/noexcept-propagation.cpp ]
+ [ run tests/propagate.cpp ]
+ [ run tests/serialisation.cpp ]
+ [ run tests/success-failure.cpp ]
+ [ run tests/swap.cpp ]
+ [ run tests/udts.cpp ]
+ [ run tests/value-or-error.cpp ]
+
+ [ run expected-pass.cpp ]
+
+ ;
+}
diff --git a/src/boost/libs/outcome/test/compile-fail/issue0071-fail.cpp b/src/boost/libs/outcome/test/compile-fail/issue0071-fail.cpp
new file mode 100644
index 000000000..ac94c7138
--- /dev/null
+++ b/src/boost/libs/outcome/test/compile-fail/issue0071-fail.cpp
@@ -0,0 +1,37 @@
+/* clang-format off
+(error: no matching function for call to .+::basic_result|error: no matching constructor for initialization of 'result<udt>'|cannot convert argument 1 from 'int')
+clang-format on
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License in the accompanying file
+Licence.txt or at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file Licence.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include "../../include/boost/outcome/result.hpp"
+
+int main()
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ struct udt
+ {
+ explicit udt(int /*unused*/) {}
+ };
+ // Must not be possible to implicitly initialise a result<udt>
+ result<udt> m(5);
+ return 0;
+}
diff --git a/src/boost/libs/outcome/test/compile-fail/outcome-int-int-1.cpp b/src/boost/libs/outcome/test/compile-fail/outcome-int-int-1.cpp
new file mode 100644
index 000000000..4ee66b746
--- /dev/null
+++ b/src/boost/libs/outcome/test/compile-fail/outcome-int-int-1.cpp
@@ -0,0 +1,33 @@
+/* clang-format off
+(use of deleted function|call to deleted constructor|attempting to reference a deleted function)
+clang-format on
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License in the accompanying file
+Licence.txt or at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file Licence.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include "../../include/boost/outcome/outcome.hpp"
+
+int main()
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ // Must not be possible to initialise an outcome with same R, S and P types
+ outcome<int, int, int> m(5);
+ return 0;
+}
diff --git a/src/boost/libs/outcome/test/compile-fail/result-int-int-1.cpp b/src/boost/libs/outcome/test/compile-fail/result-int-int-1.cpp
new file mode 100644
index 000000000..e4eb92031
--- /dev/null
+++ b/src/boost/libs/outcome/test/compile-fail/result-int-int-1.cpp
@@ -0,0 +1,33 @@
+/* clang-format off
+(use of deleted function|call to deleted constructor|attempting to reference a deleted function)
+clang-format on
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License in the accompanying file
+Licence.txt or at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file Licence.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include "../../include/boost/outcome/result.hpp"
+
+int main()
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ // Must not be possible to initialise a result with same R and S types
+ result<int, int> m(5);
+ return 0;
+}
diff --git a/src/boost/libs/outcome/test/compile-fail/result-int-int-2.cpp b/src/boost/libs/outcome/test/compile-fail/result-int-int-2.cpp
new file mode 100644
index 000000000..35c999d0a
--- /dev/null
+++ b/src/boost/libs/outcome/test/compile-fail/result-int-int-2.cpp
@@ -0,0 +1,33 @@
+/* clang-format off
+(use of deleted function|call to deleted constructor|attempting to reference a deleted function)
+clang-format on
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License in the accompanying file
+Licence.txt or at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file Licence.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include "../../include/boost/outcome/result.hpp"
+
+int main()
+{
+ using namespace BOOST_OUTCOME_V2_NAMESPACE;
+ // Must not be possible to initialise a result with same R and S types
+ result<int, int> m(in_place_type<int>);
+ return 0;
+}
diff --git a/src/boost/libs/outcome/test/expected-pass.cpp b/src/boost/libs/outcome/test/expected-pass.cpp
new file mode 100644
index 000000000..5c63b9118
--- /dev/null
+++ b/src/boost/libs/outcome/test/expected-pass.cpp
@@ -0,0 +1,2015 @@
+//! \file test_expected.cpp
+
+// Copyright Pierre Talbot 2013.
+// Copyright Vicente J. Botet Escriba 2013,2014.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+//(See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+// Notes by ned:
+// Original is at https://github.com/viboes/std-make/blob/master/test/expected/expected_pass.cpp
+// This edition modified to use result with throw_bad_result_access policy
+// Quite a lot of the test suite I had to disable, not because our Expected implementation is
+// incorrect, but because the reference test suite is testing an Expected quite far away from
+// the latest WG21 proposal paper, and we're implementing that latest edition.
+
+#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ >= 7
+
+#include <utility>
+
+#include <boost/outcome/iostream_support.hpp>
+#include <boost/outcome/std_result.hpp>
+
+#define QUICKCPPLIB_BOOST_UNIT_TEST_CUSTOM_MAIN_DEFINED
+#include <boost/test/unit_test.hpp>
+#include <boost/test/unit_test_monitor.hpp>
+
+#define JASEL_NORETURN
+#ifndef BOOST_TEST
+#define BOOST_TEST(expr) BOOST_CHECK(expr)
+#endif
+#ifndef BOOST_TEST_EQ
+#define BOOST_TEST_EQ(a, b) BOOST_CHECK_EQUAL((a), (b))
+#endif
+#ifndef BOOST_TEST_THROWS
+#define BOOST_TEST_THROWS(expr, ex) BOOST_CHECK_THROW((expr), ex)
+#endif
+#ifndef BOOST_CONSTEXPR
+#define BOOST_CONSTEXPR constexpr
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4127) // conditional expression is constant
+#pragma warning(disable : 4244) // conversion from int to short
+#endif
+
+namespace stde
+{
+#if __cplusplus >= 201700 || _HAS_CXX17
+ using in_place_t = std::in_place_t;
+ using std::in_place;
+#else
+ struct in_place_t
+ {
+ explicit in_place_t() = default;
+ };
+ constexpr in_place_t in_place{};
+#endif
+
+ //! [expected_implementation]
+ /* Here is a fairly conforming implementation of P0323R3 `expected<T, E>` using `checked<T, E>`.
+ It passes the reference test suite for P0323R3 at
+ https://github.com/viboes/std-make/blob/master/test/expected/expected_pass.cpp with modifications
+ only to move the test much closer to the P0323R3 Expected, as the reference test suite is for a
+ much older proposed Expected.
+
+ Known differences from P0323R3 in this implementation:
+ - `T` and `E` cannot be the same type.
+ - No variant storage is implemented.
+ */
+
+ namespace detail
+ {
+ template <class T, class E> using expected_result = BOOST_OUTCOME_V2_NAMESPACE::checked<T, E>;
+ template <class T, class E> struct enable_default_constructor : public expected_result<T, E>
+ {
+ using base = expected_result<T, E>;
+ using base::base;
+ constexpr enable_default_constructor()
+ : base{BOOST_OUTCOME_V2_NAMESPACE::in_place_type<T>}
+ {
+ }
+ };
+ template <class T, class E> using select_expected_base = std::conditional_t<std::is_default_constructible<T>::value, enable_default_constructor<T, E>, expected_result<T, E>>;
+ } // namespace detail
+ template <class T, class E> class expected : public detail::select_expected_base<T, E>
+ {
+ static_assert(!std::is_same<T, E>::value, "T and E cannot be the same in this expected implementation");
+ using base = detail::select_expected_base<T, E>;
+
+ public:
+ // Inherit base's constructors
+ using base::base;
+ expected() = default;
+
+ // Expected takes in_place not in_place_type
+ template <class... Args>
+ constexpr explicit expected(in_place_t /*unused*/, Args &&... args)
+ : base{BOOST_OUTCOME_V2_NAMESPACE::in_place_type<T>, std::forward<Args>(args)...}
+ {
+ }
+
+ // Expected always accepts a T even if ambiguous
+ BOOST_OUTCOME_TEMPLATE(class U)
+ BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(std::is_constructible<T, U>::value))
+ constexpr expected(U &&v) // NOLINT
+ : base{BOOST_OUTCOME_V2_NAMESPACE::in_place_type<T>, std::forward<U>(v)}
+ {
+ }
+
+ // Expected has an emplace() modifier
+ template <class... Args> void emplace(Args &&... args) { *static_cast<base *>(this) = base{BOOST_OUTCOME_V2_NAMESPACE::in_place_type<T>, std::forward<Args>(args)...}; }
+
+ // Expected has a narrow operator* and operator->
+ constexpr const T &operator*() const & { return base::assume_value(); }
+ constexpr T &operator*() & { return base::assume_value(); }
+ constexpr const T &&operator*() const && { return base::assume_value(); }
+ constexpr T &&operator*() && { return base::assume_value(); }
+ constexpr const T *operator->() const { return &base::assume_value(); }
+ constexpr T *operator->() { return &base::assume_value(); }
+
+ // Expected has a narrow error() observer
+ constexpr const E &error() const & { return base::assume_error(); }
+ constexpr E &error() & { return base::assume_error(); }
+ constexpr const E &&error() const && { return base::assume_error(); }
+ constexpr E &error() && { return base::assume_error(); }
+ };
+ template <class E> class expected<void, E> : public BOOST_OUTCOME_V2_NAMESPACE::result<void, E, BOOST_OUTCOME_V2_NAMESPACE::policy::throw_bad_result_access<E, void>>
+ {
+ using base = BOOST_OUTCOME_V2_NAMESPACE::result<void, E, BOOST_OUTCOME_V2_NAMESPACE::policy::throw_bad_result_access<E, void>>;
+
+ public:
+ // Inherit base constructors
+ using base::base;
+
+ // Expected has a narrow operator* and operator->
+ constexpr void operator*() const { base::assume_value(); }
+ constexpr void operator->() const { base::assume_value(); }
+ };
+ template <class E> using unexpected = BOOST_OUTCOME_V2_NAMESPACE::failure_type<E>;
+ template <class E> unexpected<E> make_unexpected(E &&arg) { return BOOST_OUTCOME_V2_NAMESPACE::failure<E>(std::forward<E>(arg)); }
+ template <class E, class... Args> unexpected<E> make_unexpected(Args &&... args) { return BOOST_OUTCOME_V2_NAMESPACE::failure<E>(std::forward<Args>(args)...); }
+ template <class E> using bad_expected_access = BOOST_OUTCOME_V2_NAMESPACE::bad_result_access_with<E>;
+ //! [expected_implementation]
+
+ // Not actually part of the Expected proposal, but needed to pass the test
+ template <typename T> using exception_or = expected<T, std::exception_ptr>;
+} // namespace stde
+
+template <class T> using expected_sc = stde::expected<T, std::error_code>;
+
+struct NoDefaultConstructible
+{
+ NoDefaultConstructible() = delete;
+ NoDefaultConstructible(int /*unused*/) {} // NOLINT
+};
+
+struct NoCopyConstructible
+{
+ NoCopyConstructible() = default;
+ NoCopyConstructible(NoCopyConstructible const &) = delete;
+ NoCopyConstructible(NoCopyConstructible &&) noexcept = default;
+};
+struct NoMoveConstructible
+{
+ NoMoveConstructible() = default;
+ NoMoveConstructible(NoMoveConstructible const &) noexcept = default;
+ NoMoveConstructible(NoMoveConstructible &&) = delete;
+ NoMoveConstructible &operator=(NoMoveConstructible const &) noexcept = default;
+ NoMoveConstructible &operator=(NoMoveConstructible &&) = delete;
+};
+
+enum State
+{
+ sDefaultConstructed,
+ sValueCopyConstructed,
+ sValueMoveConstructed,
+ sCopyConstructed,
+ sMoveConstructed,
+ sMoveAssigned,
+ sCopyAssigned,
+ sValueCopyAssigned,
+ sValueMoveAssigned,
+ sMovedFrom,
+ sValueConstructed
+};
+
+struct OracleVal
+{
+ State s{sValueConstructed};
+ int i;
+ constexpr OracleVal(int i_ = 0) // NOLINT
+ : i(i_)
+ {
+ }
+};
+
+struct Oracle
+{
+ State s{sDefaultConstructed};
+ OracleVal val;
+
+ Oracle() = default;
+ Oracle(const OracleVal &v) // NOLINT
+ : s(sValueCopyConstructed),
+ val(v)
+ {
+ }
+ Oracle(OracleVal &&v) noexcept : s(sValueMoveConstructed), val(v) { v.s = sMovedFrom; } // NOLINT
+ Oracle(const Oracle &o)
+ : s(sCopyConstructed)
+ , val(o.val)
+ {
+ }
+ Oracle(Oracle &&o) noexcept : s(sMoveConstructed), val(std::move(o.val)) { o.s = sMovedFrom; } // NOLINT
+
+ Oracle &operator=(const OracleVal &v)
+ {
+ s = sValueCopyConstructed;
+ val = v;
+ return *this;
+ }
+ Oracle &operator=(OracleVal &&v) noexcept
+ {
+ s = sValueMoveConstructed;
+ val = std::move(v); // NOLINT
+ v.s = sMovedFrom;
+ return *this;
+ }
+ Oracle &operator=(const Oracle &o)
+ {
+ s = sCopyConstructed;
+ val = o.val;
+ return *this;
+ }
+ Oracle &operator=(Oracle &&o) noexcept
+ {
+ s = sMoveConstructed;
+ val = std::move(o.val); // NOLINT
+ o.s = sMovedFrom;
+ return *this;
+ }
+};
+
+struct Guard
+{
+ std::string val;
+ Guard() = default;
+ explicit Guard(std::string s, int /*unused*/ = 0)
+ : val(std::move(s))
+ {
+ }
+ Guard(const Guard &) = delete;
+ Guard(Guard &&) = delete;
+ void operator=(const Guard &) = delete;
+ void operator=(Guard &&) = delete;
+};
+
+struct ExplicitStr
+{
+ std::string s;
+ explicit ExplicitStr(const char *chp)
+ : s(chp)
+ {
+ }
+};
+
+struct Date
+{
+ int i;
+ Date() = delete;
+ Date(int i_) noexcept : i{i_} {} // NOLINT
+ Date(Date &&d) noexcept : i(d.i) { d.i = 0; }
+ Date(const Date &) = delete;
+ Date &operator=(const Date &) = delete;
+ Date &operator=(Date &&d) noexcept
+ {
+ i = d.i;
+ d.i = 0;
+ return *this;
+ }
+};
+
+struct TExcept
+{
+ int i;
+ TExcept() = delete;
+ TExcept(int i_) // NOLINT
+ : i{i_}
+ {
+ }
+ TExcept(TExcept &&d)
+ : i(d.i)
+ {
+ d.i = 0;
+ }
+ TExcept(const TExcept &) = delete;
+ TExcept &operator=(const TExcept &) = delete;
+ TExcept &operator=(TExcept &&d)
+ {
+ i = d.i;
+ d.i = 0;
+ return *this;
+ }
+};
+
+template <class T> struct MoveAware
+{
+ T val;
+ bool moved;
+ MoveAware(T val_) // NOLINT
+ : val(val_),
+ moved(false)
+ {
+ }
+ MoveAware(MoveAware const &) = delete;
+ MoveAware(MoveAware &&rhs)
+ : val(rhs.val)
+ , moved(rhs.moved)
+ {
+ rhs.moved = true;
+ }
+ MoveAware &operator=(MoveAware const &) = delete;
+ MoveAware &operator=(MoveAware &&rhs)
+ {
+ val = (rhs.val);
+ moved = (rhs.moved);
+ rhs.moved = true;
+ return *this;
+ }
+};
+
+struct OverloadedAddressOf
+{
+ OverloadedAddressOf() = default;
+ OverloadedAddressOf *operator&() const { return nullptr; }
+};
+
+// using namespace boost;
+// using namespace boost::functional;
+
+class test_exception : public std::exception
+{
+};
+
+int throwing_fun()
+{
+ throw test_exception();
+}
+int nothrowing_fun()
+{
+ return 4;
+}
+
+JASEL_NORETURN void void_throwing_fun()
+{
+ throw test_exception();
+}
+void do_nothing_fun()
+{
+}
+
+void except_default_constructor()
+{
+ // From value constructor.
+ expected_sc<int> e{};
+ try
+ {
+ int i = e.value();
+ (void) i;
+ BOOST_TEST(true);
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ };
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(e);
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+
+void except_default_constructor_error_code()
+{
+ // From value constructor.
+ stde::expected<int, std::error_code> e;
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(e);
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+void except_default_constructor_constexpr()
+{
+ // From value constructor.
+ BOOST_CONSTEXPR stde::expected<int, long> e;
+ BOOST_TEST(e.has_value());
+}
+
+void expected_from_value()
+{
+ // using T = int;
+ using E = std::error_code;
+
+ // static_assert(noexcept(stde::adl::swap_impl(std::declval<T &>(), std::declval<T &>())), "");
+ static_assert(std::is_nothrow_copy_constructible<E>::value, "");
+ // static_assert(noexcept(stde::adl::swap_impl(std::declval<E &>(), std::declval<E &>())), "");
+
+ static_assert(std::is_nothrow_copy_constructible<expected_sc<int>>::value, "");
+ static_assert(std::is_nothrow_copy_assignable<expected_sc<int>>::value, "");
+ static_assert(std::is_nothrow_move_constructible<expected_sc<int>>::value, "");
+ static_assert(std::is_nothrow_move_assignable<expected_sc<int>>::value, "");
+
+ // From value constructor.
+ expected_sc<int> e(5);
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), 5);
+ BOOST_TEST_EQ(*e, 5);
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+void expected_from_value2()
+{
+ // From value constructor.
+ expected_sc<int> e(5);
+ e = {};
+ BOOST_TEST(e.has_value());
+ BOOST_TEST_EQ(e.value(), 0);
+}
+
+void expected_from_cnv_value()
+{
+ OracleVal v;
+ expected_sc<Oracle> e(v);
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST(!!e);
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(bool(e));
+ BOOST_TEST_EQ(e.value().s, sValueCopyConstructed);
+ BOOST_TEST_EQ(v.s, sValueConstructed);
+
+ expected_sc<Oracle> e2(std::move(v)); // NOLINT
+ // BOOST_REQUIRE_NO_THROW(e2.value());
+ BOOST_TEST(!!e2);
+ BOOST_TEST(e2.has_value());
+ BOOST_TEST(bool(e2));
+ BOOST_TEST_EQ(e2.value().s, sValueMoveConstructed);
+ BOOST_TEST_EQ(v.s, sMovedFrom);
+}
+
+struct NDCE // no default constructor
+{ // (no default date exists)
+ explicit NDCE(int /*unused*/) {}
+};
+
+void except_constructor_NDCE()
+{
+ expected_sc<NDCE> e{NDCE{1}};
+ BOOST_TEST(e.has_value());
+}
+struct NDC // no default constructor
+{ // (no default date exists)
+ NDC(int /*unused*/) {} // NOLINT
+};
+
+void except_constructor_NDC()
+{
+ static_assert(std::is_nothrow_copy_constructible<expected_sc<NDC>>::value, "");
+ static_assert(std::is_nothrow_copy_assignable<expected_sc<NDC>>::value, "");
+ static_assert(std::is_nothrow_move_constructible<expected_sc<NDC>>::value, "");
+ static_assert(std::is_nothrow_move_assignable<expected_sc<NDC>>::value, "");
+ expected_sc<NDC> e{1};
+ BOOST_TEST(e.has_value());
+}
+
+void except_constructor_Date()
+{
+ static_assert(std::is_nothrow_move_constructible<expected_sc<Date>>::value, "");
+ static_assert(std::is_nothrow_move_assignable<expected_sc<Date>>::value, "");
+ expected_sc<Date> e{Date{1}};
+ BOOST_TEST(e.has_value());
+}
+
+void except_constructor_TExcept()
+{
+ static_assert(!std::is_nothrow_move_constructible<expected_sc<TExcept>>::value, "");
+ static_assert(!std::is_nothrow_move_assignable<expected_sc<TExcept>>::value, "");
+ expected_sc<TExcept> e{TExcept{1}};
+ BOOST_TEST(e.has_value());
+}
+
+void expected_from_in_place_value()
+{
+ OracleVal v;
+ expected_sc<Oracle> e{stde::in_place, v};
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST(!!e);
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(bool(e));
+ BOOST_TEST_EQ(e.value().s, sValueCopyConstructed);
+ BOOST_TEST_EQ(v.s, sValueConstructed);
+
+ expected_sc<Oracle> e2{stde::in_place, std::move(v)}; // NOLINT
+ // BOOST_REQUIRE_NO_THROW(e2.value());
+ BOOST_TEST(!!e2);
+ BOOST_TEST(e2.has_value());
+ BOOST_TEST(bool(e2));
+ BOOST_TEST_EQ(e2.value().s, sValueMoveConstructed);
+ BOOST_TEST_EQ(v.s, sMovedFrom);
+}
+
+#if 0
+void expected_from_exception()
+{
+ // From stde::unexpected constructor.
+ stde::exception_or<int> e(stde::make_unexpected(test_exception()));
+ BOOST_TEST_THROWS(e.value(), test_exception);
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+}
+#endif
+
+void expected_from_copy_value()
+{
+ // From copy constructor.
+ expected_sc<int> ef(5);
+ expected_sc<int> e(ef);
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), 5);
+ BOOST_TEST_EQ(*e, 5);
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+#if 0
+void expected_from_copy_exception()
+{
+ // From stde::unexpected constructor.
+ stde::exception_or<int> ef(stde::make_unexpected(test_exception()));
+ stde::exception_or<int> e(ef);
+ BOOST_TEST_THROWS(e.value(), test_exception);
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+}
+#endif
+
+void expected_from_in_place()
+{
+ // From stde::in_place constructor.
+ expected_sc<std::string> e(stde::in_place, "stde::in_place");
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), "stde::in_place");
+ BOOST_TEST_EQ(*e, "stde::in_place");
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+#if 0
+void expected_from_exception_ptr()
+{
+ // From exception_ptr constructor.
+ stde::exception_or<int> e(stde::make_unexpected(std::make_exception_ptr(test_exception())));
+ BOOST_TEST_THROWS(e.value(), test_exception);
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+}
+#endif
+
+void expected_from_moved_value()
+{
+ // From move value constructor.
+ std::string value = "my value";
+ expected_sc<std::string> e = std::move(value);
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), "my value");
+ BOOST_TEST_EQ(*e, "my value");
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+void expected_from_catch_block()
+{
+ // From catch block
+ try
+ {
+ throw test_exception();
+ }
+ catch(...)
+ {
+ stde::exception_or<int> e(stde::make_unexpected(std::current_exception()));
+
+ BOOST_TEST_THROWS(e.value(), std::exception);
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+ }
+}
+
+
+void make_expected_E_from_value()
+{
+ // auto e = stde::make_expected<std::string>( 5 );
+ // BOOST_TEST_EQ(e.has_value(), false);
+}
+void make_expected_const_from_value()
+{
+#if defined __clang__ && __clang_major__ >= 4 && __cplusplus > 201402L
+ const int i = 0;
+ auto e = expected_sc<const int>(i);
+ (void) e;
+// static_assert(std::is_same<decltype(e), stde::success<const int>>::value, "");
+#endif
+}
+void make_expected_from_U_value()
+{
+ expected_sc<int> e = expected_sc<int>(short(5));
+ static_assert(std::is_same<decltype(e), expected_sc<int>>{}, "");
+ BOOST_TEST_EQ(e.has_value(), true);
+}
+void make_expected_from_U_value2()
+{
+ expected_sc<std::string> e = expected_sc<std::string>("aa");
+ static_assert(std::is_same<decltype(e), expected_sc<std::string>>{}, "");
+ BOOST_TEST_EQ(e.has_value(), true);
+}
+
+void expected_from_value_error_condition()
+{
+ // From value constructor.
+ stde::expected<int, std::error_condition> e(5);
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), 5);
+ BOOST_TEST_EQ(*e, 5);
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+void expected_from_error_error_condition()
+{
+ // From stde::unexpected constructor.
+ stde::expected<int, std::error_condition> e(stde::make_unexpected<std::error_condition>(std::make_error_condition(std::errc::invalid_argument)));
+ auto error_from_except_check = [](const stde::bad_expected_access<std::error_condition> &except) { return std::errc(except.error().value()) == std::errc::invalid_argument; };
+ try
+ {
+ (void) e.value();
+ }
+ catch(stde::bad_expected_access<std::error_condition> &ex)
+ {
+ BOOST_TEST(error_from_except_check(ex));
+ }
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+}
+
+
+void expected_from_error_convertible()
+{
+ {
+ stde::expected<int, short> e1 = stde::make_unexpected<short>(1);
+ stde::expected<int, long> e2(e1);
+ BOOST_TEST_EQ(e2.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e2), false);
+ BOOST_TEST_EQ(e2.error(), 1);
+ }
+ {
+ stde::expected<void, short> e1 = stde::make_unexpected<short>(1);
+ stde::expected<void, int> e2(e1);
+ BOOST_TEST_EQ(e2.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e2), false);
+ BOOST_TEST_EQ(e2.error(), 1);
+ }
+}
+
+void except_valid_constexpr_int()
+{
+ // From value constructor.
+ BOOST_CONSTEXPR stde::expected<int, long> e;
+ BOOST_CONSTEXPR bool b = e.has_value();
+ BOOST_TEST(b);
+}
+void except_value_constexpr_int()
+{
+ // From value constructor.
+ BOOST_CONSTEXPR stde::expected<int, long> e(1);
+ BOOST_CONSTEXPR int x = e.value();
+ BOOST_TEST_EQ(x, 1);
+}
+
+void expected_from_value3()
+{
+ expected_sc<int> e(5);
+ BOOST_TEST_EQ(e.value(), 5);
+
+ // From value assignment.
+ e = 8;
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), 8);
+ BOOST_TEST_EQ(*e, 8);
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+void expected_from_copy_expected()
+{
+ expected_sc<int> e(5);
+ expected_sc<int> e2(8);
+
+ // From value assignment.
+ e = e2;
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), 8);
+ BOOST_TEST_EQ(*e, 8);
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+void expected_from_moved_expected()
+{
+ expected_sc<std::string> e("e");
+ expected_sc<std::string> e2("e2");
+
+ // From value assignment.
+ e = std::move(e2);
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), "e2");
+ BOOST_TEST_EQ(*e, "e2");
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+
+// BOOST_REQUIRE_NO_THROW(e2.value());
+#ifndef __GLIBBOOST_OUTCOME_C__
+ BOOST_TEST_EQ(e2.value(), "");
+ BOOST_TEST_EQ(*e2, "");
+#endif
+ BOOST_TEST(e2.has_value());
+ BOOST_TEST(static_cast<bool>(e2));
+}
+
+void expected_from_in_place2()
+{
+ // From stde::in_place constructor.
+ expected_sc<std::string> e(stde::in_place, "stde::in_place");
+ BOOST_TEST_EQ(e.value(), "stde::in_place");
+
+ // From emplace method.
+ e.emplace("emplace method");
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), "emplace method");
+ BOOST_TEST_EQ(*e, "emplace method");
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+void expected_from_move_value()
+{
+ expected_sc<std::string> e("v");
+
+ std::string value = "my value";
+ // From assignment operator.
+ e = std::move(value);
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), "my value");
+ BOOST_TEST_EQ(*e, "my value");
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+
+void expected_from_in_place3()
+{
+ // From stde::in_place factory.
+ // auto e = stde::make_expected<std::string>("stde::in_place");
+ auto e = expected_sc<std::string>("stde::in_place");
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), "stde::in_place");
+ BOOST_TEST_EQ(*e, "stde::in_place");
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+void expected_from_in_place_error()
+{
+ // From stde::in_place factory.
+ auto e = stde::expected<std::string, std::error_condition>("stde::in_place");
+ // BOOST_REQUIRE_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.value(), "stde::in_place");
+ BOOST_TEST_EQ(*e, "stde::in_place");
+ BOOST_TEST(e.has_value());
+ BOOST_TEST(static_cast<bool>(e));
+}
+
+void expected_from_exception_catch()
+{
+ // From catch block
+ try
+ {
+ throw test_exception();
+ }
+ catch(...)
+ {
+ stde::exception_or<int> e = stde::make_unexpected(std::current_exception());
+
+ BOOST_TEST_THROWS(e.value(), std::exception);
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+ }
+}
+
+#if 0
+void expected_from_error()
+{
+ // From stde::unexpected constructor.
+ auto e = stde::make_expected_from_error<int>(std::make_error_condition(std::errc::invalid_argument));
+ auto error_from_except_check = [](const stde::bad_expected_access<std::error_condition> &except) { return std::errc(except.error().value()) == std::errc::invalid_argument; };
+ try
+ {
+ (void) e.value();
+ }
+ catch(stde::bad_expected_access<std::error_condition> &ex)
+ {
+ BOOST_TEST(error_from_except_check(ex));
+ }
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+}
+
+void expected_from_error_U()
+{
+ // From stde::unexpected constructor.
+ auto e = stde::make_expected_from_error<int, short>(42);
+ static_assert(std::is_same<decltype(e), stde::expected<int, short>>{}, "");
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+}
+
+void expected_from_exception2()
+{
+ // From stde::unexpected constructor.
+ auto e = stde::make_expected_from_exception<int>(test_exception());
+ // auto e = expected_sc<int>(stde::unexpected<>(test_exception()));
+ BOOST_TEST_THROWS(e.value(), test_exception );
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+}
+
+void expected_from_exception_ptr2()
+{
+ // From exception_ptr constructor.
+ auto e = stde::exception_or<int>(stde::make_unexpected(test_exception()));
+ BOOST_TEST_THROWS(e.value(), test_exception );
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+}
+
+void make_expected_from_call_fun()
+{
+ try
+ {
+ stde::make_expected_from_call(throwing_fun);
+ BOOST_TEST(true);
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ }
+ stde::exception_or<int> e = stde::make_expected_from_call(throwing_fun);
+ BOOST_TEST_THROWS(e.value(), std::exception );
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+
+ e = stde::make_expected_from_call(nothrowing_fun);
+ try
+ {
+ (void) e.value();
+ BOOST_TEST(true);
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST_EQ(e.value(), 4);
+ BOOST_TEST_EQ(*e, 4);
+ BOOST_TEST_EQ(e.has_value(), true);
+ BOOST_TEST_EQ(static_cast<bool>(e), true);
+
+#if 0
+ BOOST_TEST_THROWS(stde::make_expected_from_call<std::error_condition>(throwing_fun), test_exception);
+
+ BOOST_TEST_NO_THROW(stde::make_expected_from_call<std::error_condition>(nothrowing_fun));
+ stde::expected<int, std::error_condition> e2 = stde::make_expected_from_call<std::error_condition>(nothrowing_fun);
+ BOOST_TEST_NO_THROW(e2.value());
+ BOOST_TEST_EQ(e2.value(), 4);
+ BOOST_TEST_EQ(*e2, 4);
+ BOOST_TEST_EQ(e2.has_value(), true);
+ BOOST_TEST_EQ(static_cast<bool>(e2), true);
+#endif
+}
+
+void make_expected_from_call_void_fun()
+{
+#if 0
+ BOOST_TEST_NO_THROW(stde::make_expected_from_call(void_throwing_fun));
+ expected_sc<void> e = stde::make_expected_from_call(void_throwing_fun);
+ BOOST_TEST_THROWS(e.value(), std::exception);
+ BOOST_TEST_EQ(e.has_value(), false);
+ BOOST_TEST_EQ(static_cast<bool>(e), false);
+
+ e = stde::make_expected_from_call(do_nothing_fun);
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(e.has_value(), true);
+ BOOST_TEST_EQ(static_cast<bool>(e), true);
+
+ BOOST_TEST_THROWS(stde::make_expected_from_call<std::error_condition>(void_throwing_fun), test_exception);
+
+ try {
+ stde::make_expected_from_call<std::error_condition>(do_nothing_fun);
+ BOOST_TEST(true);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ stde::expected<void, std::error_condition> e2 = stde::make_expected_from_call<std::error_condition>(do_nothing_fun);
+ try {
+ (void)e2.value();
+ BOOST_TEST(true);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ //BOOST_TEST_NO_THROW(e2.value());
+ BOOST_TEST_EQ(e2.has_value(), true);
+ BOOST_TEST_EQ(static_cast<bool>(e2), true);
+#endif
+}
+#endif
+
+void expected_swap_value()
+{
+ // From value constructor.
+ expected_sc<int> e(5);
+ expected_sc<int> e2(8);
+
+ e.swap(e2);
+
+ BOOST_TEST_EQ(e.value(), 8);
+ BOOST_TEST_EQ(e2.value(), 5);
+
+ e2.swap(e);
+
+ BOOST_TEST_EQ(e.value(), 5);
+ BOOST_TEST_EQ(e2.value(), 8);
+}
+
+#if 0
+void expected_swap_exception()
+{
+ // From value constructor.
+ stde::exception_or<int> e = stde::make_unexpected(std::invalid_argument("e"));
+ stde::exception_or<int> e2 = stde::make_unexpected(std::invalid_argument("e2"));
+
+ e.swap(e2);
+
+ auto equal_to_e = [](const std::invalid_argument &except) { return std::string(except.what()) == "e"; };
+ auto equal_to_e2 = [](const std::invalid_argument &except) { return std::string(except.what()) == "e2"; };
+
+ try
+ {
+ (void) e.value();
+ BOOST_TEST(true);
+ }
+ catch(std::invalid_argument &ex)
+ {
+ BOOST_TEST(equal_to_e2(ex));
+ }
+ try
+ {
+ (void) e2.value();
+ BOOST_TEST(true);
+ }
+ catch(std::invalid_argument &ex)
+ {
+ BOOST_TEST(equal_to_e(ex));
+ }
+
+ e2.swap(e);
+
+ try
+ {
+ (void) e.value();
+ BOOST_TEST(true);
+ }
+ catch(std::invalid_argument &ex)
+ {
+ BOOST_TEST(equal_to_e(ex));
+ }
+ try
+ {
+ (void) e2.value();
+ BOOST_TEST(true);
+ }
+ catch(std::invalid_argument &ex)
+ {
+ BOOST_TEST(equal_to_e2(ex));
+ }
+}
+#endif
+
+void expected_swap_function_value()
+{
+ // From value constructor.
+ expected_sc<int> e(5);
+ expected_sc<int> e2(8);
+
+ swap(e, e2);
+
+ BOOST_TEST_EQ(e.value(), 8);
+ BOOST_TEST_EQ(e2.value(), 5);
+
+ swap(e, e2);
+
+ BOOST_TEST_EQ(e.value(), 5);
+ BOOST_TEST_EQ(e2.value(), 8);
+}
+
+
+#ifdef QUICKCPPLIB_BOOST_UNIT_TEST_HPP
+int main()
+#else
+BOOST_AUTO_TEST_CASE(expected_pass)
+#endif
+{
+
+ static_assert(!std::is_default_constructible<NoDefaultConstructible>::value, "");
+ static_assert(!std::is_default_constructible<expected_sc<NoDefaultConstructible>>::value, "");
+
+ static_assert(!std::is_copy_constructible<NoCopyConstructible>::value, "");
+ static_assert(!std::is_constructible<expected_sc<NoCopyConstructible>, NoCopyConstructible const &>::value, "");
+ static_assert(!std::is_constructible<stde::exception_or<NoCopyConstructible>, stde::exception_or<NoCopyConstructible> const &>::value, "");
+ static_assert(!std::is_copy_constructible<stde::exception_or<NoCopyConstructible>>::value, "");
+
+#if 0
+ // fixme
+ {
+ NoMoveConstructible nmc;
+ // NoMoveConstructible nmc2 = std::move(nmc); // FAILS as expected
+
+ expected_sc<NoMoveConstructible> x{std::move(nmc)}; // DOESN'T FAIL as copy is selected instead
+ (void) x;
+ }
+// fixme
+#if defined __clang__ && __clang_major__ >= 4 && __cplusplus > 201402L
+ {
+ NoMoveConstructible nmc;
+ // NoMoveConstructible nmc2 = std::move(nmc); // FAILS as expected
+
+ expected_sc<NoMoveConstructible> x = std::move(nmc); // DOESN'T FAIL as copy is selected instead
+ (void) x;
+ }
+#endif
+#endif
+
+ static_assert(!std::is_move_constructible<NoMoveConstructible>::value, "");
+ static_assert(!std::is_constructible<expected_sc<NoMoveConstructible>, NoMoveConstructible &&>::value, "");
+ static_assert(std::is_move_constructible<expected_sc<NoMoveConstructible>>::value, "");
+
+ except_default_constructor();
+ except_default_constructor_error_code();
+ except_default_constructor_constexpr();
+ expected_from_value();
+ expected_from_value2();
+ expected_from_cnv_value();
+ except_constructor_NDCE();
+ except_constructor_NDC();
+ except_constructor_Date();
+ expected_from_in_place_value();
+ // expected_from_exception();
+ expected_from_copy_value();
+ // expected_from_copy_exception();
+ expected_from_in_place();
+ // expected_from_exception_ptr();
+ expected_from_moved_value();
+ expected_from_catch_block();
+ make_expected_E_from_value();
+ make_expected_const_from_value();
+ make_expected_from_U_value2();
+ expected_from_value_error_condition();
+ expected_from_error_error_condition();
+ expected_from_error_convertible();
+ except_valid_constexpr_int();
+ except_value_constexpr_int();
+ expected_from_value3();
+ expected_from_copy_expected();
+ expected_from_moved_expected();
+ expected_from_in_place2();
+ expected_from_move_value();
+ expected_from_in_place3();
+ expected_from_in_place_error();
+ expected_from_exception_catch();
+ // expected_from_error();
+ // expected_from_error_U();
+ // expected_from_exception2();
+ // expected_from_exception_ptr2();
+ // make_expected_from_call_fun();
+ // make_expected_from_call_void_fun();
+ expected_swap_value();
+ // expected_swap_exception();
+ expected_swap_function_value();
+
+#ifdef QUICKCPPLIB_BOOST_UNIT_TEST_HPP
+ return QUICKCPPLIB_NAMESPACE::unit_test::current_test_case()->fails != 0;
+#endif
+}
+
+#if 0
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+
+//void expected_from_error_catch_exception)
+//{
+// // From catch block
+// try
+// {
+// throw test_exception();
+// }
+// catch(...)
+// {
+// auto throw_lambda = [](){ return stde::make_expected_from_error<int,std::error_condition>();};
+//
+// //BOOST_TEST_THROWS(throw_lambda(), test_exception);
+// }
+//}
+
+
+
+////////////////////////////////////
+BOOST_AUTO_TEST_SUITE(expected_map)
+
+void expected_map()
+{
+ auto fun = [](bool b) -> expected_sc<int>
+ {
+ if (b)
+ return stde::make_expected(5);
+ else
+ return stde::make_unexpected(test_exception());
+ };
+
+ auto add_five = [](int sum) -> int
+ {
+ return sum + 5;
+ };
+
+ auto launch_except = [](int sum) -> int
+ {
+ throw test_exception();
+ };
+
+ expected_sc<int> e = fun(true).map(add_five);
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(*e, 10);
+
+ e = fun(true).map(add_five).map(add_five);
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(*e, 15);
+
+ e = fun(false).map(add_five).map(add_five);
+ BOOST_TEST_THROWS(e.value(), test_exception);
+
+ BOOST_TEST_THROWS(fun(true).map(launch_except), test_exception);
+
+}
+
+void expected_void_map()
+{
+ auto fun = [](bool b)
+ {
+ if (b)
+ return stde::make_expected();
+ else
+ return expected_sc<void>(stde::make_unexpected(test_exception()));
+ };
+
+ auto launch_except = []() -> void
+ {
+ throw test_exception();
+ };
+
+ auto do_nothing = []() {};
+
+ expected_sc<void> e = fun(true).map(do_nothing);
+ BOOST_TEST_NO_THROW(e.value());
+
+ e = fun(false).map(do_nothing);
+ BOOST_TEST_THROWS(e.value(), test_exception);
+
+ BOOST_TEST_THROWS(fun(true).map(launch_except), test_exception);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+////////////////////////////////////
+BOOST_AUTO_TEST_SUITE(expected_bind)
+
+void expected_bind()
+{
+ auto fun = [](bool b) -> expected_sc<int>
+ {
+ if (b)
+ return stde::make_expected(5);
+ else
+ return stde::make_unexpected(test_exception());
+ };
+
+ auto add_five = [](int sum) -> expected_sc<int>
+ {
+ return stde::make_expected(sum + 5);
+ };
+
+ auto launch_except = [](int sum) -> expected_sc<int>
+ {
+ throw test_exception();
+ };
+
+ expected_sc<int> e = fun(true).bind(add_five);
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(*e, 10);
+
+ e = fun(true).bind(add_five).bind(add_five);
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(*e, 15);
+
+ e = fun(false).bind(add_five).bind(add_five);
+ BOOST_TEST_THROWS(e.value(), test_exception);
+
+ BOOST_TEST_THROWS(fun(true).bind(launch_except), test_exception);
+
+}
+
+void expected_void_bind()
+{
+ auto fun = [](bool b)
+ {
+ if (b)
+ return stde::make_expected();
+ else
+ return expected_sc<void>(stde::make_unexpected(test_exception()));
+ };
+
+ auto launch_except = []() -> expected_sc<void>
+ {
+ throw test_exception();
+ };
+
+ auto do_nothing = []() {
+ return stde::make_expected();
+ };
+
+ expected_sc<void> e = fun(true).bind(do_nothing);
+ BOOST_TEST_NO_THROW(e.value());
+
+ e = fun(false).bind(do_nothing);
+ BOOST_TEST_THROWS(e.value(), test_exception);
+
+ BOOST_TEST_THROWS(fun(true).bind(launch_except), test_exception);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
+////////////////////////////////////
+BOOST_AUTO_TEST_SUITE(expected_then)
+
+void expected_non_void_then()
+{
+ auto fun = [](bool b) -> expected_sc<int>
+ {
+ if (b)
+ return stde::make_expected(5);
+ else
+ return stde::make_unexpected(test_exception());
+ };
+
+
+ auto add_five = [](int sum) -> int
+ {
+ return sum + 5;
+ };
+ auto six = []() -> int
+ {
+ return 6;
+ };
+
+ auto pair = [](int a) -> bool
+ {
+ return (a % 2) == 0;
+ };
+
+ auto launch_except = [](int sum) -> int
+ {
+ throw test_exception();
+ };
+
+ auto then_launch_except = [](expected<int>) -> int
+ {
+ throw test_exception();
+ };
+
+ expected_sc<int> e = fun(true).then(if_valued(add_five));
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(*e, 10);
+
+ e = fun(true).then(if_valued(ident(six)));
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(*e, 6);
+
+ e = fun(false).then(if_unexpected(ident(six)));
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(*e, 6);
+
+ expected_sc<bool> e1 = fun(true).then(if_valued(pair));
+ BOOST_TEST_NO_THROW(e1.value());
+ BOOST_TEST_EQ(*e1, false);
+
+
+
+ e = fun(true).then(if_valued(add_five)).then(if_valued(add_five));
+ BOOST_TEST_NO_THROW(e.value());
+ BOOST_TEST_EQ(*e, 15);
+
+ e = fun(false).then(if_valued(add_five)).then(if_valued(add_five));
+ BOOST_TEST_THROWS(e.value(), test_exception);
+
+ BOOST_TEST_THROWS(fun(true).then(if_valued(launch_except)), test_exception);
+
+ e = fun(false).then(catch_all(then_launch_except));
+ BOOST_TEST_THROWS(e.value(), test_exception);
+
+}
+
+void expected_void_then()
+{
+ auto fun = [](bool b) -> expected_sc<void>
+ {
+ if (b)
+ return stde::make_expected();
+ else
+ return stde::make_unexpected(test_exception());
+ };
+
+ auto launch_except = []()
+ {
+ throw test_exception();
+ };
+
+ auto do_nothing = []() {};
+
+ BOOST_TEST(true);
+ expected_sc<void> e = fun(true).then(if_valued(do_nothing));
+ BOOST_TEST_NO_THROW(e.value());
+
+ e = fun(false).then(if_valued(do_nothing));
+ BOOST_TEST_THROWS(e.value(), test_exception);
+
+ BOOST_TEST_THROWS(fun(true).then(if_valued(launch_except)), test_exception);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_SUITE(expected_recover)
+
+void expected_recover()
+{
+ auto fun = [](bool b)
+ {
+ if (b)
+ return expected_sc<int>(5);
+ else
+ return expected_sc<int>(stde::make_unexpected(test_exception()));
+ };
+
+ auto add_five = [](int sum) -> expected_sc<int>
+ {
+ return stde::make_expected(sum + 5);
+ };
+
+ auto recover_error = [](std::exception_ptr p)
+ {
+ return stde::make_expected(0);
+ };
+
+ auto recover_error_silent_failure = [](std::exception_ptr p)
+ {
+ return expected_sc<int>(stde::make_unexpected(p));
+ };
+
+ auto recover_error_failure = [](std::exception_ptr p) -> expected_sc<int>
+ {
+ return expected_sc<int>(stde::make_unexpected(test_exception()));
+ };
+
+ auto recover_error_throws = [](std::exception_ptr p) -> expected_sc<int>
+ {
+ throw test_exception();
+ };
+
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error).has_value(), true);
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error).value(), 0);
+ BOOST_TEST_EQ(fun(true).catch_error(recover_error).value(), 5);
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error_silent_failure).has_value(), false);
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error_failure).has_value(), false);
+
+ BOOST_TEST_EQ(fun(true).bind(add_five).value(), 10);
+ BOOST_TEST_EQ(fun(true).bind(add_five).catch_error(recover_error).value(), 10);
+ BOOST_TEST_EQ(fun(true).bind(add_five).catch_error(recover_error_silent_failure).value(), 10);
+ BOOST_TEST_EQ(fun(true).bind(add_five).catch_error(recover_error_failure).value(), 10);
+
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error).bind(add_five).value(), 5);
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error).bind(add_five).bind(add_five).value(), 10);
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error_failure).bind(add_five).has_value(), false);
+ BOOST_TEST_EQ(fun(false).bind(add_five).catch_error(recover_error_failure).bind(add_five).has_value(), false);
+ BOOST_TEST_EQ(fun(false).bind(add_five).catch_error(recover_error_silent_failure).bind(add_five).has_value(), false);
+
+ BOOST_TEST_THROWS(fun(false).catch_error(recover_error_throws), test_exception);
+
+}
+
+void expected_void_recover()
+{
+ auto fun = [](bool b)
+ {
+ if (b)
+ return stde::make_expected();
+ else
+ return expected_sc<void>(boost::stde::make_unexpected(test_exception()));
+ };
+
+ auto do_nothing = []() {
+ return stde::make_expected();
+ };
+
+ auto recover_error = [](std::exception_ptr p)
+ {
+ return stde::make_expected();
+ };
+
+ auto recover_error_silent_failure = [](std::exception_ptr p)
+ {
+ return expected_sc<void>(boost::stde::make_unexpected(p));
+ };
+
+ auto recover_error_failure = [](std::exception_ptr p) -> expected_sc<void>
+ {
+ throw test_exception();
+ };
+
+ // The catch_error doesn't alter the stde::expected if it's valid.
+ BOOST_TEST_EQ(fun(true).catch_error(recover_error_failure).has_value(), true);
+
+ // Simple catch_error tests.
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error).has_value(), true);
+ BOOST_TEST_THROWS(fun(false).catch_error(recover_error_failure), test_exception);
+ BOOST_TEST_EQ(fun(false).catch_error(recover_error_silent_failure).has_value(), false);
+
+ // With a bind between.
+ BOOST_TEST_THROWS(fun(false).bind(do_nothing).catch_error(recover_error_failure), test_exception);
+
+}
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_SUITE(proposal)
+
+void proposal_concept()
+{
+ using namespace std;
+
+ {
+ stde::expected<int, string> ei = 0;
+ stde::expected<int, string> ej = 1;
+ stde::expected<int, string> ek = stde::make_unexpected(string());
+
+ ei = 1;
+ ej = stde::make_unexpected(string());;
+ ek = 0;
+
+ ei = stde::make_unexpected(string());;
+ ej = 0;
+ ek = 1;
+ }
+}
+void proposal_init()
+{
+ using namespace std;
+ {
+ string s{ "STR" };
+
+ stde::expected<string, int> ep{ stde::make_unexpected(-1) }; // unexpected value, requires Movable<E>
+ stde::expected<string, int> eq = { stde::make_unexpected(-1) }; // unexpected value, requires Movable<E>
+
+ expected_sc<string> es{ s }; // requires Copyable<T>
+ expected_sc<string> et = s; // requires Copyable<T>
+ expected_sc<string> ev = string{ "STR" }; // requires Movable<T>
+
+ expected_sc<string> ew; // unexpected value
+ expected_sc<string> ex{}; // unexpected value
+ expected_sc<string> ey = {}; // unexpected value
+ expected_sc<string> ez = expected_sc<string>{}; // unexpected value
+ }
+
+ {
+ stde::expected<Guard, int> eg; // unexpected value
+ stde::expected<Guard, int> eh{}; // unexpected value
+ stde::expected<Guard, int> ei{ stde::in_place }; // calls Guard{} in place
+ stde::expected<Guard, int> ej{ stde::in_place, "arg" }; // calls Guard{"arg"} in place
+ }
+
+ {
+ stde::expected<int, string> ei{ unexpect }; // unexpected value, calls string{} in place
+ stde::expected<int, string> ej{ unexpect, "arg" }; // unexpected value, calls string{"arg"} in place
+ }
+}
+void proposal_make_unexpected_fact()
+{
+ using namespace std;
+ {
+ stde::expected<string, int> opt1 = stde::make_unexpected(1);
+ stde::expected<string, int> opt2 = { unexpect, 1 };
+
+ opt1 = stde::make_unexpected(1);
+ opt2 = { unexpect, 1 };
+ }
+}
+void proposal_error_exception_ts()
+{
+ using namespace std;
+ {
+ stde::expected<int, error_exception<std::error_code, std::system_error> > e =
+ stde::make_unexpected(make_error_code(errc::invalid_argument));
+#if !defined BOOST_MSVC || BOOST_MSVC >= 1900
+ BOOST_TEST(e.error() == make_error_code(errc::invalid_argument));
+#else
+ // VS2013 doesn't match operator==(boost::error_exception<std::error_code,std::system_error>, std::error_code)
+ BOOST_TEST(e.error() == (error_exception<std::error_code, std::system_error>(make_error_code(errc::invalid_argument))));
+#endif
+ try {
+ e.value();
+ BOOST_TEST(false);
+ }
+ catch (std::system_error const& ex) {
+
+ }
+ catch (...) {
+ BOOST_TEST(false);
+ }
+ stde::expected<int, error_exception<std::error_code, std::system_error> > e2 = stde::make_unexpected(e.error());
+#if !defined BOOST_MSVC || BOOST_MSVC >= 1900
+ BOOST_TEST(e2.error() == make_error_code(errc::invalid_argument));
+#else
+ // VS2013 doesn't match operator==(boost::error_exception<std::error_code,std::system_error>, std::error_code)
+ BOOST_TEST(e2.error() == (error_exception<std::error_code, std::system_error>(make_error_code(errc::invalid_argument))));
+#endif
+ try {
+ e2.value();
+ BOOST_TEST(false);
+ }
+ catch (std::system_error const& ex) {
+
+ }
+ catch (...) {
+ BOOST_TEST(false);
+ }
+
+ }
+}
+void proposal_ensured_read_ts()
+{
+ using namespace std;
+ {
+ ensured_read<int> e = make_ensured_read(1);
+ BOOST_TEST(e == 1);
+ }
+ {
+ ensured_read<int> e = make_ensured_read(1);
+ stde::unexpected<ensured_read<int>> ue1 = stde::make_unexpected(std::move(e));
+ BOOST_TEST(ue1.value() == 1);
+ }
+ // {
+ // stde::make_unexpected(make_ensured_read(1));
+ // // calls to terminate.
+ // }
+ // {
+ // stde::expected<int, ensured_read<int> > e = stde::make_unexpected(make_ensured_read(1));
+ // // calls to terminate.
+ // }
+ {
+ stde::expected<int, ensured_read<int> > e{ 1 };
+ BOOST_TEST(e.value() == 1);
+ }
+ {
+ stde::expected<int, ensured_read<int> > e = stde::make_unexpected(make_ensured_read(1));
+ BOOST_TEST(e.error() == 1);
+ }
+ {
+ stde::expected<int, ensured_read<int> > e{ unexpect, 1 };
+ BOOST_TEST(e.error() == 1);
+ }
+ {
+ ensured_read<std::exception_ptr> e = make_ensured_read(std::make_exception_ptr(1));
+ BOOST_TEST_THROWS(std::rethrow_exception(e.value()), int);
+ }
+ {
+ stde::expected<int, ensured_read<std::exception_ptr> > e = stde::make_unexpected(make_ensured_read(std::make_exception_ptr(1)));
+ BOOST_TEST_THROWS(std::rethrow_exception(e.error().value()), int);
+ }
+}
+void proposal_relational_operators()
+{
+ using namespace std;
+ {
+ stde::expected<unsigned, int> e0{ 0 };
+ stde::expected<unsigned, int> e1{ 1 };
+ stde::expected<unsigned, int> eN{ unexpect, -1 };
+
+ BOOST_TEST(eN < e0);
+ BOOST_TEST(e0 < e1);
+ BOOST_TEST(!(e0 < eN));
+ BOOST_TEST(eN <= e0);
+ BOOST_TEST(e0 <= e1);
+
+ BOOST_TEST(e0 > eN);
+ BOOST_TEST(e1 > e0);
+ BOOST_TEST(e0 >= eN);
+ BOOST_TEST(e1 >= e0);
+
+ BOOST_TEST(!(eN < eN));
+ BOOST_TEST(!(e1 < e1));
+ BOOST_TEST(eN <= eN);
+ BOOST_TEST(e1 <= e1);
+
+ BOOST_TEST(eN != e0);
+ BOOST_TEST(e0 != e1);
+ BOOST_TEST(eN == eN);
+ BOOST_TEST(e0 == e0);
+
+ //////
+
+ BOOST_TEST(eN == stde::make_unexpected(-1));
+ BOOST_TEST(e0 != stde::make_unexpected(1));
+ BOOST_TEST(eN != 1u);
+ BOOST_TEST(e1 == 1u);
+
+ BOOST_TEST(eN < 1u);
+ BOOST_TEST(eN <= 1u);
+ BOOST_TEST(1u > eN);
+ BOOST_TEST(!(1u < eN));
+ BOOST_TEST(1u >= eN);
+ BOOST_TEST(stde::make_unexpected(1) < e0);
+ BOOST_TEST(stde::make_unexpected(1) <= e0);
+ BOOST_TEST(!(stde::make_unexpected(1) > e0));
+ BOOST_TEST(!(stde::make_unexpected(1) >= e0));
+
+
+ BOOST_TEST(!(e0 < stde::make_unexpected(1)));
+ BOOST_TEST(!(e0 <= stde::make_unexpected(1)));
+ BOOST_TEST(e0 > stde::make_unexpected(1));
+ BOOST_TEST(e0 >= stde::make_unexpected(1));
+ }
+ {
+ stde::expected<void, int> e0{ boost::expect };
+ stde::expected<void, int> eN{ unexpect, -1 };
+
+ BOOST_TEST(!(e0 < e0));
+ BOOST_TEST(eN < e0);
+ BOOST_TEST(!(e0 < eN));
+ BOOST_TEST(!(eN < eN));
+ BOOST_TEST(e0 <= e0);
+ BOOST_TEST(eN <= e0);
+ BOOST_TEST(!(e0 <= eN));
+ BOOST_TEST(eN <= eN);
+
+ BOOST_TEST(!(e0 > e0));
+ BOOST_TEST(e0 > eN);
+ BOOST_TEST(!(eN > e0));
+ BOOST_TEST(!(eN > eN));
+ BOOST_TEST(e0 >= e0);
+ BOOST_TEST(e0 >= eN);
+ BOOST_TEST(!(eN >= e0));
+ BOOST_TEST(eN >= eN);
+
+ BOOST_TEST(!(e0 != e0));
+ BOOST_TEST(eN != e0);
+ BOOST_TEST(e0 != eN);
+ BOOST_TEST(!(eN != eN));
+ BOOST_TEST(e0 == e0);
+ BOOST_TEST(!(eN == e0));
+ BOOST_TEST(!(e0 == eN));
+ BOOST_TEST(eN == eN);
+
+ //////
+
+ BOOST_TEST(eN == stde::make_unexpected(-1));
+ BOOST_TEST(e0 != stde::make_unexpected(1));
+
+ BOOST_TEST(stde::make_unexpected(1) < e0);
+ BOOST_TEST(stde::make_unexpected(1) <= e0);
+ BOOST_TEST(!(stde::make_unexpected(1) > e0));
+ BOOST_TEST(!(stde::make_unexpected(1) >= e0));
+
+ BOOST_TEST(!(stde::make_unexpected(1) < eN));
+ BOOST_TEST(!(stde::make_unexpected(1) <= eN));
+ BOOST_TEST(stde::make_unexpected(1) > eN);
+ BOOST_TEST(stde::make_unexpected(1) >= eN);
+
+ BOOST_TEST(!(eN < stde::make_unexpected(-1)));
+ BOOST_TEST(eN <= stde::make_unexpected(-1));
+ BOOST_TEST(!(eN > stde::make_unexpected(-1)));
+ BOOST_TEST(eN >= stde::make_unexpected(-1));
+ }
+}
+void proposal_dereference_operators()
+{
+ using namespace std;
+ {
+ const string s{ "STR" };
+
+ expected_sc<string> e0{ s };
+ const expected_sc<string> e1{ s };
+ BOOST_TEST(*e0.operator->() == s);
+ BOOST_TEST(*e1.operator->() == s);
+
+ // Test with class which has operator&() overloaded
+ const OverloadedAddressOf o{};
+ BOOST_TEST(&o == nullptr);
+
+ expected_sc<OverloadedAddressOf> e2{ o };
+ const expected_sc<OverloadedAddressOf> e3{ o };
+ BOOST_TEST(e2.operator->() != nullptr);
+ BOOST_TEST(e3.operator->() != nullptr);
+ }
+}
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_SUITE(movesem)
+//////////////////////////////
+void movesem_moved_from_state()
+{
+ // first, test mock:
+ MoveAware<int> i{ 1 }, j{ 2 };
+ BOOST_TEST(i.val == 1);
+ BOOST_TEST(!i.moved);
+ BOOST_TEST(j.val == 2);
+ BOOST_TEST(!j.moved);
+
+ MoveAware<int> k = std::move(i);
+ BOOST_TEST(k.val == 1);
+ BOOST_TEST(!k.moved);
+ BOOST_TEST(i.val == 1);
+ BOOST_TEST(i.moved);
+
+ k = std::move(j);
+ BOOST_TEST(k.val == 2);
+ BOOST_TEST(!k.moved);
+ BOOST_TEST(j.val == 2);
+ BOOST_TEST(j.moved);
+
+ // now, test stde::expected
+ expected_sc<MoveAware<int>> oi{ 1 }, oj{ 2 };
+ BOOST_TEST(oi);
+ BOOST_TEST(!oi->moved);
+ BOOST_TEST(oj);
+ BOOST_TEST(!oj->moved);
+
+ expected_sc<MoveAware<int>> ok{ std::move(oi) };
+ BOOST_TEST(ok);
+ BOOST_TEST(!ok->moved);
+ BOOST_TEST(oi);
+ BOOST_TEST(oi->moved);
+
+ ok = std::move(oj);
+ BOOST_TEST(ok);
+ BOOST_TEST(!ok->moved);
+ BOOST_TEST(oj);
+ BOOST_TEST(oj->moved);
+
+}
+void movesem_move_only_value()
+{
+ const auto make_int = []() {
+ std::unique_ptr<int> value{ new int };
+ *value = 100;
+ return value;
+ };
+ const auto return_void = [](std::unique_ptr<int> value) {
+ BOOST_TEST(value != nullptr);
+ BOOST_TEST(*value == 100);
+ };
+ const auto return_expected = [](std::unique_ptr<int> value) {
+ BOOST_TEST(value != nullptr);
+ BOOST_TEST(*value == 100);
+ return expected_sc<void>{boost::expect};
+ };
+ const auto return_int = [](std::unique_ptr<int> value) {
+ BOOST_TEST(value != nullptr);
+ BOOST_TEST(*value == 100);
+ return 200;
+ };
+
+ BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.map(return_void));
+ BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.map(return_expected));
+ BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.map(return_int));
+}
+void movesem_move_only_value2()
+{
+ const auto make_int = []() {
+ std::unique_ptr<int> value{ new int };
+ *value = 100;
+ return value;
+ };
+ const auto return_expected_void = [](std::unique_ptr<int> value) {
+ BOOST_TEST(value != nullptr);
+ BOOST_TEST(*value == 100);
+ return stde::make_expected();
+ };
+ const auto return_expected = [](std::unique_ptr<int> value) {
+ BOOST_TEST(value != nullptr);
+ BOOST_TEST(*value == 100);
+ return expected_sc<void>{boost::expect};
+ };
+ BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.bind(return_expected_void));
+ BOOST_TEST(expected<std::unique_ptr<int>>{make_int()}.bind(return_expected));
+}
+void movesem_copy_move_ctor_optional_int()
+{
+ expected_sc<int> oi;
+ expected_sc<int> oj = oi;
+
+ BOOST_TEST(oj);
+ BOOST_TEST(oj == oi);
+ BOOST_TEST(bool(oj));
+
+ oi = 1;
+ expected_sc<int> ok = oi;
+ BOOST_TEST(!!ok);
+ BOOST_TEST(bool(ok));
+ BOOST_TEST(ok == oi);
+ BOOST_TEST(ok != oj);
+ BOOST_TEST(*ok == 1);
+
+ expected_sc<int> ol = std::move(oi);
+ BOOST_TEST(!!ol);
+ BOOST_TEST(bool(ol));
+ BOOST_TEST(ol == oi);
+ BOOST_TEST(ol != oj);
+ BOOST_TEST(*ol == 1);
+}
+void movesem_expected_expected()
+{
+ expected_sc<stde::expected<int, int>> oi1 = stde::make_unexpected(-1);
+ BOOST_TEST(!oi1);
+
+ {
+ expected_sc<expected_sc<int>> oi2{ stde::expect };
+ BOOST_TEST(bool(oi2));
+ BOOST_TEST((*oi2));
+ //std::cout << typeid(**oi2).name() << std::endl;
+ }
+
+ {
+ expected_sc<stde::expected<int, int>> oi2{ stde::expect, stde::make_unexpected(-1) };
+ BOOST_TEST(bool(oi2));
+ BOOST_TEST(!*oi2);
+ }
+
+ {
+ stde::expected<stde::expected<int>> oi2{ stde::expected<int>{} };
+ BOOST_TEST(bool(oi2));
+ BOOST_TEST(*oi2);
+ }
+
+ stde::expected<int> oi;
+ auto ooi = stde::make_expected(oi);
+ static_assert(std::is_same<expected<expected<int>>, decltype(ooi)>::value, "");
+
+}
+BOOST_AUTO_TEST_SUITE_END()
+
+void process() {}
+void process(int) {}
+void processNil() {}
+
+BOOST_AUTO_TEST_SUITE(Examples)
+//////////////////////////////
+
+void example1()
+{
+ stde::expected<int> oi; // create disengaged object
+ stde::expected<int> oj = { unexpect }; // alternative syntax
+ oi = oj; // assign disengaged object
+ stde::expected<int> ok = oj; // ok is disengaged
+
+ if (oi) BOOST_TEST(false); // 'if oi is engaged...'
+ if (!oi) BOOST_TEST(true); // 'if oi is disengaged...'
+
+ BOOST_TEST(oi == ok); // two disengaged optionals compare equal
+
+ ///////////////////////////////////////////////////////////////////////////
+ stde::expected<int> ol{ 1 }; // ol is engaged; its contained value is 1
+ ok = 2; // ok becomes engaged; its contained value is 2
+ oj = ol; // oj becomes engaged; its contained value is 1
+
+ BOOST_TEST(oi != ol); // disengaged != engaged
+ BOOST_TEST(ok != ol); // different contained values
+ BOOST_TEST(oj == ol); // same contained value
+ //BOOST_TEST(oi < ol); // disengaged < engaged
+ //BOOST_TEST(ol < ok); // less by contained value
+
+ /////////////////////////////////////////////////////////////////////////////
+ stde::expected<int> om{ 1 }; // om is engaged; its contained value is 1
+ stde::expected<int> on = om; // on is engaged; its contained value is 1
+ om = 2; // om is engaged; its contained value is 2
+ BOOST_TEST(on != om); // on still contains 3. They are not pointers
+
+ /////////////////////////////////////////////////////////////////////////////
+ int i = *ol; // i obtains the value contained in ol
+ BOOST_TEST(i == 1);
+ *ol = 9; // the object contained in ol becomes 9
+ BOOST_TEST(*ol == 9);
+ BOOST_TEST(ol == stde::make_expected(9));
+
+ ///////////////////////////////////
+ int p = 1;
+ stde::expected<int> op = p;
+ BOOST_TEST(*op == 1);
+ p = 2;
+ BOOST_TEST(*op == 1); // value contained in op is separated from p
+
+ ////////////////////////////////
+ if (ol)
+ process(*ol); // use contained value if present
+ else
+ process(); // proceed without contained value
+
+ if (!om)
+ processNil();
+ else
+ process(*om);
+
+ /////////////////////////////////////////
+ process(ol.value_or(0)); // use 0 if ol is disengaged
+
+ ////////////////////////////////////////////
+ ok = { unexpect }; // if ok was engaged calls T's dtor
+ oj = {}; // assigns a temporary disengaged stde::expected
+}
+//////////////////////////////////////////////////
+void ValueOr()
+{
+ stde::expected<int> oi = 1;
+ int i = oi.value_or(0);
+ BOOST_TEST(i == 1);
+
+ oi = { unexpect };
+ BOOST_TEST(oi.value_or(3) == 3);
+
+ stde::expected<std::string> os{ "AAA" };
+ BOOST_TEST(os.value_or("BBB") == "AAA");
+ os = {};
+ BOOST_TEST(os);
+ BOOST_TEST(os.value() == "");
+
+ BOOST_TEST(os.value_or(std::string("BBB")) == "");
+ {
+ constexpr stde::expected<int> e = 1;
+ static_assert(e.has_value(), "");
+ static_assert(*e == 1, "");
+ static_assert(e.value() == 1, "");
+ }
+ {
+ constexpr std::error_code ec = std::make_error_code(std::errc(1));
+ constexpr stde::expected<int> e = stde::make_unexpected(ec);
+ static_assert(!e.has_value(), "");
+ static_assert(e.error() == ec, "");
+ }
+ {
+ constexpr stde::expected<OracleVal> e = 1;
+ static_assert(e.has_value(), "");
+ static_assert(*e == 1, "");
+ static_assert(e.value() == 1, "");
+ }
+ {
+ constexpr std::error_code ec = std::make_error_code(std::errc(1));
+ constexpr stde::expected<OracleVal> e = stde::make_unexpected(ec);
+ static_assert(!e.has_value(), "");
+ static_assert(e.error() == ec, "");
+ }
+}
+
+//////////////////////////////////////////////////
+BOOST_AUTO_TEST_SUITE_END()
+
+#endif
+
+#else
+int main(void)
+{
+ return 0;
+}
+#endif
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);
+ }
+}