forked from eclipse-iceoryx/iceoryx
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
iox-eclipse-iceoryx#218 Initial implementation of unique_ptr with sto…
…red custom deleter. Signed-off-by: Ithier Jeff (CC-AD/EYF1) <[email protected]>
- Loading branch information
Showing
4 changed files
with
269 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<typename T> | ||
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<void(ptr_t const)> 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<void(ptr_t const)> deleter) noexcept; | ||
|
||
unique_ptr(void* allocation, const function_ref<void(ptr_t const)> 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<void(ptr_t const)> m_deleter; | ||
}; | ||
|
||
|
||
} // namespace cxx | ||
} // namespace iox | ||
|
||
#include "iceoryx_utils/internal/cxx/unique_ptr.inl" | ||
|
||
#endif // IOX_UTILS_CXX_UNIQUE_PTR_HPP |
84 changes: 84 additions & 0 deletions
84
iceoryx_utils/include/iceoryx_utils/internal/cxx/unique_ptr.inl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<typename T> | ||
unique_ptr<T>::unique_ptr(const function_ref<void(T* const)> deleter) noexcept : m_deleter(deleter) | ||
{} | ||
|
||
template<typename T> | ||
unique_ptr<T>::unique_ptr(ptr_t ptr, const function_ref<void(T* const)> deleter) noexcept : m_ptr(ptr), m_deleter(deleter) | ||
{} | ||
|
||
template<typename T> | ||
unique_ptr<T>::unique_ptr(void* allocation, const function_ref<void(ptr_t const)> deleter) noexcept | ||
: m_ptr(reinterpret_cast<T*>(allocation)), m_deleter(deleter) | ||
{} | ||
|
||
template<typename T> | ||
unique_ptr<T>::~unique_ptr() noexcept | ||
{ | ||
m_deleter(m_ptr); | ||
} | ||
|
||
/// Dereference the stored pointer. | ||
template<typename T> | ||
T unique_ptr<T>::operator*() noexcept | ||
{ | ||
return *get(); | ||
} | ||
|
||
/// Return the stored pointer. | ||
template<typename T> | ||
T* unique_ptr<T>::operator->() noexcept | ||
{ | ||
return get(); | ||
} | ||
|
||
|
||
template<typename T> | ||
T* unique_ptr<T>::get() noexcept | ||
{ | ||
return m_ptr; | ||
} | ||
|
||
template<typename T> | ||
T* unique_ptr<T>::release() noexcept | ||
{ | ||
auto ptr = m_ptr; | ||
m_ptr = nullptr; | ||
return ptr; | ||
} | ||
|
||
template<typename T> | ||
void unique_ptr<T>::reset(T* ptr) noexcept | ||
{ | ||
if(m_ptr) | ||
{ | ||
m_deleter(m_ptr); | ||
} | ||
m_ptr = ptr; | ||
} | ||
|
||
template<typename T> | ||
void unique_ptr<T>::swap(unique_ptr<T>& 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <iostream> | ||
|
||
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<Position>(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<Position>(deleter); | ||
|
||
uint8_t* buf = new uint8_t[sizeof(Position)]; | ||
ptr.reset(reinterpret_cast<Position*>(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); | ||
|
||
} |