#include #include #include #include using std::string; m5::stl::expected getInt3(int val) { return val; } m5::stl::expected getInt2(int val) { return val; } m5::stl::expected getInt1() { return getInt2(5).and_then(getInt3); } TEST(Expected, Issue1) { getInt1(); } m5::stl::expected operation1() { return 42; } m5::stl::expected operation2(int const val) { (void)val; return "Bananas"; } TEST(Expected, Issue17) { auto const intermediate_result = operation1(); intermediate_result.and_then(operation2); } struct a { /* empty */ }; struct b : a { /* empty */ }; auto doit() -> m5::stl::expected, int> { return m5::stl::make_unexpected(0); } TEST(Expected, Issue23) { m5::stl::expected, int> msg = doit(); EXPECT_TRUE(!msg.has_value()); } TEST(Expected, Issue26) { m5::stl::expected exp = m5::stl::expected(m5::stl::unexpect, 0); EXPECT_TRUE(!exp.has_value()); } struct foo { foo() = default; foo(const foo &) = delete; foo(foo &&) noexcept {}; }; TEST(Expected, Issue29) { std::vector v; v.emplace_back(); m5::stl::expected, int> ov = std::move(v); EXPECT_TRUE(ov->size() == 1); } m5::stl::expected error() { return m5::stl::make_unexpected(std::string("error1 ")); } std::string maperror(std::string s) { return s + "maperror "; } TEST(Expected, Issue30) { error().map_error(maperror); } struct i31 { int i; }; TEST(Expected, Issue31) { const m5::stl::expected a = i31{42}; (void)a->i; m5::stl::expected result; m5::stl::expected result2 = result; result2 = result; } TEST(Expected, Issue33) { m5::stl::expected res{m5::stl::unexpect, 0}; EXPECT_TRUE(!res); res = res.map_error([](int i) { (void)i; return 42; }); EXPECT_TRUE(res.error() == 42); } m5::stl::expected voidWork() { return {}; } m5::stl::expected work2() { return 42; } void errorhandling(std::string) { } TEST(Expected, Issue34) { m5::stl::expected 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(Expected, Issue42) { m5::stl::expected{}.map([](non_copyable) {}); } TEST(Expected, Issue43) { auto result = m5::stl::expected{}; result = m5::stl::make_unexpected(std::string{"foo"}); } #if !(__GNUC__ <= 5) #include using MaybeDataPtr = m5::stl::expected>; MaybeDataPtr test(int i) noexcept { return std::move(i); } MaybeDataPtr test2(int i) noexcept { return std::move(i); } TEST(Expected, Issue49) { auto m = test(10).and_then(test2); } #endif m5::stl::expected> func() { return 1; } TEST(Expected, Issue61) { EXPECT_TRUE(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 { return *this; } move_tracker &operator=(move_tracker &&orig) noexcept { moved = orig.moved + 1; return *this; } }; TEST(Expected, Issue122) { m5::stl::expected res; res.emplace(); EXPECT_TRUE(res.value().moved == 0); } #ifdef __cpp_deduction_guides TEST(Expected, Issue89) { auto s = m5::stl::unexpected("Some string"); EXPECT_TRUE(s.value() == std::string("Some string")); } #endif namespace { struct SS { int i = 0; int j = 0; SS(int i) : i(i) { } SS(int i, int j) : i(i), j(j) { } }; } // namespace TEST(Expected, Issue107) { m5::stl::expected ex1(m5::stl::unexpect, 2); m5::stl::expected ex2(m5::stl::unexpect, 2, 2); EXPECT_TRUE(ex1.error().i == 2); EXPECT_TRUE(ex1.error().j == 0); EXPECT_TRUE(ex2.error().i == 2); EXPECT_TRUE(ex2.error().j == 2); } TEST(Expected, Issue129) { m5::stl::expected, int> x1{std::unique_ptr(new int(4))}; m5::stl::expected, int> y1{std::unique_ptr(new int(2))}; x1 = std::move(y1); EXPECT_TRUE(**x1 == 2); }