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>) {
88 static_assert(!allocator::internal::is_unbounded_array_v<T>,
89 "UniquePtr for unbounded array type must provide size");
90 if constexpr (allocator::internal::is_bounded_array_v<T>) {
91 size_ = std::extent_v<T>;
98 allocator::internal::is_unbounded_array_v<T>,
99 "UniquePtr must not provide size unless type is an unbounded array");
108 template <
typename U,
109 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
111 *
this = std::move(other);
123 template <
typename U,
124 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
131 UniquePtr& operator=(std::nullptr_t)
noexcept;
144 template <
typename U,
145 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
151 [[nodiscard]]
friend constexpr bool operator==(
const UniquePtr& lhs,
153 return lhs.Equals(
nullptr);
155 [[nodiscard]]
friend constexpr bool operator==(std::nullptr_t,
156 const UniquePtr& rhs) {
157 return rhs.Equals(
nullptr);
159 [[nodiscard]]
friend constexpr bool operator==(
const UniquePtr& lhs,
160 const UniquePtr& rhs) {
161 return lhs.Equals(rhs) && lhs.control_block_ == rhs.control_block_;
164 [[nodiscard]]
friend constexpr bool operator!=(
const UniquePtr& lhs,
166 return !lhs.Equals(
nullptr);
168 [[nodiscard]]
friend constexpr bool operator!=(std::nullptr_t,
169 const UniquePtr& rhs) {
170 return !rhs.Equals(
nullptr);
172 [[nodiscard]]
friend constexpr bool operator!=(
const UniquePtr& lhs,
173 const UniquePtr& rhs) {
174 return !(lhs == rhs);
181 static_assert(std::is_array_v<T>,
182 "size() cannot be called with a non-array type");
193 element_type*
Release() noexcept;
199 void Reset() noexcept;
213 template <typename U,
214 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
215 void CopyFrom(const
UniquePtr<U>& other);
221 std::conditional_t<std::is_array_v<T>,
size_t, Empty> size_;
232using UniquePtr = PW_ALLOCATOR_DEPRECATED ::pw::UniquePtr<T>;
241template <
typename U,
typename>
257 element_type* value = Base::Release();
258 deallocator_ =
nullptr;
259 if constexpr (std::is_array_v<T>) {
267 if (*
this ==
nullptr) {
270 if (!Base::HasCapability(deallocator_, allocator::kSkipsDestroy)) {
271 if constexpr (std::is_array_v<T>) {
272 Base::Destroy(size_);
279 auto* ptr =
const_cast<std::remove_const_t<element_type>*
>(
Release());
286 if constexpr (std::is_array_v<T>) {
287 std::swap(size_, other.size_);
289 std::swap(deallocator_, other.deallocator_);
293template <
typename U,
typename>
295 static_assert(std::is_array_v<T> == std::is_array_v<U>);
296 Base::CopyFrom(other);
297 if constexpr (std::is_array_v<T>) {
300 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:256
Deallocator * deallocator() const
Returns a pointer to the object that can destroy the value.
Definition: unique_ptr.h:187
UniquePtr & operator=(UniquePtr< U > &&other) noexcept
void Reset() noexcept
Definition: unique_ptr.h:266
UniquePtr(element_type *value, Deallocator &deallocator)
Definition: unique_ptr.h:86
constexpr UniquePtr() noexcept
Definition: unique_ptr.h:56
size_t size() const
Definition: unique_ptr.h:180
~UniquePtr()
Frees any currently-held value.
Definition: unique_ptr.h:115
constexpr UniquePtr(std::nullptr_t) noexcept
Definition: unique_ptr.h:70
void Swap(UniquePtr &other)
Swaps the managed pointer and deallocator of this and another object.
Definition: unique_ptr.h:284
UniquePtr(UniquePtr< U > &&other) noexcept
Definition: unique_ptr.h:110
#define PW_NO_UNIQUE_ADDRESS
Definition: compiler.h:297
The Pigweed namespace.
Definition: alignment.h:27