Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/website/release-notes/iceoryx-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
- Depend on @ncurses when building with Bazel [#2372](https://github.com/eclipse-iceoryx/iceoryx/issues/2372)
- Fix windows performance issue [#2377](https://github.com/eclipse-iceoryx/iceoryx/issues/2377)
- Max Client and Server cannot be configured independently of Max Publisher and Subscriber [#2394](https://github.com/eclipse-iceoryx/iceoryx/issues/2394)
- Use placement new to construct a new object during assignment [#2414](https://github.com/eclipse-iceoryx/iceoryx/issues/2414)

**Refactoring:**

Expand Down
6 changes: 3 additions & 3 deletions iceoryx_hoofs/test/moduletests/test_vocabulary_variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,13 +467,13 @@ TEST_F(variant_Test, DirectValueAssignmentResultsInCorrectIndex)
EXPECT_THAT(schlomo.index(), Eq(0U));
}

TEST_F(variant_Test, DirectValueAssignmentWhenAlreadyAssignedWithDifferentType)
TEST_F(variant_Test, DirectValueAssignmentWhenAlreadyAssignedWithDifferentTypeResultsInCorrectIndex)
{
::testing::Test::RecordProperty("TEST_ID", "a058c173-497b-43ec-ba03-2702f3ba8190");
::testing::Test::RecordProperty("TEST_ID", "f9f10061-b7f2-4e8f-a4b2-c04478046dcd");
iox::variant<int, float> schlomo;
schlomo = 123;
schlomo = 123.01F;
EXPECT_THAT(schlomo.index(), Eq(0U));
EXPECT_THAT(schlomo.index(), Eq(1U));
}

TEST_F(variant_Test, HoldsAlternativeForCorrectType)
Expand Down
16 changes: 6 additions & 10 deletions iceoryx_hoofs/vocabulary/include/iox/detail/variant.inl
Original file line number Diff line number Diff line change
Expand Up @@ -149,25 +149,21 @@ template <typename T>
inline typename std::enable_if<!std::is_same<T, variant<Types...>&>::value, variant<Types...>>::type&
variant<Types...>::operator=(T&& rhs) noexcept
{
if (m_type_index == INVALID_VARIANT_INDEX)
if (m_type_index != internal::get_index_of_type<0, T, Types...>::index)
{
call_element_destructor();
// NOLINTJUSTIFICATION clang-tidy suggests that std::move(rhs) might erroneously move an lvalue, but here rhs is already T&&, so it's safe.
// NOLINTNEXTLINE(bugprone-move-forwarding-reference)
new (&m_storage) T(std::move(rhs));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuanxingyang Does the suggestion from clang-tidy to use std::forward not work?

Copy link
Author

@yuanxingyang yuanxingyang Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuanxingyang Does the suggestion from clang-tidy to use std::forward not work?

It does not work; the following error occurs during compilation:

`In file included from /home/ynx3sgh/work/projects/iceoryx/iceoryx_hoofs/vocabulary/include/iox/variant.hpp:331,
                 from /home/ynx3sgh/work/projects/iceoryx/iceoryx_hoofs/test/moduletests/test_vocabulary_variant.cpp:18:
/home/ynx3sgh/work/projects/iceoryx/iceoryx_hoofs/vocabulary/include/iox/detail/variant.inl: In instantiation of ‘typename std::enable_if<(! std::is_same<T, iox::variant<Types>&>::value), iox::variant<Types> >::type& iox::variant<Types>::operator=(T&&) [with T = int; Types = {int, float}; typename std::enable_if<(! std::is_same<T, iox::variant<Types>&>::value), iox::variant<Types> >::type = iox::variant<int, float>]’:
/home/ynx3sgh/work/projects/iceoryx/iceoryx_hoofs/test/moduletests/test_vocabulary_variant.cpp:466:15:   required from here
/home/ynx3sgh/work/projects/iceoryx/iceoryx_hoofs/vocabulary/include/iox/detail/variant.inl:157:40: error: no matching function for call to ‘forward(int&)’
  157 |         new (&m_storage) T(std::forward(rhs));
`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuanxingyang move cannot be used in this context. This operator is used for copy assignment and it would be a bug if a complex type would be assigned to a default constructed variant.

Unfortunately, our tests currently do not cover this scenario yet.

m_type_index = internal::get_index_of_type<0, T, Types...>::index;
}

if (!has_bad_variant_element_access<T>())
else
{
// AXIVION Next Construct AutosarC++19_03-M5.2.8: conversion to typed pointer is intentional, it is correctly aligned and points to sufficient memory for a T by design
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto storage = reinterpret_cast<T*>(&m_storage);
*storage = std::forward<T>(rhs);
}
else
{
error_message(__PRETTY_FUNCTION__,
"wrong variant type assignment, another type is already "
"set in variant");
}

return *this;
}

Expand Down
Loading