Skip to content

Commit

Permalink
Merge pull request eclipse-iceoryx#2218 from elfenpiff/iox-2216-defin…
Browse files Browse the repository at this point in the history
…e-copy-assignment-operator-for-expected

iox-eclipse-iceoryx#2216 Implement missing copy assignment operator for expected
  • Loading branch information
elfenpiff authored Mar 11, 2024
2 parents 8ef8ecb + badde0e commit 19184d4
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 10 deletions.
2 changes: 2 additions & 0 deletions doc/website/release-notes/iceoryx-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@
- Wrong memory order in `MpmcLoFFLi` fence synchronization [#2196](https://github.com/eclipse-iceoryx/iceoryx/issues/2196)
- Race condition in `PoshRuntime` during shutdown [#2192](https://github.com/eclipse-iceoryx/iceoryx/issues/2192)
- Fix wrong memory orders in SpscFiFo [#2167](https://github.com/eclipse-iceoryx/iceoryx/issues/2167)
- Implement missing copy assignment for expected [#2216](https://github.com/eclipse-iceoryx/iceoryx/issues/2216)

**Refactoring:**

- Separate module specific errors from `iceoryx_hoofs` [\#1099](https://github.com/eclipse-iceoryx/iceoryx/issues/1099)
Expand Down
126 changes: 126 additions & 0 deletions iceoryx_hoofs/test/moduletests/test_vocabulary_expected.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,132 @@ TEST_F(expected_test, CreateWithErrFreeFunctionByForwardingIsSuccessful)
EXPECT_THAT(sut.error().m_b, Eq(B));
}

TEST_F(expected_test, CopyConstructorWorksWithValueContent)
{
::testing::Test::RecordProperty("TEST_ID", "71ce4717-bf77-47ea-8ed9-3a890b13ce88");
constexpr int VALUE{455171};

expected<int, NonTrivialTestClass> sut = ok(VALUE);
expected<int, NonTrivialTestClass> sut_copy(sut);

ASSERT_THAT(sut.has_value(), Eq(true));
ASSERT_THAT(sut_copy.has_value(), Eq(true));

ASSERT_THAT(sut.value(), Eq(VALUE));
ASSERT_THAT(sut_copy.value(), Eq(VALUE));
}

TEST_F(expected_test, CopyConstructorWorksWithErrorContent)
{
::testing::Test::RecordProperty("TEST_ID", "e0be66c3-05fc-4030-92d0-8ad84111e86f");
constexpr int A{719122};
constexpr int B{700012};

expected<int, NonTrivialTestClass> sut = err<NonTrivialTestClass>(A, B);
expected<int, NonTrivialTestClass> sut_copy(sut);

ASSERT_THAT(sut.has_error(), Eq(true));
ASSERT_THAT(sut_copy.has_error(), Eq(true));

ASSERT_THAT(sut.error().m_a, Eq(A));
ASSERT_THAT(sut.error().m_b, Eq(B));
ASSERT_THAT(sut_copy.error().m_a, Eq(A));
ASSERT_THAT(sut_copy.error().m_b, Eq(B));
}

TEST_F(expected_test, MoveConstructorWorksWithValueContent)
{
::testing::Test::RecordProperty("TEST_ID", "8f188c06-6675-4e9b-bd72-28ea813cb149");
constexpr int VALUE{919155171};

expected<int, NonTrivialTestClass> sut = ok(VALUE);
expected<int, NonTrivialTestClass> sut_move(std::move(sut));

ASSERT_THAT(sut_move.has_value(), Eq(true));
ASSERT_THAT(sut_move.value(), Eq(VALUE));
}

TEST_F(expected_test, MoveConstructorWorksWithErrorContent)
{
::testing::Test::RecordProperty("TEST_ID", "c8eb14d0-fee4-474b-ab9a-33e834a47f19");
constexpr int A{7331};
constexpr int B{73391};

expected<int, NonTrivialTestClass> sut = err<NonTrivialTestClass>(A, B);
expected<int, NonTrivialTestClass> sut_move(std::move(sut));

ASSERT_THAT(sut_move.has_error(), Eq(true));
ASSERT_THAT(sut_move.error().m_a, Eq(A));
ASSERT_THAT(sut_move.error().m_b, Eq(B));
}

TEST_F(expected_test, CopyAssignmentWorksWithValueContent)
{
::testing::Test::RecordProperty("TEST_ID", "e16679e7-91cb-4e3c-869a-bdca338c4963");
constexpr int VALUE{333195171};

expected<int, NonTrivialTestClass> sut = ok(VALUE);
expected<int, NonTrivialTestClass> sut_copy = err<NonTrivialTestClass>(1, 2);

sut_copy = sut;

ASSERT_THAT(sut.has_value(), Eq(true));
ASSERT_THAT(sut_copy.has_value(), Eq(true));

ASSERT_THAT(sut.value(), Eq(VALUE));
ASSERT_THAT(sut_copy.value(), Eq(VALUE));
}

TEST_F(expected_test, CopyAssignmentWorksWithErrorContent)
{
::testing::Test::RecordProperty("TEST_ID", "66db5dea-8543-4ad0-9705-1c23ed316463");
constexpr int A{557331};
constexpr int B{5573391};

expected<int, NonTrivialTestClass> sut = err<NonTrivialTestClass>(A, B);
expected<int, NonTrivialTestClass> sut_copy = ok(1231);

sut_copy = sut;

ASSERT_THAT(sut.has_error(), Eq(true));
ASSERT_THAT(sut_copy.has_error(), Eq(true));

ASSERT_THAT(sut.error().m_a, Eq(A));
ASSERT_THAT(sut.error().m_b, Eq(B));
ASSERT_THAT(sut_copy.error().m_a, Eq(A));
ASSERT_THAT(sut_copy.error().m_b, Eq(B));
}

TEST_F(expected_test, MoveAssignmentWorksWithValueContent)
{
::testing::Test::RecordProperty("TEST_ID", "87ca60fe-7b29-4144-91fe-80ebfed644bd");
constexpr int VALUE{910001};

expected<int, NonTrivialTestClass> sut = ok(VALUE);
expected<int, NonTrivialTestClass> sut_move = err<NonTrivialTestClass>(1, 2);

sut_move = std::move(sut);

ASSERT_THAT(sut_move.has_value(), Eq(true));
ASSERT_THAT(sut_move.value(), Eq(VALUE));
}

TEST_F(expected_test, MoveAssignmentWorksWithErrorContent)
{
::testing::Test::RecordProperty("TEST_ID", "82691fe2-fd18-4b43-b926-e9e67699760e");
constexpr int A{9557431};
constexpr int B{95574391};

expected<int, NonTrivialTestClass> sut = err<NonTrivialTestClass>(A, B);
expected<int, NonTrivialTestClass> sut_move = ok(121);

sut_move = sut;

ASSERT_THAT(sut_move.has_error(), Eq(true));
ASSERT_THAT(sut_move.error().m_a, Eq(A));
ASSERT_THAT(sut_move.error().m_b, Eq(B));
}

TEST_F(expected_test, BoolOperatorReturnsError)
{
::testing::Test::RecordProperty("TEST_ID", "f1e30651-a0e9-4c73-b2bf-57f36fc7eddf");
Expand Down
26 changes: 19 additions & 7 deletions iceoryx_hoofs/vocabulary/include/iox/detail/expected.inl
Original file line number Diff line number Diff line change
Expand Up @@ -23,43 +23,43 @@
namespace iox
{
template <typename T, typename>
detail::ok<void> ok()
inline detail::ok<void> ok()
{
return detail::ok<void>{};
}

template <typename T, typename>
detail::ok<T> ok(const T& value)
inline detail::ok<T> ok(const T& value)
{
return detail::ok<T>{value};
}

template <typename T, typename, typename>
detail::ok<T> ok(T&& value)
inline detail::ok<T> ok(T&& value)
{
return detail::ok<T>{std::forward<T>(value)};
}

template <typename T, typename... Targs, typename>
detail::ok<T> ok(Targs&&... args)
inline detail::ok<T> ok(Targs&&... args)
{
return detail::ok<T>{std::forward<Targs>(args)...};
}

template <typename T>
detail::err<T> err(const T& error)
inline detail::err<T> err(const T& error)
{
return detail::err<T>{error};
}

template <typename T, typename>
detail::err<T> err(T&& error)
inline detail::err<T> err(T&& error)
{
return detail::err<T>{std::forward<T>(error)};
}

template <typename T, typename... Targs>
detail::err<T> err(Targs&&... args)
inline detail::err<T> err(Targs&&... args)
{
return detail::err<T>{std::forward<Targs>(args)...};
}
Expand Down Expand Up @@ -108,6 +108,18 @@ inline expected<ValueType, ErrorType>::expected(unexpect_t, Targs&&... args) noe
{
}

template <typename ValueType, typename ErrorType>
inline expected<ValueType, ErrorType>&
expected<ValueType, ErrorType>::operator=(const expected<ValueType, ErrorType>& rhs) noexcept
{
// AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9, FaultDetection-DeadBranches : False positive. Check needed to avoid self assignment.
if (this != &rhs)
{
m_store = rhs.m_store;
}
return *this;
}

template <typename ValueType, typename ErrorType>
inline expected<ValueType, ErrorType>&
expected<ValueType, ErrorType>::operator=(expected<ValueType, ErrorType>&& rhs) noexcept
Expand Down
3 changes: 0 additions & 3 deletions iceoryx_hoofs/vocabulary/include/iox/expected.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@
#ifndef IOX_HOOFS_VOCABULARY_EXPECTED_HPP
#define IOX_HOOFS_VOCABULARY_EXPECTED_HPP

#include "iox/attributes.hpp"
#include "iox/detail/deprecation_marker.hpp"
#include "iox/detail/expected_helper.hpp"
#include "iox/functional_interface.hpp"
#include "iox/optional.hpp"

#include <utility>

namespace iox
{
template <typename T = void>
Expand Down

0 comments on commit 19184d4

Please sign in to comment.