Pigweed
 
Loading...
Searching...
No Matches
result.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 <cstddef>
17#include <cstdint>
18
19#include "pw_allocator/hardening.h"
20#include "pw_assert/assert.h"
21#include "pw_status/status.h"
22#include "pw_status/status_with_size.h"
23
24namespace pw::allocator {
25namespace internal {
26
33 private:
34 static constexpr size_t kPrevBits = 5;
35 static constexpr size_t kPrevShift = 0;
36
37 static constexpr size_t kNextBits = 5;
38 static constexpr size_t kNextShift = kPrevBits;
39
40 static constexpr size_t kSizeBits = 10;
41 static constexpr size_t kSizeShift = kPrevBits + kNextBits;
42
43 public:
44 enum class Prev : uint8_t {
45 kUnchanged,
46 kSplitNew,
47 kResizedSmaller,
48 kResizedLarger,
49 };
50
51 enum class Next : uint8_t {
52 kUnchanged,
53 kSplitNew,
54 kResized,
55 kMerged,
56 };
57
58 [[nodiscard]] constexpr Prev prev() const {
59 return static_cast<Prev>(Decode(kPrevBits, kPrevShift));
60 }
61
62 [[nodiscard]] constexpr Next next() const {
63 return static_cast<Next>(Decode(kNextBits, kNextShift));
64 }
65
66 [[nodiscard]] constexpr size_t size() const {
67 return Decode(kSizeBits, kSizeShift);
68 }
69
70 [[nodiscard]] constexpr bool ok() const { return encoded_.ok(); }
71
72 [[nodiscard]] constexpr Status status() const { return encoded_.status(); }
73
76 constexpr void IgnoreUnlessStrict() const {
77 if constexpr (Hardening::kIncludesDebugChecks) {
78 PW_ASSERT(ok());
79 }
80 }
81
82 protected:
83 constexpr GenericBlockResult(Status status, Prev prev, Next next, size_t size)
84 : encoded_(status,
85 Encode(size_t(prev), kPrevBits, kPrevShift) |
86 Encode(size_t(next), kNextBits, kNextShift) |
87 Encode(size, kSizeBits, kSizeShift)) {}
88
89 private:
90 static constexpr size_t Encode(size_t value, size_t bits, size_t shift) {
91 if constexpr (Hardening::kIncludesDebugChecks) {
92 PW_ASSERT(value < (1U << bits));
93 }
94 return value << shift;
95 }
96
97 constexpr size_t Decode(size_t bits, size_t shift) const {
98 return (encoded_.size() >> shift) & ~(~static_cast<size_t>(0) << bits);
99 }
100
101 StatusWithSize encoded_;
102};
103
104} // namespace internal
105
113template <typename BlockType>
114class [[nodiscard]] BlockResult : public internal::GenericBlockResult {
115 public:
116 constexpr explicit BlockResult(BlockType* block)
117 : BlockResult(block, OkStatus()) {}
118
119 constexpr BlockResult(BlockType* block, Status status)
121 status, Prev::kUnchanged, Next::kUnchanged, 0),
122 block_(block) {}
123
124 constexpr BlockResult(BlockType* block, Prev prev)
125 : BlockResult(block, prev, Next::kUnchanged, 0) {}
126
127 constexpr BlockResult(BlockType* block, Prev prev, size_t shifted_to_prev)
128 : BlockResult(block, prev, Next::kUnchanged, shifted_to_prev) {}
129
130 constexpr BlockResult(BlockType* block, Next next)
131 : BlockResult(block, Prev::kUnchanged, next, 0) {}
132
133 constexpr BlockResult(BlockType* block, Prev prev, Next next)
134 : BlockResult(block, prev, next, 0) {}
135
136 constexpr BlockResult(BlockType* block,
137 Prev prev,
138 Next next,
139 size_t shifted_to_prev)
140 : internal::GenericBlockResult(OkStatus(), prev, next, shifted_to_prev),
141 block_(block) {
142 if constexpr (Hardening::kIncludesDebugChecks) {
143 block->CheckInvariants();
144 }
145 }
146
147 [[nodiscard]] constexpr BlockType* block() const { return block_; }
148
149 private:
150 BlockType* block_ = nullptr;
151};
152
153} // namespace pw::allocator
Definition: status.h:85
constexpr bool ok() const
True if status() == OkStatus().
Definition: status_with_size.h:152
constexpr size_t size() const
Definition: status_with_size.h:146
Definition: result.h:114
constexpr void IgnoreUnlessStrict() const
Definition: result.h:76
constexpr Status OkStatus()
Definition: status.h:234