diff --git a/iceoryx_posh/include/iceoryx_posh/experimental/popo/publisher.hpp b/iceoryx_posh/include/iceoryx_posh/experimental/popo/publisher.hpp index eccd850563..24f72f4cd3 100644 --- a/iceoryx_posh/include/iceoryx_posh/experimental/popo/publisher.hpp +++ b/iceoryx_posh/include/iceoryx_posh/experimental/popo/publisher.hpp @@ -84,8 +84,6 @@ class Publisher /// void release(chunk_t&& chunk) const noexcept; - // To use this method, the user needs to know about the chunk concept. - // This means, the usage cannot be completely transparant (unless via copyAndPublish). /// /// @brief send Publishes the chunk to the system. /// @details Ownership of published chunks is automatically released. diff --git a/iceoryx_utils/include/iceoryx_utils/cxx/unique_ptr.hpp b/iceoryx_utils/include/iceoryx_utils/cxx/unique_ptr.hpp new file mode 100644 index 0000000000..92fdd22f17 --- /dev/null +++ b/iceoryx_utils/include/iceoryx_utils/cxx/unique_ptr.hpp @@ -0,0 +1,106 @@ +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef IOX_UTILS_CXX_UNIQUE_PTR_HPP +#define IOX_UTILS_CXX_UNIQUE_PTR_HPP + +#include "iceoryx_utils/cxx/function_ref.hpp" + +namespace iox +{ +namespace cxx +{ + +/// +/// @todo document how it differs to STL +/// +template +class unique_ptr{ +public: + + using ptr_t = T*; + + /// + /// @brief unique_ptr Creates an empty unique ptr that owns nothing. Can be passed ownership later. + /// + unique_ptr(function_ref deleter) noexcept; + + /// + /// @brief unique_ptr Creates a unique pointer. + /// @details A delete must always be provided as no heap is used. The unique_ptr needs to know how to delete + /// the object when the reference is out of scope. + /// @param ptr The raw pointer to the object to take ownership of. + /// @param deleter The deleter function for cleaning up the object. + /// + unique_ptr(ptr_t ptr, const function_ref deleter) noexcept; + + unique_ptr(void* allocation, const function_ref deleter) noexcept; + + // Not copy-able to ensure uniqueness. + unique_ptr(const unique_ptr& other) = delete; + unique_ptr& operator=(const unique_ptr&) = delete; + + // These might need to be specialized. + unique_ptr(unique_ptr&& rhs) = default; + unique_ptr& operator=(unique_ptr&& rhs) = default; + + /// + /// Automatically deletes the owned object on destruction. + /// + ~unique_ptr() noexcept; + + /// Dereference the stored pointer. + T operator*() noexcept; + + /// Return the stored pointer. + ptr_t operator->() noexcept; + + /// + /// @brief get Retrieve the underlying raw pointer. + /// @details The unique_ptr retains ownership, therefore the "borrowed" pointer must not be deleted. + /// @return Pointer to managed object or nullptr if none owned. + /// + ptr_t get() noexcept; + + /// + /// @brief release Releases ownership of the underlying pointer. + /// @return Pointer to the managed object or nullptr if none owned. + /// + ptr_t release() noexcept; + + /// + /// @brief reset Reset the unique_ptr instance's owned object to the one given. + /// @details Any previously owned objects will be deleted. + /// @param ptr Pointer to object to take ownership on. + /// + void reset(ptr_t ptr) noexcept; + + /// + /// @brief swap Swaps object ownership with another unique_ptr. + /// @param other The unique_ptr with which to swap owned objects. + /// + void swap(unique_ptr& other) noexcept; + +private: + ptr_t m_ptr = nullptr; + function_ref m_deleter; +}; + + +} // namespace cxx +} // namespace iox + +#include "iceoryx_utils/internal/cxx/unique_ptr.inl" + +#endif // IOX_UTILS_CXX_UNIQUE_PTR_HPP diff --git a/iceoryx_utils/include/iceoryx_utils/internal/cxx/unique_ptr.inl b/iceoryx_utils/include/iceoryx_utils/internal/cxx/unique_ptr.inl new file mode 100644 index 0000000000..ad81026ced --- /dev/null +++ b/iceoryx_utils/include/iceoryx_utils/internal/cxx/unique_ptr.inl @@ -0,0 +1,84 @@ + +#ifndef IOX_UTILS_CXX_UNIQUE_PTR_INL +#define IOX_UTILS_CXX_UNIQUE_PTR_INL + +#include "iceoryx_utils/cxx/unique_ptr.hpp" + +namespace iox +{ +namespace cxx +{ + +template +unique_ptr::unique_ptr(const function_ref deleter) noexcept : m_deleter(deleter) +{} + +template +unique_ptr::unique_ptr(ptr_t ptr, const function_ref deleter) noexcept : m_ptr(ptr), m_deleter(deleter) +{} + +template +unique_ptr::unique_ptr(void* allocation, const function_ref deleter) noexcept + : m_ptr(reinterpret_cast(allocation)), m_deleter(deleter) +{} + +template +unique_ptr::~unique_ptr() noexcept +{ + m_deleter(m_ptr); +} + +/// Dereference the stored pointer. +template +T unique_ptr::operator*() noexcept +{ + return *get(); +} + +/// Return the stored pointer. +template +T* unique_ptr::operator->() noexcept +{ + return get(); +} + + +template +T* unique_ptr::get() noexcept +{ + return m_ptr; +} + +template +T* unique_ptr::release() noexcept +{ + auto ptr = m_ptr; + m_ptr = nullptr; + return ptr; +} + +template +void unique_ptr::reset(T* ptr) noexcept +{ + if(m_ptr) + { + m_deleter(m_ptr); + } + m_ptr = ptr; +} + +template +void unique_ptr::swap(unique_ptr& other) noexcept +{ + // Release pointers from both instances. + auto thisPtr = release(); + auto otherPtr = other.release(); + // Set new pointers on both instances. + reset(otherPtr); + other.reset(release()); +} + +} // namespace iox +} // namespace popo + +#endif // IOX_UTILS_CXX_UNIQUE_PTR_INL diff --git a/iceoryx_utils/test/moduletests/test_cxx_unique_ptr.cpp b/iceoryx_utils/test/moduletests/test_cxx_unique_ptr.cpp new file mode 100644 index 0000000000..71cd57dace --- /dev/null +++ b/iceoryx_utils/test/moduletests/test_cxx_unique_ptr.cpp @@ -0,0 +1,79 @@ +// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "iceoryx_utils/cxx/unique_ptr.hpp" +#include "test.hpp" + +#include + +using namespace ::testing; + +struct Position { + double_t x = 0.0; + double_t y = 0.0; + double_t z = 0.0; +}; + +class UniquePtrTest : public Test { + +public: + UniquePtrTest() + { + + } + + void SetUp() + { + } + + void TearDown() + { + } + +}; + +TEST_F(UniquePtrTest, CanBeConstructedWithUndefinedBlob) +{ + auto deleter = [](Position* const p){delete p;}; + uint8_t* buf = new uint8_t[sizeof(Position)]; + auto ptr = iox::cxx::unique_ptr(buf, deleter); + + ptr->x = 10.0; + ptr->y = 77.77; + ptr->z = 50.50; + + EXPECT_EQ(10.0, ptr->x); + EXPECT_EQ(77.77, ptr->y); + EXPECT_EQ(50.50, ptr->z); + +} + +TEST_F(UniquePtrTest, CanBeResetToPointToUndefinedBlob) +{ + + auto deleter = [](Position* const p){delete p;}; + auto ptr = iox::cxx::unique_ptr(deleter); + + uint8_t* buf = new uint8_t[sizeof(Position)]; + ptr.reset(reinterpret_cast(buf)); + + ptr->x = 10.0; + ptr->y = 77.77; + ptr->z = 50.50; + + EXPECT_EQ(10.0, ptr->x); + EXPECT_EQ(77.77, ptr->y); + EXPECT_EQ(50.50, ptr->z); + +}