dius 0.1.0
Loading...
Searching...
No Matches
error.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/container/algorithm/max.h"
4#include "di/vocab/error/status_code.h"
6
7namespace di::platform {
9
10class GenericDomain;
11
12using GenericCode = vocab::StatusCode<GenericDomain>;
13
14class GenericDomain final : public vocab::StatusCodeDomain {
15private:
16 using Base = vocab::StatusCodeDomain;
17
18public:
20 using UniqueId = Base::UniqueId;
21
22 constexpr explicit GenericDomain(UniqueId id = 0xff261d32b71e0a8a) : Base(id) {}
23
24 GenericDomain(GenericDomain const&) = default;
26
27 auto operator=(GenericDomain const&) -> GenericDomain& = default;
28 auto operator=(GenericDomain&&) -> GenericDomain& = default;
29
30 constexpr static auto get() -> GenericDomain const&;
31
32 auto name() const -> di::container::ErasedString override { return container::ErasedString(u8"Posix) Domain"); }
33
34 auto payload_info() const -> PayloadInfo override {
35 return { sizeof(Value), sizeof(Value) + sizeof(StatusCodeDomain const*),
36 di::container::max(alignof(Value), alignof(StatusCodeDomain const*)) };
37 }
38
39protected:
40 constexpr auto do_failure(vocab::StatusCode<void> const& code) const -> bool override {
41 return down_cast(code).value() != BasicError::Success;
42 }
43
44 constexpr auto do_equivalent(vocab::StatusCode<void> const& a, vocab::StatusCode<void> const& b) const
45 -> bool override {
46 DI_ASSERT(a.domain() == *this);
47 return b.domain() == *this && down_cast(a).value() == down_cast(b).value();
48 }
49
50 constexpr auto do_convert_to_generic(vocab::StatusCode<void> const& a) const -> vocab::GenericCode override {
51 DI_ASSERT(a.domain() == *this);
52 return vocab::GenericCode(di::in_place, down_cast(a).value());
53 }
54
55 // NOLINTNEXTLINE(readability-function-cognitive-complexity)
56 constexpr auto do_message(vocab::StatusCode<void> const& code) const -> di::container::ErasedString override {
57 auto value = down_cast(code).value();
58 if (value == BasicError::Success) {
59 return container::ErasedString(u8"Success");
60 }
61 if (value == BasicError::AddressFamilyNotSupported) {
62 return container::ErasedString(u8"Address familty not supported");
63 }
64 if (value == BasicError::AddressInUse) {
65 return container::ErasedString(u8"Address in use");
66 }
67 if (value == BasicError::AddressNotAvailable) {
68 return container::ErasedString(u8"Address not available");
69 }
70 if (value == BasicError::AlreadyConnected) {
71 return container::ErasedString(u8"Already connected");
72 }
73 if (value == BasicError::ArgumentListTooLong) {
74 return container::ErasedString(u8"Argument list too long");
75 }
76 if (value == BasicError::ArgumentOutOfDomain) {
77 return container::ErasedString(u8"Argument out of domain");
78 }
79 if (value == BasicError::BadAddress) {
80 return container::ErasedString(u8"Bad address");
81 }
82 if (value == BasicError::BadFileDescriptor) {
83 return container::ErasedString(u8"Bad file descriptor");
84 }
85 if (value == BasicError::BadMessage) {
86 return container::ErasedString(u8"Bad message");
87 }
88 if (value == BasicError::BrokenPipe) {
89 return container::ErasedString(u8"Broken pipe");
90 }
91 if (value == BasicError::ConnectionAborted) {
92 return container::ErasedString(u8"Connect aborted");
93 }
94 if (value == BasicError::ConnectionAlreadyInProgress) {
95 return container::ErasedString(u8"Connection already in progress");
96 }
97 if (value == BasicError::ConnectionRefused) {
98 return container::ErasedString(u8"Connection refused");
99 }
100 if (value == BasicError::ConnectionReset) {
101 return container::ErasedString(u8"Connection reset");
102 }
103 if (value == BasicError::CrossDeviceLink) {
104 return container::ErasedString(u8"Cross device link");
105 }
106 if (value == BasicError::DestinationAddressRequired) {
107 return container::ErasedString(u8"Destination address required");
108 }
109 if (value == BasicError::DeviceOrResourceBusy) {
110 return container::ErasedString(u8"Device or resource busy");
111 }
112 if (value == BasicError::DirectoryNotEmpty) {
113 return container::ErasedString(u8"Directory not empty");
114 }
115 if (value == BasicError::ExecutableFormatError) {
116 return container::ErasedString(u8"Executable format error");
117 }
118 if (value == BasicError::FileExists) {
119 return container::ErasedString(u8"File exists");
120 }
121 if (value == BasicError::FileTooLarge) {
122 return container::ErasedString(u8"File too large");
123 }
124 if (value == BasicError::FilenameTooLong) {
125 return container::ErasedString(u8"Filename too long");
126 }
127 if (value == BasicError::FunctionNotSupported) {
128 return container::ErasedString(u8"Function not supported");
129 }
130 if (value == BasicError::HostUnreachable) {
131 return container::ErasedString(u8"Host unreachable");
132 }
133 if (value == BasicError::IdentifierRemoved) {
134 return container::ErasedString(u8"Identifier removed");
135 }
136 if (value == BasicError::IllegalByteSequence) {
137 return container::ErasedString(u8"Illegal byte sequence");
138 }
139 if (value == BasicError::InappropriateIoControlOperation) {
140 return container::ErasedString(u8"Inappropriate io control operation");
141 }
142 if (value == BasicError::Interrupted) {
143 return container::ErasedString(u8"Interrupted");
144 }
145 if (value == BasicError::InvalidArgument) {
146 return container::ErasedString(u8"Invalid argument");
147 }
148 if (value == BasicError::InvalidSeek) {
149 return container::ErasedString(u8"Invalid seek");
150 }
151 if (value == BasicError::IoError) {
152 return container::ErasedString(u8"IO error");
153 }
154 if (value == BasicError::IsADirectory) {
155 return container::ErasedString(u8"Is a directory");
156 }
157 if (value == BasicError::MessageSize) {
158 return container::ErasedString(u8"Message size");
159 }
160 if (value == BasicError::NetworkDown) {
161 return container::ErasedString(u8"Network down");
162 }
163 if (value == BasicError::NetworkReset) {
164 return container::ErasedString(u8"Network reset");
165 }
166 if (value == BasicError::NetworkUnreachable) {
167 return container::ErasedString(u8"Network unreachable");
168 }
169 if (value == BasicError::NoBufferSpace) {
170 return container::ErasedString(u8"No buffer space");
171 }
172 if (value == BasicError::NoChildProcess) {
173 return container::ErasedString(u8"No child process");
174 }
175 if (value == BasicError::NoLink) {
176 return container::ErasedString(u8"No link");
177 }
178 if (value == BasicError::NoLockAvailable) {
179 return container::ErasedString(u8"No lock available");
180 }
181 if (value == BasicError::NoMessageAvailable) {
182 return container::ErasedString(u8"No message available");
183 }
184 if (value == BasicError::NoMessage) {
185 return container::ErasedString(u8"No message");
186 }
187 if (value == BasicError::NoProtocolOption) {
188 return container::ErasedString(u8"No protocol option");
189 }
190 if (value == BasicError::NoSpaceOnDevice) {
191 return container::ErasedString(u8"No space on device");
192 }
193 if (value == BasicError::NoStreamResources) {
194 return container::ErasedString(u8"No stream resources");
195 }
196 if (value == BasicError::NoSuchDeviceOrAddress) {
197 return container::ErasedString(u8"No such device or address");
198 }
199 if (value == BasicError::NoSuchDevice) {
200 return container::ErasedString(u8"No such device");
201 }
202 if (value == BasicError::NoSuchFileOrDirectory) {
203 return container::ErasedString(u8"No such file or directory");
204 }
205 if (value == BasicError::NoSuchProcess) {
206 return container::ErasedString(u8"No such process");
207 }
208 if (value == BasicError::NotADirectory) {
209 return container::ErasedString(u8"Not a directory");
210 }
211 if (value == BasicError::NotASocket) {
212 return container::ErasedString(u8"Not a socket");
213 }
214 if (value == BasicError::NotAStream) {
215 return container::ErasedString(u8"Not a stream");
216 }
217 if (value == BasicError::NotConnected) {
218 return container::ErasedString(u8"Not connected");
219 }
220 if (value == BasicError::NotEnoughMemory) {
221 return container::ErasedString(u8"Not enough memory");
222 }
223 if (value == BasicError::OperationCanceled) {
224 return container::ErasedString(u8"Operation cancelled");
225 }
226 if (value == BasicError::OperationInProgress) {
227 return container::ErasedString(u8"Operation in progress");
228 }
229 if (value == BasicError::OperationNotPermitted) {
230 return container::ErasedString(u8"Operation not permitted");
231 }
232 if (value == BasicError::NotSupported) {
233 return container::ErasedString(u8"Not supported");
234 }
235 if (value == BasicError::OperationNotSupported) {
236 return container::ErasedString(u8"Operation not supported");
237 }
238 if (value == BasicError::OperationWouldBlock) {
239 return container::ErasedString(u8"Operation would block");
240 }
241 if (value == BasicError::OwnerDead) {
242 return container::ErasedString(u8"Owner dead");
243 }
244 if (value == BasicError::PermissionDenied) {
245 return container::ErasedString(u8"Permission denied");
246 }
247 if (value == BasicError::ProtocolError) {
248 return container::ErasedString(u8"Protocol error");
249 }
250 if (value == BasicError::ProtocolNotSupported) {
251 return container::ErasedString(u8"Protocol not supported");
252 }
253 if (value == BasicError::ReadOnlyFileSystem) {
254 return container::ErasedString(u8"Read only file system");
255 }
256 if (value == BasicError::ResourceDeadlockWouldOccur) {
257 return container::ErasedString(u8"Resource deadlock would occur");
258 }
259 if (value == BasicError::ResourceUnavailableTryAgain) {
260 return container::ErasedString(u8"Resource unavailable try again");
261 }
262 if (value == BasicError::ResultOutOfRange) {
263 return container::ErasedString(u8"Result out of range");
264 }
265 if (value == BasicError::StateNotRecoverable) {
266 return container::ErasedString(u8"State not recoverable");
267 }
268 if (value == BasicError::StreamTimeout) {
269 return container::ErasedString(u8"Stream timeout");
270 }
271 if (value == BasicError::TextFileBusy) {
272 return container::ErasedString(u8"Text file busy");
273 }
274 if (value == BasicError::TimedOut) {
275 return container::ErasedString(u8"Timed out");
276 }
277 if (value == BasicError::TooManyFilesOpenInSystem) {
278 return container::ErasedString(u8"Too many files open in system");
279 }
280 if (value == BasicError::TooManyFilesOpen) {
281 return container::ErasedString(u8"Too many files open");
282 }
283 if (value == BasicError::TooManyLinks) {
284 return container::ErasedString(u8"Too many links");
285 }
286 if (value == BasicError::TooManySymbolicLinkLevels) {
287 return container::ErasedString(u8"Too many symbolic link levels");
288 }
289 if (value == BasicError::ValueTooLarge) {
290 return container::ErasedString(u8"Value too large");
291 }
292 if (value == BasicError::WrongProtocolType) {
293 return container::ErasedString(u8"Wrong protocol type");
294 }
295 return container::ErasedString(u8"(Unknown)");
296 }
297
298private:
299 template<typename Domain>
301
302 constexpr auto down_cast(vocab::StatusCode<void> const& code) const -> GenericCode const& {
303 DI_ASSERT(code.domain() == *this);
304 return static_cast<GenericCode const&>(code);
305 }
306};
307
308#ifdef DI_SANITIZER
309// When compiling with UBSAN, using the address of a constexpr inline variable fails.
310// This includes checking for nullptr. To work around this, do not declare the variable
311// as inline when compiling with a sanitizer.
312// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962.
313// As a side note, this means there will be multiple copies of the generic_domain object
314// in a user's program. This is perfectly fine, since we make sure to compare domains by
315// their unique id and not their address, which is necessary even for inline variables when
316// in the presence of dynamic linking.
317constexpr auto generic_domain = GenericDomain {};
318#else
319constexpr inline auto generic_domain = GenericDomain {};
320#endif
321
322constexpr auto GenericDomain::get() -> GenericDomain const& {
323 return generic_domain;
324}
325}
326
328constexpr auto tag_invoke(di::types::Tag<di::vocab::into_status_code>, di::platform::BasicError error) {
329 return di::platform::GenericCode(di::in_place, error);
330}
331}
332
333namespace di::vocab {
334constexpr auto StatusCode<void>::generic_code() const -> GenericCode {
335 if (!this->empty()) {
336 return this->domain().do_convert_to_generic(*this);
337 }
338 return GenericCode(di::in_place, platform::BasicError::InvalidArgument);
339}
340}
Definition error.h:14
auto operator=(GenericDomain &&) -> GenericDomain &=default
Base::UniqueId UniqueId
Definition error.h:20
constexpr auto do_equivalent(vocab::StatusCode< void > const &a, vocab::StatusCode< void > const &b) const -> bool override
Definition error.h:44
auto payload_info() const -> PayloadInfo override
Definition error.h:34
auto operator=(GenericDomain const &) -> GenericDomain &=default
constexpr auto do_convert_to_generic(vocab::StatusCode< void > const &a) const -> vocab::GenericCode override
Definition error.h:50
auto name() const -> di::container::ErasedString override
Definition error.h:32
GenericDomain(GenericDomain const &)=default
static constexpr auto get() -> GenericDomain const &
Definition error.h:322
friend class di::vocab::StatusCode
Definition error.h:300
BasicError Value
Definition error.h:19
constexpr auto do_message(vocab::StatusCode< void > const &code) const -> di::container::ErasedString override
Definition error.h:56
constexpr auto do_failure(vocab::StatusCode< void > const &code) const -> bool override
Definition error.h:40
constexpr GenericDomain(UniqueId id=0xff261d32b71e0a8a)
Definition error.h:22
GenericDomain(GenericDomain &&)=default
Definition error.h:7
constexpr auto generic_domain
Definition error.h:319
vocab::StatusCode< GenericDomain > GenericCode
Definition error.h:12
dius::PosixError BasicError
Definition error.h:8
Definition error.h:327
constexpr auto tag_invoke(di::types::Tag< di::vocab::into_status_code >, di::platform::BasicError error)
Definition error.h:328
Definition error.h:327
Definition error.h:7
PosixError
Definition platform_error.h:7