Pigweed
 
Loading...
Searching...
No Matches
status_with_size.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 <type_traits>
18
19#include "pw_status/status.h"
20
21namespace pw {
22
49class _PW_STATUS_NO_DISCARD StatusWithSize {
50 public:
51 static constexpr StatusWithSize Cancelled(size_t size = 0) {
52 return StatusWithSize(Status::Cancelled(), size);
53 }
54 static constexpr StatusWithSize Unknown(size_t size = 0) {
55 return StatusWithSize(Status::Unknown(), size);
56 }
57 static constexpr StatusWithSize InvalidArgument(size_t size = 0) {
58 return StatusWithSize(Status::InvalidArgument(), size);
59 }
60 static constexpr StatusWithSize DeadlineExceeded(size_t size = 0) {
61 return StatusWithSize(Status::DeadlineExceeded(), size);
62 }
63 static constexpr StatusWithSize NotFound(size_t size = 0) {
64 return StatusWithSize(Status::NotFound(), size);
65 }
66 static constexpr StatusWithSize AlreadyExists(size_t size = 0) {
67 return StatusWithSize(Status::AlreadyExists(), size);
68 }
69 static constexpr StatusWithSize PermissionDenied(size_t size = 0) {
70 return StatusWithSize(Status::PermissionDenied(), size);
71 }
72 static constexpr StatusWithSize Unauthenticated(size_t size = 0) {
73 return StatusWithSize(Status::Unauthenticated(), size);
74 }
75 static constexpr StatusWithSize ResourceExhausted(size_t size = 0) {
76 return StatusWithSize(Status::ResourceExhausted(), size);
77 }
78 static constexpr StatusWithSize FailedPrecondition(size_t size = 0) {
79 return StatusWithSize(Status::FailedPrecondition(), size);
80 }
81 static constexpr StatusWithSize Aborted(size_t size = 0) {
82 return StatusWithSize(Status::Aborted(), size);
83 }
84 static constexpr StatusWithSize OutOfRange(size_t size = 0) {
85 return StatusWithSize(Status::OutOfRange(), size);
86 }
87 static constexpr StatusWithSize Unimplemented(size_t size = 0) {
88 return StatusWithSize(Status::Unimplemented(), size);
89 }
90 static constexpr StatusWithSize Internal(size_t size = 0) {
91 return StatusWithSize(Status::Internal(), size);
92 }
93 static constexpr StatusWithSize Unavailable(size_t size = 0) {
94 return StatusWithSize(Status::Unavailable(), size);
95 }
96 static constexpr StatusWithSize DataLoss(size_t size = 0) {
97 return StatusWithSize(Status::DataLoss(), size);
98 }
99
101 explicit constexpr StatusWithSize() : size_(0) {}
102
106 template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
107 explicit constexpr StatusWithSize(T size) : size_(static_cast<size_t>(size)) {
108 // TODO(hepler): Add debug-only assert that size <= max_size().
109 }
110
112 explicit constexpr StatusWithSize(Status status, size_t size)
113 : StatusWithSize((static_cast<size_t>(status.code()) << kStatusShift) |
114 size) {}
115
116 constexpr StatusWithSize(const StatusWithSize&) = default;
117 constexpr StatusWithSize& operator=(const StatusWithSize&) = default;
118
126 constexpr void UpdateAndAdd(StatusWithSize new_status_with_size) {
127 Status new_status;
128 if (ok()) {
129 new_status = new_status_with_size.status();
130 } else {
131 new_status = status();
132 }
133 size_t new_size = size() + new_status_with_size.size();
134 *this = StatusWithSize(new_status, new_size);
135 }
136
138 constexpr void ZeroIfNotOk() {
139 if (!ok()) {
140 *this = StatusWithSize(status(), 0);
141 }
142 }
143
146 [[nodiscard]] constexpr size_t size() const { return size_ & kSizeMask; }
147
149 [[nodiscard]] static constexpr size_t max_size() { return kSizeMask; }
150
152 [[nodiscard]] constexpr bool ok() const {
153 return (size_ & kStatusMask) == 0u;
154 }
155
159 constexpr void IgnoreError() const {}
160
161 [[nodiscard]] constexpr Status status() const {
162 return static_cast<Status::Code>((size_ & kStatusMask) >> kStatusShift);
163 }
164
165 // Functions for checking which status the StatusWithSize contains.
166 [[nodiscard]] constexpr bool IsCancelled() const {
167 return status().IsCancelled();
168 }
169 [[nodiscard]] constexpr bool IsUnknown() const {
170 return status().IsUnknown();
171 }
172 [[nodiscard]] constexpr bool IsInvalidArgument() const {
173 return status().IsInvalidArgument();
174 }
175 [[nodiscard]] constexpr bool IsDeadlineExceeded() const {
176 return status().IsDeadlineExceeded();
177 }
178 [[nodiscard]] constexpr bool IsNotFound() const {
179 return status().IsNotFound();
180 }
181 [[nodiscard]] constexpr bool IsAlreadyExists() const {
182 return status().IsAlreadyExists();
183 }
184 [[nodiscard]] constexpr bool IsPermissionDenied() const {
185 return status().IsPermissionDenied();
186 }
187 [[nodiscard]] constexpr bool IsResourceExhausted() const {
188 return status().IsResourceExhausted();
189 }
190 [[nodiscard]] constexpr bool IsFailedPrecondition() const {
191 return status().IsFailedPrecondition();
192 }
193 [[nodiscard]] constexpr bool IsAborted() const {
194 return status().IsAborted();
195 }
196 [[nodiscard]] constexpr bool IsOutOfRange() const {
197 return status().IsOutOfRange();
198 }
199 [[nodiscard]] constexpr bool IsUnimplemented() const {
200 return status().IsUnimplemented();
201 }
202 [[nodiscard]] constexpr bool IsInternal() const {
203 return status().IsInternal();
204 }
205 [[nodiscard]] constexpr bool IsUnavailable() const {
206 return status().IsUnavailable();
207 }
208 [[nodiscard]] constexpr bool IsDataLoss() const {
209 return status().IsDataLoss();
210 }
211 [[nodiscard]] constexpr bool IsUnauthenticated() const {
212 return status().IsUnauthenticated();
213 }
214
215 private:
216 static constexpr size_t kStatusBits = 5;
217 static constexpr size_t kSizeMask = ~static_cast<size_t>(0) >> kStatusBits;
218 static constexpr size_t kStatusMask = ~kSizeMask;
219 static constexpr size_t kStatusShift = sizeof(size_t) * 8 - kStatusBits;
220
221 size_t size_;
222};
223
224namespace internal {
225
226constexpr Status ConvertToStatus(StatusWithSize status_with_size) {
227 return status_with_size.status();
228}
229
230constexpr size_t ConvertToValue(StatusWithSize status_with_size) {
231 return status_with_size.size();
232}
233
234constexpr StatusWithSize ConvertToStatusWithSize(Status status) {
235 return StatusWithSize(status, 0);
236}
237
238constexpr StatusWithSize ConvertToStatusWithSize(
239 StatusWithSize status_with_size) {
240 return status_with_size;
241}
242
243} // namespace internal
244} // namespace pw
Definition: status.h:85
Definition: status_with_size.h:49
constexpr void IgnoreError() const
Definition: status_with_size.h:159
constexpr StatusWithSize(Status status, size_t size)
Creates a StatusWithSize with the provided status and size.
Definition: status_with_size.h:112
static constexpr size_t max_size()
The maximum valid value for size.
Definition: status_with_size.h:149
constexpr void UpdateAndAdd(StatusWithSize new_status_with_size)
Definition: status_with_size.h:126
constexpr void ZeroIfNotOk()
Zeroes the size if the status is not OK.
Definition: status_with_size.h:138
constexpr StatusWithSize()
Creates a StatusWithSize with status OK and a size of 0.
Definition: status_with_size.h:101
constexpr StatusWithSize(T size)
Definition: status_with_size.h:107
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
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27