mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 00:50:22 +00:00
Add Error<>
Put simply, Error<> is a way of forcing error handling onto an API user. Given a function like: bool might_work(); The following code might have been written previously: might_work(); // but what if it didn't? The easy way to work around this is of course to [[nodiscard]] might_work. But this doesn't work for more complex cases like, for instance, a hypothetical read() function which might return one of _many_ errors (typically signalled with an int, let's say). int might_read(); In such a case, the result is often _read_, but not properly handled. Like: return buffer.substr(0, might_read()); // but what if might_read returned an error? This is where Error<> comes in: typedef Error<int, 0> ReadError; ReadError might_read(); auto res = might_read(); if (might_read.failed()) { switch (res.value()) { case EBADF: ... } } Error<> uses clang's consumable attributes to force failed() to be checked on an Error instance. If it's not checked, then you get smacked.
This commit is contained in:
parent
28362fcc57
commit
7dd25141cd
Notes:
sideshowbarker
2024-07-19 12:58:58 +09:00
Author: https://github.com/rburchell Commit: https://github.com/SerenityOS/serenity/commit/7dd25141cdd Pull-request: https://github.com/SerenityOS/serenity/pull/385
1 changed files with 53 additions and 0 deletions
53
AK/Error.h
Normal file
53
AK/Error.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Platform.h>
|
||||
|
||||
namespace AK {
|
||||
|
||||
template <typename T, auto NoErrorValue>
|
||||
class CONSUMABLE(unknown) Error {
|
||||
public:
|
||||
RETURN_TYPESTATE(unknown)
|
||||
Error()
|
||||
: t(NoErrorValue)
|
||||
{}
|
||||
|
||||
RETURN_TYPESTATE(unknown)
|
||||
Error(T t)
|
||||
: t(t)
|
||||
{}
|
||||
|
||||
RETURN_TYPESTATE(unknown)
|
||||
Error(Error&& other)
|
||||
: t(move(other.t))
|
||||
{
|
||||
}
|
||||
|
||||
RETURN_TYPESTATE(unknown)
|
||||
Error(const Error& other)
|
||||
: t(other.t)
|
||||
{
|
||||
}
|
||||
|
||||
CALLABLE_WHEN("unknown", "consumed")
|
||||
~Error() {}
|
||||
|
||||
SET_TYPESTATE(consumed)
|
||||
bool failed() const {
|
||||
return t != NoErrorValue;
|
||||
}
|
||||
|
||||
[[deprecated]]
|
||||
SET_TYPESTATE(consumed)
|
||||
void ignore() {}
|
||||
|
||||
const T& value() const { return t; }
|
||||
|
||||
bool operator==(const Error& o) { return t == o.t; }
|
||||
bool operator!=(const Error& o) { return t != o.t; }
|
||||
T t;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using AK::Error;
|
Loading…
Reference in a new issue