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;
93 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
95 *
this = std::move(other);
107 template <
typename U,
108 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
115 UniquePtr& operator=(std::nullptr_t)
noexcept;
128 template <
typename U,
129 std::enable_if_t<std::is_assignable_v<T*&, U*>,
int> = 0>
132 [[nodiscard]]
friend constexpr bool operator==(
const UniquePtr& lhs,
134 return lhs.Equals(
nullptr);
136 [[nodiscard]]
friend constexpr bool operator==(std::nullptr_t,
138 return rhs.Equals(
nullptr);
140 [[nodiscard]]
friend constexpr bool operator==(
const UniquePtr& lhs,
141 const UniquePtr& rhs) {
142 return lhs.Equals(rhs) && lhs.control_block_ == rhs.control_block_;
145 [[nodiscard]]
friend constexpr bool operator!=(
const UniquePtr& lhs,
147 return !lhs.Equals(
nullptr);
149 [[nodiscard]]
friend constexpr bool operator!=(std::nullptr_t,
150 const UniquePtr& rhs) {
151 return !rhs.Equals(
nullptr);
153 [[nodiscard]]
friend constexpr bool operator!=(
const UniquePtr& lhs,
154 const UniquePtr& rhs) {
155 return !(lhs == rhs);
170 element_type*
Release() noexcept;
176 void Reset() noexcept;
190 template <typename U,
191 typename = std::enable_if_t<std::is_assignable_v<T*&, U*>>>
192 void CopyFrom(const
UniquePtr<U>& other);
198 std::conditional_t<std::is_array_v<T>,
size_t, Empty> size_;
211 if constexpr (std::is_array_v<T>) {
219 static_assert(!is_unbounded_array_v<T>,
220 "UniquePtr for unbounded array type must provide size");
221 if constexpr (is_bounded_array_v<T>) {
222 size_ = std::extent_v<T>;
230 : Base(value), size_(size), deallocator_(&deallocator) {
232 is_unbounded_array_v<T>,
233 "UniquePtr must not provide size unless type is an unbounded array");
237template <
typename U, std::enable_if_t<std::is_assignable_v<T*&, U*>,
int>>
238constexpr UniquePtr<T>::operator UniquePtr<U>() && {
240 return UniquePtr<U>(
static_cast<U*
>(Release()), deallocator);
245 static_assert(std::is_array_v<T>,
246 "size() cannot be called with a non-array type");
251template <
typename U,
typename>
267 element_type* value = Base::Release();
268 deallocator_ =
nullptr;
269 if constexpr (std::is_array_v<T>) {
277 if (*
this ==
nullptr) {
280 if (!deallocator_->HasCapability(allocator::kSkipsDestroy)) {
281 if constexpr (std::is_array_v<T>) {
282 Base::Destroy(size_);
289 auto* ptr =
const_cast<std::remove_const_t<element_type>*
>(Release());
296 if constexpr (std::is_array_v<T>) {
297 std::swap(size_, other.size_);
299 std::swap(deallocator_, other.deallocator_);
303template <
typename U,
typename>
305 static_assert(std::is_array_v<T> == std::is_array_v<U>);
306 Base::CopyFrom(other);
307 if constexpr (std::is_array_v<T>) {
310 deallocator_ = other.deallocator_;
Abstract interface for releasing memory.
Definition: deallocator.h:30
Definition: unique_ptr.h:44
element_type * Release() noexcept
Definition: unique_ptr.h:266
Deallocator * deallocator() const
Returns a pointer to the object that can destroy the value.
Definition: unique_ptr.h:164
UniquePtr & operator=(UniquePtr< U > &&other) noexcept
void Reset() noexcept
Definition: unique_ptr.h:276
size_t size() const
Definition: unique_ptr.h:244
~UniquePtr()
Frees any currently-held value.
Definition: unique_ptr.h:99
constexpr UniquePtr(std::nullptr_t) noexcept
Definition: unique_ptr.h:67
void Swap(UniquePtr &other)
Swaps the managed pointer and deallocator of this and another object.
Definition: unique_ptr.h:294
UniquePtr(UniquePtr< U > &&other) noexcept
Definition: unique_ptr.h:94
void Deallocate(void *ptr)
Definition: deallocator.h:314
constexpr Deallocator()=default
TODO(b/326509341): Remove when downstream consumers migrate.
Definition: unique_ptr.h:183
#define PW_NO_UNIQUE_ADDRESS
Definition: compiler.h:297
The Pigweed namespace.
Definition: alignment.h:27