From 77bca1a9601f40310a249bf853ca3f5387dbcc8d Mon Sep 17 00:00:00 2001 From: "Jayesh Badwaik (FZ Juelich)" <j.badwaik@fz-juelich.de> Date: Sun, 4 Jun 2023 15:31:52 +0200 Subject: [PATCH] + nola::owning_ptr : add functionality - add a constructor from convertible_to pointer - add a method to return the allocator --- src/cpp/include/nola/owning_ptr.hpp | 30 +++++++++++++++++++++++++++++ test/unit/cpp/nola/owning_ptr.t.cpp | 30 +++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/cpp/include/nola/owning_ptr.hpp b/src/cpp/include/nola/owning_ptr.hpp index 6051bf4..154d488 100644 --- a/src/cpp/include/nola/owning_ptr.hpp +++ b/src/cpp/include/nola/owning_ptr.hpp @@ -35,6 +35,14 @@ public: owning_ptr(pointer ptr, allocator_type const& alloc); + template <typename U, typename OtherAlloc> + explicit owning_ptr(owning_ptr<U, OtherAlloc>&& other) noexcept + requires std::convertible_to<U*, T*>; + + template <typename U, typename OtherAlloc> + auto operator=(owning_ptr<U, OtherAlloc>&& other) noexcept -> owning_ptr& + requires std::convertible_to<U*, T*>; + private: owning_ptr(owning_ptr const&) = default; auto operator=(owning_ptr const&) -> owning_ptr& = default; @@ -65,6 +73,8 @@ public: void reset(pointer ptr) noexcept; void reset() noexcept; + auto get_allocator() const noexcept -> allocator_type { return alloc_; } + private: pointer value_ = nullptr; internal_allocator alloc_; @@ -97,6 +107,26 @@ owning_ptr<T, Alloc>::~owning_ptr() } } +template <typename T, typename Alloc> +template <typename U, typename OtherAlloc> +owning_ptr<T, Alloc>::owning_ptr(owning_ptr<U, OtherAlloc>&& other) noexcept + requires std::convertible_to<U*, T*> +: value_(other.release()), alloc_(std::move(other.get_allocator())) +{ +} + +template <typename T, typename Alloc> +template <typename U, typename OtherAlloc> +auto owning_ptr<T, Alloc>::operator=(owning_ptr<U, OtherAlloc>&& other) noexcept -> owning_ptr& + requires std::convertible_to<U*, T*> +{ + if (*this != other) { + value_ = other.release(); + alloc_ = std::move(other.get_allocator()); + } + return *this; +} + template <typename T1, typename Alloc1, typename T2, typename Alloc> auto operator==(owning_ptr<T1, Alloc1> const& lhs, owning_ptr<T2, Alloc> const& rhs) noexcept -> bool diff --git a/test/unit/cpp/nola/owning_ptr.t.cpp b/test/unit/cpp/nola/owning_ptr.t.cpp index d316c20..ac60f27 100644 --- a/test/unit/cpp/nola/owning_ptr.t.cpp +++ b/test/unit/cpp/nola/owning_ptr.t.cpp @@ -22,6 +22,28 @@ public: auto get() const -> int { return i; } }; +class Base { +public: + Base() = default; + virtual auto get() const -> int = 0; + virtual ~Base() = default; + Base(Base const&) = default; + Base(Base&&) = default; + auto operator=(Base const&) -> Base& = default; + auto operator=(Base&&) -> Base& = default; +}; + +class Derived : public Base { +public: + Derived() = default; + auto get() const -> int override { return 3; } + ~Derived() override = default; + Derived(Derived const&) = default; + Derived(Derived&&) = default; + auto operator=(Derived const&) -> Derived& = default; + auto operator=(Derived&&) -> Derived& = default; +}; + TEST_CASE("01. owning_ptr construction", "[all]") { auto ptr = nola::make_owning<S>(3); @@ -34,3 +56,11 @@ TEST_CASE("01. owning_ptr construction", "[all]") REQUIRE((*new_ptr).get() == 5); REQUIRE((*ptr).get() == 3); } + +TEST_CASE("02. Test Construction of Derived") +{ + auto ptr = nola::make_owning<Derived>(); + REQUIRE(ptr->get() == 3); + + auto base_ptr = nola::owning_ptr<Base>(ptr.clone()); +} -- GitLab