27 #ifndef LELY_UTIL_RESULT_HPP_
28 #define LELY_UTIL_RESULT_HPP_
32 #include <type_traits>
47 template <
class U,
class = typename ::std::enable_if<!::std::is_same<
48 typename ::std::decay<U>::type,
Success>::value>::type>
49 Success(U&& u) : value_(::std::forward<U>(u)) {}
63 return ::std::move(value_);
68 return ::std::move(value_);
78 using value_type = void;
88 template <
class U,
class = typename ::std::enable_if<!::std::is_same<
89 typename ::std::decay<U>::type,
Failure>::value>::type>
90 Failure(U&& u) : error_(::std::forward<U>(u)) {}
104 return ::std::move(error_);
109 return ::std::move(error_);
121 using error_type = int;
123 static constexpr
bool
124 is_error(error_type
error) noexcept {
129 throw_error(error_type
error,
const char* what_arg) {
136 using error_type = ::std::error_code;
139 is_error(error_type
error) noexcept {
140 return error.value() != 0;
144 throw_error(error_type
error,
const char* what_arg) {
145 throw ::std::system_error(
error, what_arg);
151 using error_type = ::std::exception_ptr;
154 is_error(
const error_type&
error) noexcept {
155 return error !=
nullptr;
159 throw_error(error_type
error,
const char* ) {
160 ::std::rethrow_exception(::std::move(
error));
180 inline detail::Success<typename ::std::decay<T>::type>
182 return {::std::forward<T>(t)};
190 inline detail::Failure<typename ::std::decay<E>::type>
192 return {::std::forward<E>(e)};
199 template <
class T,
class E = ::std::error_code>
238 ::std::is_constructible<value_type, U>::value &&
239 !::std::is_constructible<error_type, U>::value,
242 : value_{::std::forward<U>(u)} {}
250 !::std::is_constructible<value_type, U>::value &&
251 ::std::is_constructible<error_type, U>::value,
254 : error_{::std::forward<U>(u)} {}
257 explicit operator bool() const noexcept {
return has_value(); }
275 if (
has_error()) error_traits::throw_error(error_,
"value");
285 if (
has_error()) error_traits::throw_error(error_,
"value");
292 return error_traits::is_error(error_);
313 class Result<T, typename ::std::enable_if<!::std::is_void<T>::value>::type> {
315 using value_type = T;
316 using error_type = void;
328 template <
class U,
typename = typename ::std::enable_if<
329 ::std::is_constructible<value_type, U>::value>::type>
332 Result(U&& u) : value_{::std::forward<U>(u)} {}
334 explicit operator bool()
const noexcept {
return has_value(); }
347 value()
const noexcept {
357 error()
const noexcept {}
368 using value_type = void;
369 using error_type =
typename error_traits::error_type;
383 template <
class U,
typename = typename ::std::enable_if<
384 ::std::is_constructible<error_type, U>::value>::type>
387 Result(U&& u) : error_{::std::forward<U>(u)} {}
389 explicit operator bool()
const noexcept {
return has_value(); }
398 if (
has_error()) error_traits::throw_error(error_,
"value");
403 return error_traits::is_error(error_);
412 error()
const noexcept {
423 using value_type = void;
424 using error_type = void;
431 explicit operator bool()
const noexcept {
return has_value(); }
439 value()
const noexcept {}
447 error()
const noexcept {}
The type of objects thrown as exceptions to report a system error with an associated error code.
A type capable of representing both the successful and failure result of an operation.
Result(const detail::Success< U > &s)
Constructs a successful result with the specified value.
const error_type & error() const noexcept
Returns a reference to the error, if any.
bool has_error() const noexcept
Returns true if *this contains a non-zero error.
Result()=default
Constructs a successful result with an empty value.
Result(const detail::Failure< U > &f)
Constructs a failure result with the specified error.
Result(const detail::Success< void > &)
Constructs a successful result with an empty value.
const value_type & value() const
Returns a reference to the value if *this contains a value, and throws an exception if *this contains...
T value_type
The value type on success.
bool has_value() const noexcept
Returns true if *this contains a value (and not a non-zero error).
typename error_traits::error_type error_type
The error type on failure.
Result(detail::Success< U > &&s)
Constructs a successful result with the specified value.
Result(U &&u, typename ::std::enable_if< ::std::is_constructible< value_type, U >::value &&!::std::is_constructible< error_type, U >::value, bool >::type=false)
Constructs a successful result with value u if U is constructible to value_type and not constructible...
value_type & value()
Returns a reference to the value if *this contains a value, and throws an exception if *this contains...
Result(detail::Failure< U > &&f)
Constructs a failure result with the specified error.
Result(U &&u, typename ::std::enable_if< !::std::is_constructible< value_type, U >::value &&::std::is_constructible< error_type, U >::value, bool >::type=false)
Constructs a failure result with error u if U is constructible to error_type and not constructible to...
error_type & error() noexcept
Returns a reference to the error, if any.
This header file is part of the utilities library; it contains C++ convenience functions for creating...
void throw_errc(int errc=get_errc())
Throws an std::system_error exception corresponding to the specified or current (thread-specific) nat...
detail::Success< void > success() noexcept
Returns an object that can be used to implicitly construct a successful lely::util::Result with a def...
detail::Failure< typename ::std::decay< E >::type > failure(E &&e) noexcept
Returns an object that can be used to implicitly construct a failure lely::util::Result with the spec...