Skip to content

Commit 60008d5

Browse files
committed
iox-eclipse-iceoryx#2414 Use placement new to construct a new object during assignment
1 parent f33d582 commit 60008d5

File tree

3 files changed

+10
-13
lines changed

3 files changed

+10
-13
lines changed

doc/website/release-notes/iceoryx-unreleased.md

+1
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
- Depend on @ncurses when building with Bazel [#2372](https://github.com/eclipse-iceoryx/iceoryx/issues/2372)
149149
- Fix windows performance issue [#2377](https://github.com/eclipse-iceoryx/iceoryx/issues/2377)
150150
- Max Client and Server cannot be configured independently of Max Publisher and Subscriber [#2394](https://github.com/eclipse-iceoryx/iceoryx/issues/2394)
151+
- Use placement new to construct a new object during assignment [#2414](https://github.com/eclipse-iceoryx/iceoryx/issues/2414)
151152

152153
**Refactoring:**
153154

iceoryx_hoofs/test/moduletests/test_vocabulary_variant.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -467,13 +467,13 @@ TEST_F(variant_Test, DirectValueAssignmentResultsInCorrectIndex)
467467
EXPECT_THAT(schlomo.index(), Eq(0U));
468468
}
469469

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

479479
TEST_F(variant_Test, HoldsAlternativeForCorrectType)

iceoryx_hoofs/vocabulary/include/iox/detail/variant.inl

+6-10
Original file line numberDiff line numberDiff line change
@@ -149,25 +149,21 @@ template <typename T>
149149
inline typename std::enable_if<!std::is_same<T, variant<Types...>&>::value, variant<Types...>>::type&
150150
variant<Types...>::operator=(T&& rhs) noexcept
151151
{
152-
if (m_type_index == INVALID_VARIANT_INDEX)
152+
if (m_type_index != internal::get_index_of_type<0, T, Types...>::index)
153153
{
154+
call_element_destructor();
155+
// NOLINTJUSTIFICATION clang-tidy suggests that std::move(rhs) might erroneously move an lvalue, but here rhs is already T&&, so it's safe.
156+
// NOLINTNEXTLINE(bugprone-move-forwarding-reference)
157+
new (&m_storage) T(std::move(rhs));
154158
m_type_index = internal::get_index_of_type<0, T, Types...>::index;
155159
}
156-
157-
if (!has_bad_variant_element_access<T>())
160+
else
158161
{
159162
// 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
160163
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
161164
auto storage = reinterpret_cast<T*>(&m_storage);
162165
*storage = std::forward<T>(rhs);
163166
}
164-
else
165-
{
166-
error_message(__PRETTY_FUNCTION__,
167-
"wrong variant type assignment, another type is already "
168-
"set in variant");
169-
}
170-
171167
return *this;
172168
}
173169

0 commit comments

Comments
 (0)