20#include "pw_allocator/config.h"
21#include "pw_allocator/deallocator.h"
22#include "pw_allocator/internal/managed_ptr.h"
23#include "pw_allocator/layout.h"
24#include "pw_preprocessor/compiler.h"
44class UniquePtr :
public ::pw::allocator::internal::ManagedPtr<T> {
46 using Base = ::pw::allocator::internal::ManagedPtr<T>;
47 using Empty = ::pw::allocator::internal::Empty;
50 using pointer =
typename Base::element_type*;
51 using element_type =
typename Base::element_type;
58 if constexpr (std::is_array_v<T>) {
89 static_assert(!allocator::internal::is_unbounded_array_v<T>,
90 "UniquePtr for unbounded array type must provide size");
91 if constexpr (allocator::internal::is_bounded_array_v<T>) {
92 size_ = std::extent_v<T>;
99 allocator::internal::is_unbounded_array_v<T>,
100 "UniquePtr must not provide size unless type is an unbounded array");
109 template <
typename U,
110 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
112 *
this = std::move(other);
124 template <
typename U,
125 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
132 UniquePtr& operator=(std::nullptr_t)
noexcept;
145 template <
typename U,
146 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
152 [[nodiscard]]
friend constexpr bool operator==(
const UniquePtr& lhs,
154 return lhs.Equals(
nullptr);
156 [[nodiscard]]
friend constexpr bool operator==(std::nullptr_t,
157 const UniquePtr& rhs) {
158 return rhs.Equals(
nullptr);
160 [[nodiscard]]
friend constexpr bool operator==(
const UniquePtr& lhs,
161 const UniquePtr& rhs) {
162 return lhs.Equals(rhs) && lhs.control_block_ == rhs.control_block_;
165 [[nodiscard]]
friend constexpr bool operator!=(
const UniquePtr& lhs,
167 return !lhs.Equals(
nullptr);
169 [[nodiscard]]
friend constexpr bool operator!=(std::nullptr_t,
170 const UniquePtr& rhs) {
171 return !rhs.Equals(
nullptr);
173 [[nodiscard]]
friend constexpr bool operator!=(
const UniquePtr& lhs,
174 const UniquePtr& rhs) {
175 return !(lhs == rhs);
182 static_assert(std::is_array_v<T>,
183 "size() cannot be called with a non-array type");
194 element_type*
Release() noexcept;
200 void Reset() noexcept;
214 template <typename U,
215 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
216 void CopyFrom(const
UniquePtr<U>& other);
222 std::conditional_t<std::is_array_v<T>,
size_t, Empty> size_;
234template <typename U, typename>
250 element_type* value = Base::Release();
251 deallocator_ =
nullptr;
252 if constexpr (std::is_array_v<T>) {
260 if (*
this ==
nullptr) {
263 if (!deallocator_->
HasCapability(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:28
Definition: unique_ptr.h:44
element_type * Release() noexcept
Definition: unique_ptr.h:249
Deallocator * deallocator() const
Returns a pointer to the object that can destroy the value.
Definition: unique_ptr.h:188
UniquePtr & operator=(UniquePtr< U > &&other) noexcept
void Reset() noexcept
Definition: unique_ptr.h:259
UniquePtr(element_type *value, Deallocator &deallocator)
Definition: unique_ptr.h:87
constexpr UniquePtr() noexcept
Definition: unique_ptr.h:57
size_t size() const
Definition: unique_ptr.h:181
~UniquePtr()
Frees any currently-held value.
Definition: unique_ptr.h:116
constexpr UniquePtr(std::nullptr_t) noexcept
Definition: unique_ptr.h:71
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:111
void Deallocate(void *ptr)
Definition: deallocator.h:59
constexpr bool HasCapability(Capability capability) const
Returns whether a given capability is enabled for this object.
Definition: deallocator.h:49
#define PW_NO_UNIQUE_ADDRESS
Definition: compiler.h:297
The Pigweed namespace.
Definition: alignment.h:27