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