add: [imp] expected ut

This commit is contained in:
mutouyun 2023-03-05 18:34:53 +08:00
parent 0883929918
commit b75022b4a4
2 changed files with 151 additions and 3 deletions

View File

@ -246,7 +246,8 @@ struct storage : value_getter<storage<T, E>, T, E> {
storage(storage &&other)
: getter_t(std::move(other))
, has_value_(std::exchange(other.has_value_, false)) {}
/// After construction, has_value() is equal to other.has_value().
, has_value_(other.has_value_) {}
template <typename T_, typename E_>
storage(storage<T_, E_> const &other)
@ -256,7 +257,8 @@ struct storage : value_getter<storage<T, E>, T, E> {
template <typename T_, typename E_>
storage(storage<T_, E_> &&other)
: getter_t(std::move(other))
, has_value_(std::exchange(other.has_value_, false)) {}
/// After construction, has_value() is equal to other.has_value().
, has_value_(other.has_value_) {}
bool has_value() const noexcept {
return has_value_;
@ -331,7 +333,7 @@ class expected : public detail_expected::storage<typename std::remove_cv<T>::typ
expected()
: detail_expected::storage<value_type, E>(in_place) {}
expected &operator=(expected other) {
this->swap(other);
return *this;

View File

@ -0,0 +1,146 @@
#include <utility>
#include <cstdio>
#include <cstdint>
#include "gtest/gtest.h"
#include "libimp/expected.h"
namespace {
class test_val {
public:
int val = 0;
int dc_ = 0;
int cc_ = 0;
int mv_ = 0;
test_val() {
dc_ += 1;
std::printf("test_val construct.\n");
}
test_val(test_val const &o)
: val(o.val) {
cc_ = o.cc_ + 1;
std::printf("test_val copy construct.\n");
}
test_val(test_val &&o) noexcept
: val(std::exchange(o.val, 0)) {
mv_ = o.mv_ + 1;
std::printf("test_val move construct.\n");
}
~test_val() {
std::printf("test_val destruct.\n");
}
test_val &operator=(test_val &&o) noexcept {
mv_ = o.mv_ + 1;
val = std::exchange(o.val, 0);
return *this;
}
test_val(int v)
: val(v) {
std::printf("test_val value initialization.\n");
}
bool operator==(test_val const &rhs) const {
return val == rhs.val;
}
};
class test_err {
public:
int dc_ = 0;
int cc_ = 0;
int mv_ = 0;
std::int64_t val = 0;
test_err() {
dc_ += 1;
std::printf("test_err construct.\n");
}
test_err(test_err const &o)
: val(o.val) {
cc_ = o.cc_ + 1;
std::printf("test_err copy construct.\n");
}
test_err(test_err &&o) noexcept
: val(std::exchange(o.val, 0)) {
mv_ = o.mv_ + 1;
std::printf("test_err move construct.\n");
}
~test_err() {
std::printf("test_err destruct.\n");
}
test_err &operator=(test_err &&o) noexcept {
mv_ = o.mv_ + 1;
val = std::exchange(o.val, 0);
return *this;
}
test_err(int v)
: val(v) {
std::printf("test_err value initialization.\n");
}
bool operator==(test_err const &rhs) const {
return val == rhs.val;
}
};
} // namespace
TEST(expected, in_place) {
imp::expected<test_val, test_err> e1;
EXPECT_TRUE(e1);
EXPECT_EQ(e1.value().dc_, 1);
EXPECT_EQ(e1.value().val, 0);
imp::expected<test_val, test_err> e2 {imp::in_place, 123};
EXPECT_TRUE(e2);
EXPECT_EQ(e2.value().dc_, 0);
EXPECT_EQ(e2.value().val, 123);
}
TEST(expected, unexpected) {
imp::expected<test_val, test_err> e1 {imp::unexpected};
EXPECT_FALSE(e1);
EXPECT_EQ(e1.error().dc_, 1);
EXPECT_EQ(e1.error().val, 0);
imp::expected<test_val, test_err> e2 {imp::unexpected, 321};
EXPECT_FALSE(e2);
EXPECT_EQ(e2.error().dc_, 0);
EXPECT_EQ(e2.error().val, 321);
}
TEST(expected, copy_and_move) {
imp::expected<test_val, test_err> e1 {imp::in_place, 123};
imp::expected<test_val, test_err> e2 {e1};
EXPECT_TRUE(e1);
EXPECT_TRUE(e2);
EXPECT_EQ(e1, e2);
EXPECT_EQ(e2.value().cc_, 1);
EXPECT_EQ(e2.value().val, 123);
imp::expected<test_val, test_err> e3 {imp::unexpected, 333};
imp::expected<test_val, test_err> e4 {e3};
EXPECT_FALSE(e3);
EXPECT_FALSE(e4);
EXPECT_EQ(e3, e4);
EXPECT_EQ(e4.error().cc_, 1);
EXPECT_EQ(e4.error().val, 333);
imp::expected<test_val, test_err> e5;
e5 = e1;
EXPECT_EQ(e1, e5);
EXPECT_EQ(e5.value().val, 123);
imp::expected<test_val, test_err> e6;
e6 = std::move(e5);
EXPECT_EQ(e1, e6);
EXPECT_EQ(e5.value().val, 0);
}