Pigweed
 
Loading...
Searching...
No Matches
deallocator.h
1// Copyright 2024 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include "pw_allocator/capability.h"
17#include "pw_allocator/layout.h"
18#include "pw_allocator/unique_ptr.h"
19#include "pw_result/result.h"
20#include "pw_status/status.h"
21#include "pw_status/status_with_size.h"
22
23namespace pw {
24
27 protected:
28 // Alias types and variables needed for SFINAE below.
29 template <typename T>
30 static constexpr bool is_bounded_array_v =
31 allocator::internal::is_bounded_array_v<T>;
32
33 template <typename T>
34 static constexpr bool is_unbounded_array_v =
35 allocator::internal::is_unbounded_array_v<T>;
36
37 public:
39 using Capability = allocator::Capability;
41
42 virtual ~Deallocator() = default;
43
44 constexpr const Capabilities& capabilities() const { return capabilities_; }
45
47 bool HasCapability(Capability capability) const {
48 return capabilities_.has(capability);
49 }
50
57 void Deallocate(void* ptr) {
58 if (ptr != nullptr) {
59 DoDeallocate(ptr);
60 }
61 }
62
66 void Deallocate(void* ptr, Layout layout) {
67 if (ptr != nullptr) {
68 DoDeallocate(ptr, layout);
69 }
70 }
71
78 template <typename T>
79 void Delete(T* ptr) {
80 if (!capabilities_.has(Capability::kSkipsDestroy)) {
81 std::destroy_at(ptr);
82 }
83 Deallocate(ptr);
84 }
85
94 auto result = DoGetInfo(InfoType::kCapacity, nullptr);
95 return StatusWithSize(result.status(), Layout::Unwrap(result).size());
96 }
97
108 bool IsEqual(const Deallocator& other) const { return this == &other; }
109
110 // See WrapUnique below. Disallow calls with explicitly-sized array types like
111 // `T[kN]`.
112 template <typename T,
113 int&... kExplicitGuard,
114 std::enable_if_t<is_bounded_array_v<T>, int> = 0,
115 typename... Args>
116 void WrapUnique(Args&&...) = delete;
117
118 protected:
120 constexpr Deallocator() = default;
121
122 explicit constexpr Deallocator(const Capabilities& capabilities)
123 : capabilities_(capabilities) {}
124
128 template <typename T, std::enable_if_t<!std::is_array_v<T>, int> = 0>
129 [[nodiscard]] UniquePtr<T> WrapUnique(T* ptr) {
130 return UniquePtr<T>(ptr, this);
131 }
132
137 template <typename T,
138 int&... kExplicitGuard,
139 typename ElementType = std::remove_extent_t<T>,
140 std::enable_if_t<is_unbounded_array_v<T>, int> = 0>
141 [[nodiscard]] UniquePtr<T> WrapUnique(ElementType* ptr, size_t size) {
142 return UniquePtr<T>(ptr, size, this);
143 }
144
149 template <typename T>
150 [[nodiscard]] UniquePtr<T[]> WrapUniqueArray(T* ptr, size_t size) {
151 return WrapUnique<T[]>(ptr, size);
152 }
153
182 enum class InfoType {
193 kRequestedLayoutOf,
194
198
205 kUsableLayoutOf,
206
217 kAllocatedLayoutOf,
218
224 kCapacity,
225
233 kRecognizes,
234 };
235
241 Result<Layout> GetInfo(InfoType info_type, const void* ptr) const {
242 return DoGetInfo(info_type, ptr);
243 }
244
250 static Result<Layout> GetInfo(const Deallocator& deallocator,
251 InfoType info_type,
252 const void* ptr) {
253 return deallocator.DoGetInfo(info_type, ptr);
254 }
255
258 Result<Layout> GetRequestedLayout(const void* ptr) const {
259 return DoGetInfo(InfoType::kRequestedLayoutOf, ptr);
260 }
261
264 static Result<Layout> GetRequestedLayout(const Deallocator& deallocator,
265 const void* ptr) {
266 return deallocator.GetRequestedLayout(ptr);
267 }
268
271 Result<Layout> GetUsableLayout(const void* ptr) const {
272 return DoGetInfo(InfoType::kUsableLayoutOf, ptr);
273 }
274
277 static Result<Layout> GetUsableLayout(const Deallocator& deallocator,
278 const void* ptr) {
279 return deallocator.GetUsableLayout(ptr);
280 }
281
284 Result<Layout> GetAllocatedLayout(const void* ptr) const {
285 return DoGetInfo(InfoType::kAllocatedLayoutOf, ptr);
286 }
287
290 static Result<Layout> GetAllocatedLayout(const Deallocator& deallocator,
291 const void* ptr) {
292 return deallocator.GetAllocatedLayout(ptr);
293 }
294
297 bool Recognizes(const void* ptr) const {
298 return DoGetInfo(InfoType::kRecognizes, ptr).ok();
299 }
300
303 static bool Recognizes(const Deallocator& deallocator, const void* ptr) {
304 return deallocator.Recognizes(ptr);
305 }
306
307 private:
311 virtual void DoDeallocate(void*) {
312 // This method will be pure virtual once consumer migrate from the deprected
313 // version that takes a `Layout` parameter. In the meantime, the check that
314 // this method is implemented is deferred to run-time.
315 PW_ASSERT(false);
316 }
317
320 virtual void DoDeallocate(void* ptr, Layout) { DoDeallocate(ptr); }
321
323 virtual Result<Layout> DoGetInfo(InfoType, const void*) const {
324 return Status::Unimplemented();
325 }
326
327 const Capabilities capabilities_;
328};
329
330namespace allocator {
331
332// Alias for module consumers using the older name for the above type.
333using Deallocator = ::pw::Deallocator;
334
335} // namespace allocator
336} // namespace pw
Abstract interface for releasing memory.
Definition: deallocator.h:26
void Deallocate(void *ptr, Layout layout)
Definition: deallocator.h:66
bool HasCapability(Capability capability) const
Returns whether a given capabilityis enabled for this object.
Definition: deallocator.h:47
StatusWithSize GetCapacity() const
Definition: deallocator.h:93
void Deallocate(void *ptr)
Definition: deallocator.h:57
UniquePtr< T[]> WrapUniqueArray(T *ptr, size_t size)
Definition: deallocator.h:150
void Delete(T *ptr)
Definition: deallocator.h:79
UniquePtr< T > WrapUnique(ElementType *ptr, size_t size)
Definition: deallocator.h:141
UniquePtr< T > WrapUnique(T *ptr)
Definition: deallocator.h:129
bool IsEqual(const Deallocator &other) const
Definition: deallocator.h:108
constexpr Deallocator()=default
TODO(b/326509341): Remove when downstream consumers migrate.
Definition: status_with_size.h:49
Definition: unique_ptr.h:40
Definition: capability.h:62
Definition: layout.h:56
static constexpr Layout Unwrap(const Result< Layout > &result)
Definition: layout.h:89
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27