Skip to content

Commit

Permalink
Add template constructor and assignment
Browse files Browse the repository at this point in the history
Allow copying and assignment from different template types by adding
templated copy constructor and assignment operator.
  • Loading branch information
RauliL committed Jun 12, 2020
1 parent fac702f commit c466a52
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
16 changes: 16 additions & 0 deletions include/peelo/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ namespace peelo
, m_value(that.m_value ? new value_type(*that.m_value) : nullptr)
, m_error(that.m_error ? new error_type(*that.m_error) : nullptr) {}

template<class T2, class E2>
result(const result<T2, E2>& that)
: m_type(!!that ? type::ok : type::error)
, m_value(that.value() ? new value_type(*that.value()) : nullptr)
, m_error(that.error() ? new error_type(*that.error()) : nullptr) {}

result& operator=(const result& that)
{
if (this != &that)
Expand All @@ -71,6 +77,16 @@ namespace peelo
return *this;
}

template<class T2, class E2>
result& operator=(const result<T2, E2>& that)
{
m_type = !!that ? type::ok : type::error;
m_value.reset(that.value() ? new value_type(*that.value()) : nullptr);
m_error.reset(that.error() ? new error_type(*that.error()) : nullptr);

return *this;
}

inline enum type type() const
{
return m_type;
Expand Down
58 changes: 58 additions & 0 deletions test/test_result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,30 @@ static void test_copy_error()
assert(!copy.value());
}

static void test_copy_ok_with_different_types()
{
using result1 = peelo::result<int, error>;
using result2 = peelo::result<double, error>;
const result1 original = result1::ok(5);
const result2 copy(original);

assert(copy.type() == result2::type::ok);
assert(*copy.value() == *original.value());
assert(!copy.error());
}

static void test_copy_error_with_different_types()
{
using result1 = peelo::result<int, error>;
using result2 = peelo::result<double, error>;
const result1 original = result1::error({ 404, "Not Found"});
const result2 copy(original);

assert(copy.type() == result2::type::error);
assert(copy.error()->code == original.error()->code);
assert(!copy.value());
}

static void test_assign_ok()
{
const result ok = result::ok({ 5, "Five" });
Expand All @@ -89,6 +113,36 @@ static void test_assign_error()
assert(r.error()->code == err.error()->code);
}

static void test_assign_ok_with_different_types()
{
using result1 = peelo::result<int, error>;
using result2 = peelo::result<double, error>;
const result1 ok = result1::ok(5);
result2 r = result2::error({ 400, "Bad Request" });

r = ok;

assert(r.type() == result2::type::ok);
assert(bool(r.value()));
assert(!r.error());
assert(*r.value() == *ok.value());
}

static void test_assign_error_with_different_types()
{
using result1 = peelo::result<int, error>;
using result2 = peelo::result<double, error>;
const result1 err = result1::error({ 500, "Internal Server Error" });
result2 r = result2::ok(1);

r = err;

assert(r.type() == result2::type::error);
assert(!r.value());
assert(bool(r.error()));
assert(r.error()->code == err.error()->code);
}

static void test_equals()
{
const auto ok1 = result::ok({ 1, "One" });
Expand All @@ -108,8 +162,12 @@ int main()
test_error();
test_copy_ok();
test_copy_error();
test_copy_ok_with_different_types();
test_copy_error_with_different_types();
test_assign_ok();
test_assign_error();
test_assign_ok_with_different_types();
test_assign_error_with_different_types();
test_equals();

return 0;
Expand Down

0 comments on commit c466a52

Please sign in to comment.