mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-13 22:23:45 +00:00
util/attempt.h: add 'Unique_attempt' utility
The new variant combines the attempt with unique-pointer semantics and is thereby usable for returning non-copyable objects such as RAM 'Allocation'. Issue #5502
This commit is contained in:
parent
7d4b6b6bd5
commit
2dfaeab7c2
@ -14,7 +14,12 @@
|
||||
#ifndef _INCLUDE__UTIL__ATTEMPT_H_
|
||||
#define _INCLUDE__UTIL__ATTEMPT_H_
|
||||
|
||||
namespace Genode { template <typename, typename> struct Attempt; }
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
namespace Genode {
|
||||
template <typename, typename> struct Attempt;
|
||||
template <typename, typename> struct Unique_attempt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -80,4 +85,67 @@ class Genode::Attempt
|
||||
bool failed() const { return !_ok; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base type for the result of constrained RAM allocations
|
||||
*
|
||||
* The type is a unique pointer to the allocated RAM while also holding
|
||||
* allocation-error information, following the conventions of 'Attempt'.
|
||||
*/
|
||||
template <typename RESULT, typename ERROR>
|
||||
class Genode::Unique_attempt : Noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
Constructible<RESULT> _result { };
|
||||
|
||||
ERROR _error { };
|
||||
|
||||
protected:
|
||||
|
||||
void _construct(auto &&... args) { _result.construct(args...); }
|
||||
void _destruct (ERROR e) { _result.destruct(); _error = e; }
|
||||
|
||||
public:
|
||||
|
||||
Unique_attempt(auto &&... args) { _result.construct(args...); }
|
||||
Unique_attempt(ERROR error) { _destruct(error); }
|
||||
|
||||
template <typename RET>
|
||||
RET convert(auto const &access_fn, auto const &fail_fn)
|
||||
{
|
||||
return _result.constructed() ? RET { access_fn(*_result) }
|
||||
: RET { fail_fn(_error) };
|
||||
}
|
||||
|
||||
template <typename RET>
|
||||
RET convert(auto const &access_fn, auto const &fail_fn) const
|
||||
{
|
||||
return _result.constructed() ? RET { access_fn(*_result) }
|
||||
: RET { fail_fn(_error) };
|
||||
}
|
||||
|
||||
void with_result(auto const &access_fn, auto const &fail_fn)
|
||||
{
|
||||
_result.constructed() ? access_fn(*_result) : fail_fn(_error);
|
||||
}
|
||||
|
||||
void with_result(auto const &access_fn, auto const &fail_fn) const
|
||||
{
|
||||
_result.constructed() ? access_fn(*_result) : fail_fn(_error);
|
||||
}
|
||||
|
||||
void with_error(auto const &fail_fn) const
|
||||
{
|
||||
if (!_result.constructed())
|
||||
fail_fn(_error);
|
||||
}
|
||||
|
||||
bool operator == (ERROR const &rhs) const {
|
||||
return failed() && (_error == rhs); }
|
||||
|
||||
bool ok() const { return _result.constructed(); }
|
||||
bool failed() const { return !_result.constructed(); }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__UTIL__ATTEMPT_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user