20#include "pw_allocator/config.h"
21#include "pw_allocator/internal/managed_ptr.h"
22#include "pw_allocator/layout.h"
23#include "pw_preprocessor/compiler.h"
43class UniquePtr :
public ::pw::allocator::internal::ManagedPtr<T> {
45 using Base = ::pw::allocator::internal::ManagedPtr<T>;
46 using Empty = ::pw::allocator::internal::Empty;
49 using pointer =
typename Base::element_type*;
50 using element_type =
typename Base::element_type;
57 if constexpr (std::is_array_v<T>) {
84 static_assert(!allocator::internal::is_unbounded_array_v<T>,
85 "UniquePtr for unbounded array type must provide size");
86 if constexpr (allocator::internal::is_bounded_array_v<T>) {
87 size_ = std::extent_v<T>;
94 allocator::internal::is_unbounded_array_v<T>,
95 "UniquePtr must not provide size unless type is an unbounded array");
104 template <
typename U,
105 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
107 *
this = std::move(other);
119 template <
typename U,
120 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
140 template <
typename U,
141 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
147 [[nodiscard]]
friend constexpr bool operator==(
const UniquePtr& lhs,
149 return lhs.Equals(
nullptr);
151 [[nodiscard]]
friend constexpr bool operator==(std::nullptr_t,
152 const UniquePtr& rhs) {
153 return rhs.Equals(
nullptr);
155 [[nodiscard]]
friend constexpr bool operator==(
const UniquePtr& lhs,
156 const UniquePtr& rhs) {
157 return lhs.Equals(rhs) && lhs.control_block_ == rhs.control_block_;
160 [[nodiscard]]
friend constexpr bool operator!=(
const UniquePtr& lhs,
162 return !lhs.Equals(
nullptr);
164 [[nodiscard]]
friend constexpr bool operator!=(std::nullptr_t,
165 const UniquePtr& rhs) {
166 return !rhs.Equals(
nullptr);
168 [[nodiscard]]
friend constexpr bool operator!=(
const UniquePtr& lhs,
169 const UniquePtr& rhs) {
170 return !(lhs == rhs);
177 static_assert(std::is_array_v<T>,
178 "size() cannot be called with a non-array type");
189 element_type*
Release() noexcept;
195 void Reset() noexcept;
209 template <typename U,
210 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
211 void CopyFrom(const
UniquePtr<U>& other);
217 std::conditional_t<std::is_array_v<T>,
size_t, Empty> size_;
228using UniquePtr = PW_ALLOCATOR_DEPRECATED ::pw::UniquePtr<T>;
237template <
typename U,
typename>
253 element_type* value = Base::Release();
254 deallocator_ =
nullptr;
260 if (*
this ==
nullptr) {
263 if (!Base::HasCapability(deallocator_, allocator::kSkipsDestroy)) {
264 if constexpr (std::is_array_v<T>) {
265 Base::Destroy(size_);
272 auto* ptr =
const_cast<std::remove_const_t<element_type>*
>(
Release());
279 if constexpr (std::is_array_v<T>) {
280 std::swap(size_, other.size_);
282 std::swap(deallocator_, other.deallocator_);
286template <
typename U,
typename>
288 static_assert(std::is_array_v<T> == std::is_array_v<U>);
289 Base::CopyFrom(other);
290 if constexpr (std::is_array_v<T>) {
293 deallocator_ = other.deallocator_;
Abstract interface for releasing memory.
Definition: deallocator.h:29
Definition: unique_ptr.h:43
element_type * Release() noexcept
Definition: unique_ptr.h:252
Deallocator * deallocator() const
Returns a pointer to the object that can destroy the value.
Definition: unique_ptr.h:183
UniquePtr & operator=(UniquePtr< U > &&other) noexcept
void Reset() noexcept
Definition: unique_ptr.h:259
UniquePtr(element_type *value, Deallocator &deallocator)
Definition: unique_ptr.h:82
constexpr UniquePtr() noexcept
Definition: unique_ptr.h:56
size_t size() const
Definition: unique_ptr.h:176
~UniquePtr()
Frees any currently-held value.
Definition: unique_ptr.h:111
constexpr UniquePtr(std::nullptr_t) noexcept
Definition: unique_ptr.h:66
void Swap(UniquePtr &other)
Swaps the managed pointer and deallocator of this and another object.
Definition: unique_ptr.h:277
UniquePtr(UniquePtr< U > &&other) noexcept
Definition: unique_ptr.h:106
#define PW_NO_UNIQUE_ADDRESS
Definition: compiler.h:297
The Pigweed namespace.
Definition: alignment.h:27