Error handling (error_or)¶
-
class
bad_error_or_access
: public std::exception¶ Thrown by
error_or
if an object is coerced to a value if it contains an error or if it is coerced to an error if it contains a value.
-
template<typename
T
, typenameErr
= std::error_code>
classerror_or
¶ An instance of
error_or
may contain either an error (of typeErr
) or a value (of typeT
).In addition to methods to query whether an object contains an error or a value,
error_or
provides an apply operation and a reduce operation. The apply operation can be used to transform an object that contains a value, but retain the error if the object does not contain a value. The reduce operation can be used to transform anerror_or
into a new value regardless of whether it contained a value or an error.The template types
T
andErr
must both be complete types that are move-constructible and are neither an array type, reference type, or function type.Err
must also be default-constructible and copy-constructible; it is recommended to ensure thatErr
is trivially copy- and move-constructible. All operations ofErr
must be noexcept. (This restriction is placed onErr
to make all operations onerror_or
instances with errors uniformly noexcept.)Example:
using nu::error_or; using nu::make_error_or; // default-constructed objects contain Err(), which by default is std::error_code error_or<int> e; error_or<int> i(1); // et will still contain Err() error_or<int> et = e / [] (int i) { return i+1; }; ASSERT_EQ(et.error(), std::error_code()); // it will contain 2 error_or<int> it = i / [] (int i) { return i+1; }; ASSERT_EQ(it.value(), 2); // er will be set to -1 int er = e.reduce( [] (int i) { return i; }, [] (std::error_code) { return -1; }); ASSERT_EQ(er, -1); // ir will be set to 1 int ir = i.reduce( [] (int i) { return i; }, [] (std::error_code) { return -1; }); ASSERT_EQ(ir, 1); // % can be used to chain operations that may themselves fail error_or<double> d = make_error_or<int>(1) / [] (int i) { return i - 1; } % [] (int i) -> error_or<double> { if (i != 0) return i * 3.14; else return {std::make_error_code(std::errc::invalid_argument)}; }; ASSERT_FALSE(d);
-
error_or
() noexcept¶ Constructs the object holding a default-constructed
Err
as itserror()
.Noexcept: noexcept
-
error_or
(Err e) noexcept¶ Constructs the object holding a e as its
error()
. The value is moved into the newly constructed object.Noexcept: noexcept
-
error_or
(T value)¶ Constructs the object holding
value
as itsvalue()
. The provided value is moved into the object.Noexcept: noexcept
if the move constructor ofT
isnoexcept
-
error_or
(error_or &&other)¶ Constructs the object with the state of
other
. The state ofother
is moved into the newly constructed object;other
is in an indefinite state afterwards.Noexcept: noexcept
if the function<unspecified> swap(T&, T&)
isnoexcept
, whereswap
is eitherstd::swap
or found by ADL.
-
error_or &
operator=
(error_or &&other)¶ Moves the state of
other
into*this
. Afterwards,other
is in an indefinite state.Noexcept: noexcept
if the function<unspecified> swap(T&, T&)
isnoexcept
, whereswap
is eitherstd::swap
or found by ADL.
-
void
swap
(error_or &other)¶ Swaps the states of
*this
andother
.Noexcept: noexcept
if the function<unspecified> swap(T&, T&)
isnoexcept
, whereswap
is eitherstd::swap
or found by ADL.
-
explicit
operator bool
() const noexcept¶ Returns: true
if*this
contains a value,false
otherwiseNoexcept: noexcept
-
bool
operator!
() const noexcept¶ Returns: false
if*this
contains a value,true
otherwiseNoexcept: noexcept
-
template<typename
Fn
>
autooperator/
(Fn f)¶ If
*this
contains a value, callsf(get_or_release())
and returns the result as anerror_or<R>
object, whereR
is the return type ofFn
.These operators are useful because they can provide exception guarantees that the usual sequences
if (e) on_value(e.value()); else on_error(e.error());
cannot provide, since bothvalue()
anderror()
may throw.Returns: *this ? error_or<R>(f(get_or_release())) : error_or<R>(error())
Noexcept: noexcept
iff
isnoexcept
-
template<typename
R
= void, typenameTrueFn
, typenameFalseFn
>
autoreduce
(TrueFn t, FalseFn f) const¶
-
template<typename
R
= void, typenameTrueFn
, typenameFalseFn
>
autoreduce
(TrueFn t, FalseFn f)¶ If
*this
contains a value, callst(get_or_release())
, otherwise callsf(error())
. The result of botht(get_or_release())
andf(error())
is converted to typeRT
and returned, whereRT
isR
ifR
is notvoid
, otherwisestd:common_type<TT, FT>::type
whereTT
andFT
are the result types oft(get_or_release())
andf(error())
respectively. The result types oft
andf
must each be a complete type that is neither an array type, a reference type, or a function type.These functions are useful because they can provide exception guarantees that the usual sequences
if (e) on_value(e.value()); else on_error(e.error());
cannot provide, since bothvalue()
anderror()
may throw.Returns: *this ? t(get_or_release()) : f(error())
Noexcept: noexcept
ift
isnoexcept
andf
isnoexcept
.
-
template<typename
Fn
>
autooperator%
(Fn f)¶ If
*this
contains a value, callsfn(get_or_release())
and returns the result. If*this
does not contain a value, returnserror()
cast to the result type offn(get_or_release())
. The result type must be a complete type that is neither an array type, a reference type, or a function type.These operators are provided as a shorthand for
reduce(fn1, std::move<Err>)
, wherefn1
would usually be a function that returns another instance oferror_or
. By using the%
operator, multiple calls to functions returningerror_or
can be easily chained if only the last error in the chain is important, for example if a program must open a file and invoke an ioctl on it in one operation that appears atomic to the consumer.Returns: *this ? fn(get_or_release()) : error()
Noexcept: noexcept
iffn
isnoexcept
.
-
const Err &
error
() const¶ Returns: The error stored in *this
.Throws: nu::bad_error_or_access – If *this
contains a value.
-
const T &
value
() const &¶ Returns: The value stored in *this
.Throws: nu::bad_error_or_access – If *this
contains an error.
-
T &&
release_value
()¶ Returns: The value stored in *this
.Throws: nu::bad_error_or_access – If *this
contains an error.
-