From 7673b3b7c3a19ccdeb6d46d6527fe853d7143114 Mon Sep 17 00:00:00 2001 From: Xingyang Yuan Date: Thu, 16 Jan 2025 19:59:35 +0800 Subject: [PATCH] iox-#2414 Use placement new to construct a new object during assignment --- .../release-notes/iceoryx-unreleased.md | 1 + .../moduletests/test_vocabulary_variant.cpp | 2 +- .../vocabulary/include/iox/detail/variant.inl | 23 ++++++++----------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/doc/website/release-notes/iceoryx-unreleased.md b/doc/website/release-notes/iceoryx-unreleased.md index 13a3b11c48..4ac9cd9aa5 100644 --- a/doc/website/release-notes/iceoryx-unreleased.md +++ b/doc/website/release-notes/iceoryx-unreleased.md @@ -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:** diff --git a/iceoryx_hoofs/test/moduletests/test_vocabulary_variant.cpp b/iceoryx_hoofs/test/moduletests/test_vocabulary_variant.cpp index 7746ab4ba9..8db3747a25 100644 --- a/iceoryx_hoofs/test/moduletests/test_vocabulary_variant.cpp +++ b/iceoryx_hoofs/test/moduletests/test_vocabulary_variant.cpp @@ -473,7 +473,7 @@ TEST_F(variant_Test, DirectValueAssignmentWhenAlreadyAssignedWithDifferentType) iox::variant schlomo; schlomo = 123; schlomo = 123.01F; - EXPECT_THAT(schlomo.index(), Eq(0U)); + EXPECT_THAT(schlomo.index(), Eq(1U)); } TEST_F(variant_Test, HoldsAlternativeForCorrectType) diff --git a/iceoryx_hoofs/vocabulary/include/iox/detail/variant.inl b/iceoryx_hoofs/vocabulary/include/iox/detail/variant.inl index 537dd48a0a..79f1429602 100644 --- a/iceoryx_hoofs/vocabulary/include/iox/detail/variant.inl +++ b/iceoryx_hoofs/vocabulary/include/iox/detail/variant.inl @@ -149,25 +149,22 @@ template inline typename std::enable_if&>::value, variant>::type& variant::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(); + new (&m_storage) T(std::move(rhs)); m_type_index = internal::get_index_of_type<0, T, Types...>::index; } - - if (!has_bad_variant_element_access()) - { - // 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(&m_storage); - *storage = std::forward(rhs); - } else { - error_message(__PRETTY_FUNCTION__, - "wrong variant type assignment, another type is already " - "set in variant"); + if (m_type_index != INVALID_VARIANT_INDEX) + { + // 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(&m_storage); + *storage = std::forward(rhs); + } } - return *this; }