Skip to content

Commit

Permalink
iox-eclipse-iceoryx#1732 Remove static_storage from storable_function
Browse files Browse the repository at this point in the history
Signed-off-by: Marika Lehmann <[email protected]>
  • Loading branch information
FerdinandSpitzschnueffler committed Jan 18, 2023
1 parent 338e840 commit 7fd4e06
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define IOX_HOOFS_STORABLE_FUNCTION_HPP

#include "iceoryx_hoofs/cxx/type_traits.hpp"
#include "iceoryx_hoofs/iceoryx_hoofs_types.hpp"
#include "iceoryx_hoofs/internal/cxx/static_storage.hpp"

#include <iostream>
Expand Down Expand Up @@ -155,7 +156,9 @@ class storable_function<Capacity, signature<ReturnType, Args...>> final
private:
operations m_operations; // operations depending on type-erased callable (copy, move, destroy)

StorageType m_storage; // storage for the callable
// AXIVION Next Construct AutosarC++19_03-A18.1.1 : safe access is guaranteed since the c-array is wrapped inside the storable_function
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, hicpp-avoid-c-arrays)
byte_t m_storage[Capacity]; // storage for the callable
void* m_callable{nullptr}; // pointer to stored type-erased callable
ReturnType (*m_invoker)(void*, Args&&...){nullptr}; // indirection to invoke the stored callable,
// nullptr if no callable is stored
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,22 +166,23 @@ inline void swap(storable_function<Capacity, T>& f, storable_function<Capacity,
f.swap(g);
}

template <typename T>
void* allocate(byte_t* startAddress)
{
uint64_t alignedPosition = cxx::align(reinterpret_cast<uint64_t>(startAddress), alignof(T));
return reinterpret_cast<void*>(alignedPosition);
}

template <uint64_t Capacity, typename ReturnType, typename... Args>
template <typename Functor, typename>
inline void storable_function<Capacity, signature<ReturnType, Args...>>::storeFunctor(const Functor& functor) noexcept
{
using StoredType = typename std::remove_reference<Functor>::type;
auto ptr = m_storage.template allocate<StoredType>();
cxx::Expects(ptr != nullptr);

// AXIVION Next Construct AutosarC++19_03-A18.5.10: false positive, m_storage.allocate<T>
// provides a properly aligned ptr and sufficient memory (static_storage satisfies this)
/// @NOLINTJUSTIFICATION ownership is encapsulated in storable_function and will be released in destroy
/// @NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
ptr = new (ptr) StoredType(functor);
m_callable = allocate<StoredType>(m_storage);

// erase the functor type and store as reference to the call in storage
m_callable = ptr;
new (m_callable) StoredType(functor);

m_invoker = &invoke<StoredType>;
m_operations.copyFunction = &copy<StoredType>;
m_operations.moveFunction = &move<StoredType>;
Expand All @@ -194,19 +195,13 @@ template <typename CallableType>
inline void storable_function<Capacity, signature<ReturnType, Args...>>::copy(const storable_function& src,
storable_function& dest) noexcept
{
auto ptr = dest.m_storage.template allocate<CallableType>();
cxx::Expects(ptr != nullptr);
dest.m_callable = allocate<CallableType>(dest.m_storage);

// AXIVION Next Construct AutosarC++19_03-M5.2.8: type erasure - conversion to compatible type
const auto obj = static_cast<CallableType*>(src.m_callable);
cxx::Expects(obj != nullptr); // should not happen unless src is incorrectly used after move

// AXIVION Next Construct AutosarC++19_03-A18.5.10: false positive, m_storage.allocate<T>
// provides a properly aligned ptr and sufficient memory (static_storage satisfies this)
/// @NOLINTJUSTIFICATION ownership is encapsulated in storable_function and will be released in destroy
/// @NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
ptr = new (ptr) CallableType(*obj);
dest.m_callable = ptr;
new (dest.m_callable) CallableType(*obj);
dest.m_invoker = src.m_invoker;
}

Expand All @@ -217,19 +212,14 @@ template <typename CallableType>
inline void storable_function<Capacity, signature<ReturnType, Args...>>::move(storable_function& src,
storable_function& dest) noexcept
{
auto ptr = dest.m_storage.template allocate<CallableType>();
cxx::Expects(ptr != nullptr);
// m_callable = static_cast<void*>(align(reinterpret_cast<uint64_t>(m_storage), alignof(CallableType)));
dest.m_callable = allocate<CallableType>(dest.m_storage);

// AXIVION Next Construct AutosarC++19_03-M5.2.8: type erasure - conversion to compatible type
const auto obj = static_cast<CallableType*>(src.m_callable);
cxx::Expects(obj != nullptr); // should not happen unless src is incorrectly used after move

// AXIVION Next Construct AutosarC++19_03-A18.5.10: false positive, m_storage.allocate<T>
// provides a properly aligned ptr and sufficient memory (static_storage satisfies this)
/// @NOLINTJUSTIFICATION ownership is encapsulated in storable_function and will be released in destroy
/// @NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
ptr = new (ptr) CallableType(std::move(*obj));
dest.m_callable = ptr;
new (dest.m_callable) CallableType(std::move(*obj));
dest.m_invoker = src.m_invoker;
src.m_operations.destroy(src);
src.m_callable = nullptr;
Expand All @@ -246,7 +236,6 @@ inline void storable_function<Capacity, signature<ReturnType, Args...>>::destroy
const auto ptr = static_cast<CallableType*>(f.m_callable);
// AXIVION Next Construct AutosarC++19_03-A5.3.2: ptr is guaranteed not to be nullptr
ptr->~CallableType();
f.m_storage.deallocate();
}
}

Expand Down

0 comments on commit 7fd4e06

Please sign in to comment.