init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
18
Telegram/ThirdParty/expected/tests/assertions.cpp
vendored
Normal file
18
Telegram/ThirdParty/expected/tests/assertions.cpp
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
#define TL_ASSERT(cond) if (!(cond)) { throw std::runtime_error(std::string("assertion failure")); }
|
||||
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
TEST_CASE("Assertions", "[assertions]") {
|
||||
tl::expected<int,int> o1 = 42;
|
||||
REQUIRE_THROWS_WITH(o1.error(), "assertion failure");
|
||||
|
||||
tl::expected<int,int> o2 {tl::unexpect, 0};
|
||||
REQUIRE_THROWS_WITH(*o2, "assertion failure");
|
||||
|
||||
struct foo { int bar; };
|
||||
tl::expected<struct foo,int> o3 {tl::unexpect, 0};
|
||||
REQUIRE_THROWS_WITH(o3->bar, "assertion failure");
|
||||
}
|
||||
75
Telegram/ThirdParty/expected/tests/assignment.cpp
vendored
Normal file
75
Telegram/ThirdParty/expected/tests/assignment.cpp
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
TEST_CASE("Simple assignment", "[assignment.simple]") {
|
||||
tl::expected<int, int> e1 = 42;
|
||||
tl::expected<int, int> e2 = 17;
|
||||
tl::expected<int, int> e3 = 21;
|
||||
tl::expected<int, int> e4 = tl::make_unexpected(42);
|
||||
tl::expected<int, int> e5 = tl::make_unexpected(17);
|
||||
tl::expected<int, int> e6 = tl::make_unexpected(21);
|
||||
|
||||
e1 = e2;
|
||||
REQUIRE(e1);
|
||||
REQUIRE(*e1 == 17);
|
||||
REQUIRE(e2);
|
||||
REQUIRE(*e2 == 17);
|
||||
|
||||
e1 = std::move(e2);
|
||||
REQUIRE(e1);
|
||||
REQUIRE(*e1 == 17);
|
||||
REQUIRE(e2);
|
||||
REQUIRE(*e2 == 17);
|
||||
|
||||
e1 = 42;
|
||||
REQUIRE(e1);
|
||||
REQUIRE(*e1 == 42);
|
||||
|
||||
auto unex = tl::make_unexpected(12);
|
||||
e1 = unex;
|
||||
REQUIRE(!e1);
|
||||
REQUIRE(e1.error() == 12);
|
||||
|
||||
e1 = tl::make_unexpected(42);
|
||||
REQUIRE(!e1);
|
||||
REQUIRE(e1.error() == 42);
|
||||
|
||||
e1 = e3;
|
||||
REQUIRE(e1);
|
||||
REQUIRE(*e1 == 21);
|
||||
|
||||
e4 = e5;
|
||||
REQUIRE(!e4);
|
||||
REQUIRE(e4.error() == 17);
|
||||
|
||||
e4 = std::move(e6);
|
||||
REQUIRE(!e4);
|
||||
REQUIRE(e4.error() == 21);
|
||||
|
||||
e4 = e1;
|
||||
REQUIRE(e4);
|
||||
REQUIRE(*e4 == 21);
|
||||
}
|
||||
|
||||
TEST_CASE("Assignment deletion", "[assignment.deletion]") {
|
||||
struct has_all {
|
||||
has_all() = default;
|
||||
has_all(const has_all &) = default;
|
||||
has_all(has_all &&) noexcept = default;
|
||||
has_all &operator=(const has_all &) = default;
|
||||
};
|
||||
|
||||
tl::expected<has_all, has_all> e1 = {};
|
||||
tl::expected<has_all, has_all> e2 = {};
|
||||
e1 = e2;
|
||||
|
||||
struct except_move {
|
||||
except_move() = default;
|
||||
except_move(const except_move &) = default;
|
||||
except_move(except_move &&) noexcept(false){};
|
||||
except_move &operator=(const except_move &) = default;
|
||||
};
|
||||
tl::expected<except_move, except_move> e3 = {};
|
||||
tl::expected<except_move, except_move> e4 = {};
|
||||
// e3 = e4; should not compile
|
||||
}
|
||||
191
Telegram/ThirdParty/expected/tests/bases.cpp
vendored
Normal file
191
Telegram/ThirdParty/expected/tests/bases.cpp
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
// Old versions of GCC don't have the correct trait names. Could fix them up if needs be.
|
||||
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
|
||||
!defined(__clang__))
|
||||
// nothing for now
|
||||
#else
|
||||
TEST_CASE("Triviality", "[bases.triviality]") {
|
||||
REQUIRE(std::is_trivially_copy_constructible<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_trivially_copy_assignable<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_constructible<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_assignable<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_trivially_destructible<tl::expected<int,int>>::value);
|
||||
|
||||
REQUIRE(std::is_trivially_copy_constructible<tl::expected<void,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_constructible<tl::expected<void,int>>::value);
|
||||
REQUIRE(std::is_trivially_destructible<tl::expected<void,int>>::value);
|
||||
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&) = default;
|
||||
T(T&&) = default;
|
||||
T& operator=(const T&) = default;
|
||||
T& operator=(T&&) = default;
|
||||
~T() = default;
|
||||
};
|
||||
REQUIRE(std::is_trivially_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_trivially_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_trivially_move_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_trivially_destructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&){}
|
||||
T(T&&) {}
|
||||
T& operator=(const T&) { return *this; }
|
||||
T& operator=(T&&) { return *this; }
|
||||
~T(){}
|
||||
};
|
||||
REQUIRE(!std::is_trivially_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_trivially_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_trivially_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_trivially_move_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_trivially_destructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Deletion", "[bases.deletion]") {
|
||||
REQUIRE(std::is_copy_constructible<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_copy_assignable<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_move_constructible<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_move_assignable<tl::expected<int,int>>::value);
|
||||
REQUIRE(std::is_destructible<tl::expected<int,int>>::value);
|
||||
|
||||
{
|
||||
struct T {
|
||||
T()=default;
|
||||
};
|
||||
REQUIRE(std::is_default_constructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(int){}
|
||||
};
|
||||
REQUIRE(!std::is_default_constructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&) = default;
|
||||
T(T&&) = default;
|
||||
T& operator=(const T&) = default;
|
||||
T& operator=(T&&) = default;
|
||||
~T() = default;
|
||||
};
|
||||
REQUIRE(std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_move_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_destructible<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&)=delete;
|
||||
T(T&&)=delete;
|
||||
T& operator=(const T&)=delete;
|
||||
T& operator=(T&&)=delete;
|
||||
};
|
||||
REQUIRE(!std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_move_assignable<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&)=delete;
|
||||
T(T&&)=default;
|
||||
T& operator=(const T&)=delete;
|
||||
T& operator=(T&&)=default;
|
||||
};
|
||||
REQUIRE(!std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(!std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_move_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_move_assignable<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
struct T {
|
||||
T(const T&)=default;
|
||||
T(T&&)=delete;
|
||||
T& operator=(const T&)=default;
|
||||
T& operator=(T&&)=delete;
|
||||
};
|
||||
REQUIRE(std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||
REQUIRE(std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e;
|
||||
REQUIRE(std::is_default_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_assignable<decltype(e)>::value);
|
||||
REQUIRE(TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
|
||||
REQUIRE(TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
|
||||
# if !defined(TL_EXPECTED_GCC49)
|
||||
REQUIRE(std::is_trivially_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_trivially_move_assignable<decltype(e)>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, std::string> e;
|
||||
REQUIRE(std::is_default_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_assignable<decltype(e)>::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
|
||||
# if !defined(TL_EXPECTED_GCC49)
|
||||
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<std::string, int> e;
|
||||
REQUIRE(std::is_default_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_assignable<decltype(e)>::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
|
||||
# if !defined(TL_EXPECTED_GCC49)
|
||||
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<std::string, std::string> e;
|
||||
REQUIRE(std::is_default_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_assignable<decltype(e)>::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
|
||||
# if !defined(TL_EXPECTED_GCC49)
|
||||
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
6
Telegram/ThirdParty/expected/tests/constexpr.cpp
vendored
Normal file
6
Telegram/ThirdParty/expected/tests/constexpr.cpp
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
TEST_CASE("Constexpr", "[constexpr]") {
|
||||
//TODO
|
||||
}
|
||||
134
Telegram/ThirdParty/expected/tests/constructors.cpp
vendored
Normal file
134
Telegram/ThirdParty/expected/tests/constructors.cpp
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct takes_init_and_variadic {
|
||||
std::vector<int> v;
|
||||
std::tuple<int, int> t;
|
||||
template <class... Args>
|
||||
takes_init_and_variadic(std::initializer_list<int> l, Args &&... args)
|
||||
: v(l), t(std::forward<Args>(args)...) {}
|
||||
};
|
||||
|
||||
TEST_CASE("Constructors", "[constructors]") {
|
||||
{
|
||||
tl::expected<int,int> e;
|
||||
REQUIRE(e);
|
||||
REQUIRE(e == 0);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int,int> e = tl::make_unexpected(0);
|
||||
REQUIRE(!e);
|
||||
REQUIRE(e.error() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int,int> e (tl::unexpect, 0);
|
||||
REQUIRE(!e);
|
||||
REQUIRE(e.error() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int,int> e (tl::in_place, 42);
|
||||
REQUIRE(e);
|
||||
REQUIRE(e == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<std::vector<int>,int> e (tl::in_place, {0,1});
|
||||
REQUIRE(e);
|
||||
REQUIRE((*e)[0] == 0);
|
||||
REQUIRE((*e)[1] == 1);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<std::tuple<int,int>,int> e (tl::in_place, 0, 1);
|
||||
REQUIRE(e);
|
||||
REQUIRE(std::get<0>(*e) == 0);
|
||||
REQUIRE(std::get<1>(*e) == 1);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<takes_init_and_variadic,int> e (tl::in_place, {0,1}, 2, 3);
|
||||
REQUIRE(e);
|
||||
REQUIRE(e->v[0] == 0);
|
||||
REQUIRE(e->v[1] == 1);
|
||||
REQUIRE(std::get<0>(e->t) == 2);
|
||||
REQUIRE(std::get<1>(e->t) == 3);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e;
|
||||
REQUIRE(std::is_default_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_assignable<decltype(e)>::value);
|
||||
REQUIRE(TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
|
||||
REQUIRE(TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
|
||||
# if !defined(TL_EXPECTED_GCC49)
|
||||
REQUIRE(std::is_trivially_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_trivially_move_assignable<decltype(e)>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, std::string> e;
|
||||
REQUIRE(std::is_default_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_assignable<decltype(e)>::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
|
||||
# if !defined(TL_EXPECTED_GCC49)
|
||||
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<std::string, int> e;
|
||||
REQUIRE(std::is_default_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_assignable<decltype(e)>::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
|
||||
# if !defined(TL_EXPECTED_GCC49)
|
||||
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<std::string, std::string> e;
|
||||
REQUIRE(std::is_default_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(std::is_copy_assignable<decltype(e)>::value);
|
||||
REQUIRE(std::is_move_assignable<decltype(e)>::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(decltype(e))::value);
|
||||
REQUIRE(!TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(decltype(e))::value);
|
||||
# if !defined(TL_EXPECTED_GCC49)
|
||||
REQUIRE(!std::is_trivially_move_constructible<decltype(e)>::value);
|
||||
REQUIRE(!std::is_trivially_move_assignable<decltype(e)>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<void,int> e;
|
||||
REQUIRE(e);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<void,int> e (tl::unexpect, 42);
|
||||
REQUIRE(!e);
|
||||
REQUIRE(e.error() == 42);
|
||||
}
|
||||
}
|
||||
50
Telegram/ThirdParty/expected/tests/emplace.cpp
vendored
Normal file
50
Telegram/ThirdParty/expected/tests/emplace.cpp
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
namespace {
|
||||
struct takes_init_and_variadic {
|
||||
std::vector<int> v;
|
||||
std::tuple<int, int> t;
|
||||
template <class... Args>
|
||||
takes_init_and_variadic(std::initializer_list<int> l, Args &&... args)
|
||||
: v(l), t(std::forward<Args>(args)...) {}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("Emplace", "[emplace]") {
|
||||
{
|
||||
tl::expected<std::unique_ptr<int>,int> e;
|
||||
e.emplace(new int{42});
|
||||
REQUIRE(e);
|
||||
REQUIRE(**e == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<std::vector<int>,int> e;
|
||||
e.emplace({0,1});
|
||||
REQUIRE(e);
|
||||
REQUIRE((*e)[0] == 0);
|
||||
REQUIRE((*e)[1] == 1);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<std::tuple<int,int>,int> e;
|
||||
e.emplace(2,3);
|
||||
REQUIRE(e);
|
||||
REQUIRE(std::get<0>(*e) == 2);
|
||||
REQUIRE(std::get<1>(*e) == 3);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<takes_init_and_variadic,int> e = tl::make_unexpected(0);
|
||||
e.emplace({0,1}, 2, 3);
|
||||
REQUIRE(e);
|
||||
REQUIRE(e->v[0] == 0);
|
||||
REQUIRE(e->v[1] == 1);
|
||||
REQUIRE(std::get<0>(e->t) == 2);
|
||||
REQUIRE(std::get<1>(e->t) == 3);
|
||||
}
|
||||
}
|
||||
830
Telegram/ThirdParty/expected/tests/extensions.cpp
vendored
Normal file
830
Telegram/ThirdParty/expected/tests/extensions.cpp
vendored
Normal file
@@ -0,0 +1,830 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
#define TOKENPASTE(x, y) x##y
|
||||
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
|
||||
#undef STATIC_REQUIRE
|
||||
#define STATIC_REQUIRE(e) \
|
||||
constexpr bool TOKENPASTE2(rqure, __LINE__) = e; \
|
||||
(void)TOKENPASTE2(rqure, __LINE__); \
|
||||
REQUIRE(e);
|
||||
|
||||
TEST_CASE("Map extensions", "[extensions.map]") {
|
||||
auto mul2 = [](int a) { return a * 2; };
|
||||
auto ret_void = [](int a) { (void)a; };
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.map(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.map(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).map(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).map(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.map(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.map(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).map(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).map(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.map(ret_void);
|
||||
REQUIRE(ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.map(ret_void);
|
||||
REQUIRE(ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).map(ret_void);
|
||||
REQUIRE(ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).map(ret_void);
|
||||
REQUIRE(ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.map(ret_void);
|
||||
REQUIRE(!ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.map(ret_void);
|
||||
REQUIRE(!ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).map(ret_void);
|
||||
REQUIRE(!ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).map(ret_void);
|
||||
REQUIRE(!ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
|
||||
// mapping functions which return references
|
||||
{
|
||||
tl::expected<int, int> e(42);
|
||||
auto ret = e.map([](int& i) -> int& { return i; });
|
||||
REQUIRE(ret);
|
||||
REQUIRE(ret == 42);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Map error extensions", "[extensions.map_error]") {
|
||||
auto mul2 = [](int a) { return a * 2; };
|
||||
auto ret_void = [](int a) { (void)a; };
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.map_error(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.map_error(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).map_error(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).map_error(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.map_error(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.map_error(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).map_error(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).map_error(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.map_error(ret_void);
|
||||
REQUIRE(ret);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.map_error(ret_void);
|
||||
REQUIRE(ret);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).map_error(ret_void);
|
||||
REQUIRE(ret);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).map_error(ret_void);
|
||||
REQUIRE(ret);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.map_error(ret_void);
|
||||
REQUIRE(!ret);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.map_error(ret_void);
|
||||
REQUIRE(!ret);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).map_error(ret_void);
|
||||
REQUIRE(!ret);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).map_error(ret_void);
|
||||
REQUIRE(!ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("And then extensions", "[extensions.and_then]") {
|
||||
auto succeed = [](int a) { (void)a; return tl::expected<int, int>(21 * 2); };
|
||||
auto fail = [](int a) { (void)a; return tl::expected<int, int>(tl::unexpect, 17); };
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.and_then(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.and_then(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).and_then(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).and_then(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.and_then(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 17);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.and_then(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 17);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).and_then(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 17);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).and_then(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 17);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.and_then(succeed);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.and_then(succeed);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).and_then(succeed);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).and_then(succeed);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.and_then(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.and_then(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).and_then(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).and_then(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("or_else", "[extensions.or_else]") {
|
||||
using eptr = std::unique_ptr<int>;
|
||||
auto succeed = [](int a) { (void)a; return tl::expected<int, int>(21 * 2); };
|
||||
auto succeedptr = [](eptr e) { (void)e; return tl::expected<int,eptr>(21*2);};
|
||||
auto fail = [](int a) { (void)a; return tl::expected<int,int>(tl::unexpect, 17);};
|
||||
auto failptr = [](eptr e) { *e = 17;return tl::expected<int,eptr>(tl::unexpect, std::move(e));};
|
||||
auto failvoid = [](int) {};
|
||||
auto failvoidptr = [](const eptr&) { /* don't consume */};
|
||||
auto consumeptr = [](eptr) {};
|
||||
auto make_u_int = [](int n) { return std::unique_ptr<int>(new int(n));};
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.or_else(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.or_else(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).or_else(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, eptr> e = 21;
|
||||
auto ret = std::move(e).or_else(succeedptr);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).or_else(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.or_else(fail);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.or_else(fail);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).or_else(fail);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(ret == 21);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
tl::expected<int, eptr> e = 21;
|
||||
auto ret = std::move(e).or_else(failptr);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).or_else(fail);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.or_else(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.or_else(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).or_else(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, eptr> e(tl::unexpect, make_u_int(21));
|
||||
auto ret = std::move(e).or_else(succeedptr);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).or_else(succeed);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.or_else(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 17);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.or_else(failvoid);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.or_else(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 17);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.or_else(failvoid);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).or_else(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 17);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).or_else(failvoid);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, eptr> e(tl::unexpect, make_u_int(21));
|
||||
auto ret = std::move(e).or_else(failvoidptr);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(*ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, eptr> e(tl::unexpect, make_u_int(21));
|
||||
auto ret = std::move(e).or_else(consumeptr);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).or_else(fail);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 17);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).or_else(failvoid);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("Transform extensions", "[extensions.tronsfarm]") {
|
||||
auto mul2 = [](int a) { return a * 2; };
|
||||
auto ret_void = [](int a) { (void)a; };
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.transform(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.transform(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).transform(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).transform(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.transform(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.transform(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).transform(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).transform(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.transform(ret_void);
|
||||
REQUIRE(ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.transform(ret_void);
|
||||
REQUIRE(ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).transform(ret_void);
|
||||
REQUIRE(ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).transform(ret_void);
|
||||
REQUIRE(ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.transform(ret_void);
|
||||
REQUIRE(!ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.transform(ret_void);
|
||||
REQUIRE(!ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).transform(ret_void);
|
||||
REQUIRE(!ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).transform(ret_void);
|
||||
REQUIRE(!ret);
|
||||
STATIC_REQUIRE(
|
||||
(std::is_same<decltype(ret), tl::expected<void, int>>::value));
|
||||
}
|
||||
|
||||
|
||||
// mapping functions which return references
|
||||
{
|
||||
tl::expected<int, int> e(42);
|
||||
auto ret = e.transform([](int& i) -> int& { return i; });
|
||||
REQUIRE(ret);
|
||||
REQUIRE(ret == 42);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Transform error extensions", "[extensions.transform_error]") {
|
||||
auto mul2 = [](int a) { return a * 2; };
|
||||
auto ret_void = [](int a) { (void)a; };
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.transform_error(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.transform_error(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).transform_error(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).transform_error(mul2);
|
||||
REQUIRE(ret);
|
||||
REQUIRE(*ret == 21);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.transform_error(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.transform_error(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).transform_error(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 42);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).transform_error(mul2);
|
||||
REQUIRE(!ret);
|
||||
REQUIRE(ret.error() == 42);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = e.transform_error(ret_void);
|
||||
REQUIRE(ret);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = e.transform_error(ret_void);
|
||||
REQUIRE(ret);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).transform_error(ret_void);
|
||||
REQUIRE(ret);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e = 21;
|
||||
auto ret = std::move(e).transform_error(ret_void);
|
||||
REQUIRE(ret);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.transform_error(ret_void);
|
||||
REQUIRE(!ret);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = e.transform_error(ret_void);
|
||||
REQUIRE(!ret);
|
||||
}
|
||||
|
||||
{
|
||||
tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).transform_error(ret_void);
|
||||
REQUIRE(!ret);
|
||||
}
|
||||
|
||||
{
|
||||
const tl::expected<int, int> e(tl::unexpect, 21);
|
||||
auto ret = std::move(e).transform_error(ret_void);
|
||||
REQUIRE(!ret);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
struct F {
|
||||
int x;
|
||||
};
|
||||
|
||||
TEST_CASE("14", "[issue.14]") {
|
||||
auto res = tl::expected<S,F>{tl::unexpect, F{}};
|
||||
|
||||
res.map_error([](F f) {
|
||||
(void)f;
|
||||
});
|
||||
}
|
||||
|
||||
TEST_CASE("32", "[issue.32]") {
|
||||
int i = 0;
|
||||
tl::expected<void, int> a;
|
||||
a.map([&i]{i = 42;});
|
||||
REQUIRE(i == 42);
|
||||
|
||||
auto x = a.map([]{return 42;});
|
||||
REQUIRE(*x == 42);
|
||||
}
|
||||
195
Telegram/ThirdParty/expected/tests/issues.cpp
vendored
Normal file
195
Telegram/ThirdParty/expected/tests/issues.cpp
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
using std::string;
|
||||
|
||||
tl::expected<int, string> getInt3(int val) { return val; }
|
||||
|
||||
tl::expected<int, string> getInt2(int val) { return val; }
|
||||
|
||||
tl::expected<int, string> getInt1() { return getInt2(5).and_then(getInt3); }
|
||||
|
||||
TEST_CASE("Issue 1", "[issues.1]") { getInt1(); }
|
||||
|
||||
tl::expected<int, int> operation1() { return 42; }
|
||||
|
||||
tl::expected<std::string, int> operation2(int const val) { (void)val; return "Bananas"; }
|
||||
|
||||
TEST_CASE("Issue 17", "[issues.17]") {
|
||||
auto const intermediate_result = operation1();
|
||||
|
||||
intermediate_result.and_then(operation2);
|
||||
}
|
||||
|
||||
struct a {};
|
||||
struct b : a {};
|
||||
|
||||
auto doit() -> tl::expected<std::unique_ptr<b>, int> {
|
||||
return tl::make_unexpected(0);
|
||||
}
|
||||
|
||||
TEST_CASE("Issue 23", "[issues.23]") {
|
||||
tl::expected<std::unique_ptr<a>, int> msg = doit();
|
||||
REQUIRE(!msg.has_value());
|
||||
}
|
||||
|
||||
TEST_CASE("Issue 26", "[issues.26]") {
|
||||
tl::expected<a, int> exp = tl::expected<b, int>(tl::unexpect, 0);
|
||||
REQUIRE(!exp.has_value());
|
||||
}
|
||||
|
||||
struct foo {
|
||||
foo() = default;
|
||||
foo(foo &) = delete;
|
||||
foo(foo &&){};
|
||||
};
|
||||
|
||||
TEST_CASE("Issue 29", "[issues.29]") {
|
||||
std::vector<foo> v;
|
||||
v.emplace_back();
|
||||
tl::expected<std::vector<foo>, int> ov = std::move(v);
|
||||
REQUIRE(ov->size() == 1);
|
||||
}
|
||||
|
||||
tl::expected<int, std::string> error() {
|
||||
return tl::make_unexpected(std::string("error1 "));
|
||||
}
|
||||
std::string maperror(std::string s) { return s + "maperror "; }
|
||||
|
||||
TEST_CASE("Issue 30", "[issues.30]") {
|
||||
error().map_error(maperror);
|
||||
}
|
||||
|
||||
struct i31{
|
||||
int i;
|
||||
};
|
||||
TEST_CASE("Issue 31", "[issues.31]") {
|
||||
const tl::expected<i31, int> a = i31{42};
|
||||
(void)a->i;
|
||||
|
||||
tl::expected< void, std::string > result;
|
||||
tl::expected< void, std::string > result2 = result;
|
||||
result2 = result;
|
||||
}
|
||||
|
||||
TEST_CASE("Issue 33", "[issues.33]") {
|
||||
tl::expected<void, int> res {tl::unexpect, 0};
|
||||
REQUIRE(!res);
|
||||
res = res.map_error([](int i) { (void)i; return 42; });
|
||||
REQUIRE(res.error() == 42);
|
||||
}
|
||||
|
||||
|
||||
tl::expected<void, std::string> voidWork() { return {}; }
|
||||
tl::expected<int, std::string> work2() { return 42; }
|
||||
void errorhandling(std::string){}
|
||||
|
||||
TEST_CASE("Issue 34", "[issues.34]") {
|
||||
tl::expected <int, std::string> result = voidWork ()
|
||||
.and_then (work2);
|
||||
result.map_error ([&] (std::string result) {errorhandling (result);});
|
||||
}
|
||||
|
||||
struct non_copyable {
|
||||
non_copyable(non_copyable&&) = default;
|
||||
non_copyable(non_copyable const&) = delete;
|
||||
non_copyable() = default;
|
||||
};
|
||||
|
||||
TEST_CASE("Issue 42", "[issues.42]") {
|
||||
tl::expected<non_copyable,int>{}.map([](non_copyable) {});
|
||||
}
|
||||
|
||||
TEST_CASE("Issue 43", "[issues.43]") {
|
||||
auto result = tl::expected<void, std::string>{};
|
||||
result = tl::make_unexpected(std::string{ "foo" });
|
||||
}
|
||||
|
||||
#if !(__GNUC__ <= 5)
|
||||
#include <memory>
|
||||
|
||||
using MaybeDataPtr = tl::expected<int, std::unique_ptr<int>>;
|
||||
|
||||
MaybeDataPtr test(int i) noexcept
|
||||
{
|
||||
return std::move(i);
|
||||
}
|
||||
|
||||
MaybeDataPtr test2(int i) noexcept
|
||||
{
|
||||
return std::move(i);
|
||||
}
|
||||
|
||||
TEST_CASE("Issue 49", "[issues.49]") {
|
||||
auto m = test(10)
|
||||
.and_then(test2);
|
||||
}
|
||||
#endif
|
||||
|
||||
tl::expected<int, std::unique_ptr<std::string>> func()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST_CASE("Issue 61", "[issues.61]") {
|
||||
REQUIRE(func().value() == 1);
|
||||
}
|
||||
|
||||
struct move_tracker {
|
||||
int moved = 0;
|
||||
|
||||
move_tracker() = default;
|
||||
|
||||
move_tracker(move_tracker const &other) noexcept {};
|
||||
move_tracker(move_tracker &&orig) noexcept
|
||||
: moved(orig.moved + 1) {}
|
||||
|
||||
move_tracker &
|
||||
operator=(move_tracker const &other) noexcept {};
|
||||
|
||||
move_tracker &operator=(move_tracker &&orig) noexcept {
|
||||
moved = orig.moved + 1;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CASE("Issue 122", "[issues.122]") {
|
||||
tl::expected<move_tracker, int> res;
|
||||
res.emplace();
|
||||
REQUIRE(res.value().moved == 0);
|
||||
}
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
TEST_CASE("Issue 89", "[issues.89]") {
|
||||
auto s = tl::unexpected("Some string");
|
||||
REQUIRE(s.value() == std::string("Some string"));
|
||||
}
|
||||
#endif
|
||||
|
||||
struct S {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
S(int i) : i(i) {}
|
||||
S(int i, int j) : i(i), j(j) {}
|
||||
};
|
||||
|
||||
TEST_CASE("Issue 107", "[issues.107]") {
|
||||
tl::expected<int, S> ex1(tl::unexpect, 2);
|
||||
tl::expected<int, S> ex2(tl::unexpect, 2, 2);
|
||||
|
||||
REQUIRE(ex1.error().i == 2);
|
||||
REQUIRE(ex1.error().j == 0);
|
||||
REQUIRE(ex2.error().i == 2);
|
||||
REQUIRE(ex2.error().j == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("Issue 129", "[issues.129]") {
|
||||
tl::expected<std::unique_ptr<int>, int> x1 {std::unique_ptr<int>(new int(4))};
|
||||
tl::expected<std::unique_ptr<int>, int> y1 {std::unique_ptr<int>(new int(2))};
|
||||
x1 = std::move(y1);
|
||||
|
||||
REQUIRE(**x1 == 2);
|
||||
}
|
||||
2
Telegram/ThirdParty/expected/tests/main.cpp
vendored
Normal file
2
Telegram/ThirdParty/expected/tests/main.cpp
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch2/catch.hpp>
|
||||
6
Telegram/ThirdParty/expected/tests/noexcept.cpp
vendored
Normal file
6
Telegram/ThirdParty/expected/tests/noexcept.cpp
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
TEST_CASE("Noexcept", "[noexcept]") {
|
||||
//TODO
|
||||
}
|
||||
36
Telegram/ThirdParty/expected/tests/observers.cpp
vendored
Normal file
36
Telegram/ThirdParty/expected/tests/observers.cpp
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
struct move_detector {
|
||||
move_detector() = default;
|
||||
move_detector(move_detector &&rhs) { rhs.been_moved = true; }
|
||||
bool been_moved = false;
|
||||
};
|
||||
|
||||
TEST_CASE("Observers", "[observers]") {
|
||||
tl::expected<int,int> o1 = 42;
|
||||
tl::expected<int,int> o2 {tl::unexpect, 0};
|
||||
const tl::expected<int,int> o3 = 42;
|
||||
|
||||
REQUIRE(*o1 == 42);
|
||||
REQUIRE(*o1 == o1.value());
|
||||
REQUIRE(o2.value_or(42) == 42);
|
||||
REQUIRE(o2.error() == 0);
|
||||
REQUIRE(o3.value() == 42);
|
||||
auto success = std::is_same<decltype(o1.value()), int &>::value;
|
||||
REQUIRE(success);
|
||||
success = std::is_same<decltype(o3.value()), const int &>::value;
|
||||
REQUIRE(success);
|
||||
success = std::is_same<decltype(std::move(o1).value()), int &&>::value;
|
||||
REQUIRE(success);
|
||||
|
||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||
success = std::is_same<decltype(std::move(o3).value()), const int &&>::value;
|
||||
REQUIRE(success);
|
||||
#endif
|
||||
|
||||
tl::expected<move_detector,int> o4{tl::in_place};
|
||||
move_detector o5 = std::move(o4).value();
|
||||
REQUIRE(o4->been_moved);
|
||||
REQUIRE(!o5.been_moved);
|
||||
}
|
||||
17
Telegram/ThirdParty/expected/tests/relops.cpp
vendored
Normal file
17
Telegram/ThirdParty/expected/tests/relops.cpp
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
TEST_CASE("Relational operators", "[relops]") {
|
||||
tl::expected<int, int> o1 = 42;
|
||||
tl::expected<int, int> o2{tl::unexpect, 0};
|
||||
const tl::expected<int, int> o3 = 42;
|
||||
|
||||
REQUIRE(o1 == o1);
|
||||
REQUIRE(o1 != o2);
|
||||
REQUIRE(o1 == o3);
|
||||
REQUIRE(o3 == o3);
|
||||
|
||||
tl::expected<void, int> o6;
|
||||
|
||||
REQUIRE(o6 == o6);
|
||||
}
|
||||
107
Telegram/ThirdParty/expected/tests/swap.cpp
vendored
Normal file
107
Telegram/ThirdParty/expected/tests/swap.cpp
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <tl/expected.hpp>
|
||||
|
||||
struct no_throw {
|
||||
no_throw(std::string i) : i(i) {}
|
||||
std::string i;
|
||||
};
|
||||
struct canthrow_move {
|
||||
canthrow_move(std::string i) : i(i) {}
|
||||
canthrow_move(canthrow_move const &) = default;
|
||||
canthrow_move(canthrow_move &&other) noexcept(false) : i(other.i) {}
|
||||
canthrow_move &operator=(canthrow_move &&) = default;
|
||||
std::string i;
|
||||
};
|
||||
|
||||
bool should_throw = false;
|
||||
|
||||
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
|
||||
struct willthrow_move {
|
||||
willthrow_move(std::string i) : i(i) {}
|
||||
willthrow_move(willthrow_move const &) = default;
|
||||
willthrow_move(willthrow_move &&other) : i(other.i) {
|
||||
if (should_throw)
|
||||
throw 0;
|
||||
}
|
||||
willthrow_move &operator=(willthrow_move &&) = default;
|
||||
std::string i;
|
||||
};
|
||||
#endif // TL_EXPECTED_EXCEPTIONS_ENABLED
|
||||
|
||||
static_assert(tl::detail::is_swappable<no_throw>::value, "");
|
||||
|
||||
template <class T1, class T2> void swap_test() {
|
||||
std::string s1 = "abcdefghijklmnopqrstuvwxyz";
|
||||
std::string s2 = "zyxwvutsrqponmlkjihgfedcba";
|
||||
|
||||
tl::expected<T1, T2> a{s1};
|
||||
tl::expected<T1, T2> b{s2};
|
||||
swap(a, b);
|
||||
REQUIRE(a->i == s2);
|
||||
REQUIRE(b->i == s1);
|
||||
|
||||
a = s1;
|
||||
b = tl::unexpected<T2>(s2);
|
||||
swap(a, b);
|
||||
REQUIRE(a.error().i == s2);
|
||||
REQUIRE(b->i == s1);
|
||||
|
||||
a = tl::unexpected<T2>(s1);
|
||||
b = s2;
|
||||
swap(a, b);
|
||||
REQUIRE(a->i == s2);
|
||||
REQUIRE(b.error().i == s1);
|
||||
|
||||
a = tl::unexpected<T2>(s1);
|
||||
b = tl::unexpected<T2>(s2);
|
||||
swap(a, b);
|
||||
REQUIRE(a.error().i == s2);
|
||||
REQUIRE(b.error().i == s1);
|
||||
|
||||
a = s1;
|
||||
b = s2;
|
||||
a.swap(b);
|
||||
REQUIRE(a->i == s2);
|
||||
REQUIRE(b->i == s1);
|
||||
|
||||
a = s1;
|
||||
b = tl::unexpected<T2>(s2);
|
||||
a.swap(b);
|
||||
REQUIRE(a.error().i == s2);
|
||||
REQUIRE(b->i == s1);
|
||||
|
||||
a = tl::unexpected<T2>(s1);
|
||||
b = s2;
|
||||
a.swap(b);
|
||||
REQUIRE(a->i == s2);
|
||||
REQUIRE(b.error().i == s1);
|
||||
|
||||
a = tl::unexpected<T2>(s1);
|
||||
b = tl::unexpected<T2>(s2);
|
||||
a.swap(b);
|
||||
REQUIRE(a.error().i == s2);
|
||||
REQUIRE(b.error().i == s1);
|
||||
}
|
||||
|
||||
#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
|
||||
TEST_CASE("swap") {
|
||||
|
||||
swap_test<no_throw, no_throw>();
|
||||
swap_test<no_throw, canthrow_move>();
|
||||
swap_test<canthrow_move, no_throw>();
|
||||
|
||||
std::string s1 = "abcdefghijklmnopqrstuvwxyz";
|
||||
std::string s2 = "zyxwvutsrqponmlkjihgfedcbaxxx";
|
||||
tl::expected<no_throw, willthrow_move> a{s1};
|
||||
tl::expected<no_throw, willthrow_move> b{tl::unexpect, s2};
|
||||
should_throw = 1;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//this seems to break catch on GCC and Clang
|
||||
REQUIRE_THROWS(swap(a, b));
|
||||
#endif
|
||||
|
||||
REQUIRE(a->i == s1);
|
||||
REQUIRE(b.error().i == s2);
|
||||
}
|
||||
#endif // TL_EXPECTED_EXCEPTIONS_ENABLED
|
||||
32
Telegram/ThirdParty/expected/tests/test.cpp
vendored
Normal file
32
Telegram/ThirdParty/expected/tests/test.cpp
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
struct no_throw {
|
||||
no_throw(std::string i) : i(i) {}
|
||||
std::string i;
|
||||
};
|
||||
struct canthrow_move {
|
||||
canthrow_move(std::string i) : i(i) {}
|
||||
canthrow_move(canthrow_move const &) = default;
|
||||
canthrow_move(canthrow_move &&other) noexcept(false) : i(other.i) {}
|
||||
canthrow_move &operator=(canthrow_move &&) = default;
|
||||
std::string i;
|
||||
};
|
||||
|
||||
bool should_throw = false;
|
||||
struct willthrow_move {
|
||||
willthrow_move(std::string i) : i(i) {}
|
||||
willthrow_move(willthrow_move const &) = default;
|
||||
willthrow_move(willthrow_move &&other) : i(other.i) {
|
||||
if (should_throw)
|
||||
throw 0;
|
||||
}
|
||||
willthrow_move &operator=(willthrow_move &&) = default;
|
||||
std::string i;
|
||||
};
|
||||
|
||||
int main() {
|
||||
std::string s1 = "abcdefghijklmnopqrstuvwxyz";
|
||||
std::string s2 = "zyxwvutsrqponmlkjihgfedcbaxxx";
|
||||
tl::expected<no_throw, willthrow_move> a{s1};
|
||||
tl::expected<no_throw, willthrow_move> b{tl::unexpect, s2};
|
||||
should_throw = 1;
|
||||
swap(a, b);
|
||||
}
|
||||
Reference in New Issue
Block a user