Result
Result provides a way to return a value or an error. The concept is similar to Either in Haskell or Result in Rust.
Usage
Use value, error, emplace_value and emplace_error to create new Result.
auto value42 = atoms::Result< int >::value( 22 );
auto value0 = atoms::Result< int, std::runtime_error >::emplace_value();
auto errStr = atoms::Result< double >::error( "string is default error type" );
auto errExcept = atoms::Result< int, std::runtime_error >::emplace_error( "passed to constructor" );
When returning Result from a function, you can use helper creation functions.
atoms::Result< int > div( int lhs, int rhs ) {
if ( rhs == 0 ) {
return atoms::result_error< std::string >( "division by 0" );
}
return atoms::result_value( lhs / rhs );
}
Use make_ helper creation function variants to pass arguments directly to constuctors.
atoms::Result< std::vector< double > > repeat( int count, double value ) {
if ( count < 0 ) {
return atoms::make_result_error< std::string >( "count is negative" );
}
return atoms::make_result_value( count, value );
}
You can check if a Result contains a value and dereference the Result to get it.
auto result = atoms::Result< int >::value( 10 );
if ( result ) { // or `result.has_value()`
std::cout << "Have result " << *result << "\n"; // or `result.assume_value()`
} else {
std::cout << "Have error " << result.assume_error() << "\n";
}
You can use monadic methods based on std::optional. Note that when using monadic methods, the other type has to be copy/move constructible.
auto result = atoms::Result< int >::value( 10 );
auto newResult = result.and_then( []( int value ){
return atoms::result_error( std::to_string( value ) );
} )
.or_else( []( const std::string & str ) {
return atoms::value( static_cast< int >( str.size() ) );
} )
.or_else( []() {
return atoms::value( 12 );
} )
.transform( []( int value ){
return static_cast< unsigned >( value + 2 );
} );
// If you `std::move` the result, the content will be moved as well
unsigned newValue = std::move( newResult ).transform_error( []( std::string str ){
return "Error: " + std::move( str );
} )
.value_or( []( std::string error ){
throw std::runtime_error( std::move( error ) );
} );
For matching on a result, you can use Result::match methods.
#include <atoms/util.hpp> // for `overloaded`
// ...
auto correctAnswer = atoms::Result< int >::value( 10 );
correctAnswer.match( overloaded{
[]( int value ) { std::cout << "Got answer " << value << "\n"; }
[]( const std::string & error ) { std::cerr << "Got error: " << error << "\n"; }
} );
// With compatible value and error types
auto correctStrAnswer = atoms::Result< std::string, std::string >::value( "Apple" );
/**
* Doesn't compile (compiler cannot deduce value/error from type)
* Also doesn't work on compatible types (e.g. int/unsigned) for the programmer's safety.
*/
// correctAnswer.match( overloaded{
// []( const std::string & value ) { std::cout << "Got answer " << value << "\n"; }
// []( const std::string & error ) { std::cerr << "Got error: " << error << "\n"; }
// } );
correctAnswer.match( overloaded{
[]( std::true_type, const std::string & value ) { std::cout << "Got answer " << value << "\n"; }
[]( std::false_type, const std::string & error ) { std::cerr << "Got error: " << error << "\n"; }
} );
Classes reference
-
template<typename T, typename E = std::string>
class Result A type that holds either a value or an error.
The usecase is similar to that of
std::optionalexcept it can hold additional info about the failure.The
Resultclass template is designed to be an almost drop-in replacement forstd::optionalexcept the construction.The
Resultis similar tostd::variantand should be treated as such. Specifically usestd::monostateifTorEtypes don’t have a value.Constructing static member functions
-
static inline constexpr Result value(const value_type &val)
Constructs the contained value by the copy constructor.
-
static inline constexpr Result value(value_type &&val)
Constructs the contained value by the move constructor.
-
static inline constexpr Result emplace_value(auto&&... args)
Constructs the contained value in-place.
-
static inline constexpr Result error(const error_type &err)
Constructs the contained error by the copy constructor.
-
static inline constexpr Result error(error_type &&err)
Constructs the contained error by the move constructor.
Implicit conversions
Implicit conversions when one of types is
detail::TypePlaceholder-
template<typename ValueT>
inline constexpr operator Result<ValueT, error_type>() const & Changes the
value_typefromdetail::TypePlaceholderby copying.
-
template<typename ValueT>
inline constexpr operator Result<ValueT, error_type>() && Changes the
value_typefromdetail::TypePlaceholderby moving.
-
template<typename ErrorT>
inline constexpr operator Result<value_type, ErrorT>() const & Changes the
error_typefromdetail::TypePlaceholderby copying.
-
template<typename ErrorT>
inline constexpr operator Result<value_type, ErrorT>() && Changes the
error_typefromdetail::TypePlaceholderby moving.
Observers
-
inline constexpr bool has_value() const noexcept
Checks whether
thiscontains a value.- Return values
true – if
thiscontains a value.false – if
thiscontains an error.
-
inline constexpr operator bool() const noexcept
Checks whether
thiscontains a value.- Return values
true – if
thiscontains a value.false – if
thiscontains an error.
Accessors
-
inline constexpr value_type *operator->() noexcept
Accesses the contained value.
- Returns
Pointer to the contained value.
-
inline constexpr const value_type *operator->() const noexcept
Accesses the contained value.
- Returns
Pointer to the contained value.
-
inline constexpr value_type &operator*() & noexcept
Accesses the contained value.
- Returns
Reference to the contained value.
-
inline constexpr const value_type &operator*() const & noexcept
Accesses the contained value.
- Returns
Reference to the contained value.
-
inline constexpr value_type &&operator*() && noexcept
Accesses the contained value.
- Returns
Reference to the contained value.
-
inline constexpr value_type &assume_value() & noexcept
Assume that the result contains a value.
- Returns
Reference to the contained value.
-
inline constexpr const value_type &assume_value() const & noexcept
Assume that the result contains a value.
- Returns
Reference to the contained value.
-
inline constexpr value_type &&assume_value() && noexcept
Assume that the result contains a value.
- Returns
Reference to the contained value.
-
inline constexpr error_type &assume_error() & noexcept
Assume that the result contains an error.
- Returns
Reference to the contained error.
-
inline constexpr const error_type &assume_error() const & noexcept
Assume that the result contains an error.
- Returns
Reference to the contained error.
-
inline constexpr error_type &&assume_error() && noexcept
Assume that the result contains an error.
- Returns
Reference to the contained error.
-
inline constexpr Result<detail::TypePlaceholder, error_type> assume_error_result() & noexcept
Assume that the result contains an error.
Deletes the
value_typesothiscan be converted to anotherResult.- Returns
Resultcontaining error fromthis.
-
inline constexpr Result<detail::TypePlaceholder, error_type> assume_error_result() const & noexcept
Assume that the result contains an error.
Deletes the
value_typesothiscan be converted to anotherResult.- Returns
Resultcontaining error fromthis.
-
inline constexpr Result<detail::TypePlaceholder, error_type> assume_error_result() && noexcept
Assume that the result contains an error.
Deletes the
value_typesothiscan be converted to anotherResult.- Returns
Resultcontaining error fromthis.
Get or throw operations
-
inline constexpr value_type &get_or_throw() &
Returns the contained value if it contains a value.
Otherwise, throws the contained error as an exception.
- Throws
If – the result type contains an error throws exception of type
error_type.- Returns
The contained value or doesn’t return normally.
-
inline constexpr const value_type &get_or_throw() const &
Returns the contained value if it contains a value.
Otherwise, throws the contained error as an exception.
- Throws
If – the result type contains an error throws exception of type
error_type.- Returns
The contained value or doesn’t return normally.
-
inline constexpr value_type &&get_or_throw() &&
Returns the contained value if it contains a value.
Otherwise, throws the contained error as an exception.
- Throws
If – the result type contains an error throws exception of type
error_type.- Returns
The contained value or doesn’t return normally.
-
template<std::constructible_from<error_type&> ExceptionT>
inline constexpr value_type &get_or_throw_as() & Returns the contained value if
thiscontains a value.Otherwise, throws the
ExceptionTconstructed from the error.- Template Parameters
ExceptionT – exception type constructable from
value_type &- Throws
If – the result type contains an error throws exception of type
ExceptionT.- Returns
The contained value or doesn’t return normally.
-
template<std::constructible_from<const error_type&> ExceptionT>
inline constexpr const value_type &get_or_throw_as() const & Returns the contained value if
thiscontains a value.Otherwise, throws the
ExceptionTconstructed from the error.- Template Parameters
ExceptionT – exception type constructable from
value_type &- Throws
If – the result type contains an error throws exception of type
ExceptionT.- Returns
The contained value or doesn’t return normally.
-
template<std::constructible_from<error_type&&> ExceptionT>
inline constexpr value_type &&get_or_throw_as() && Returns the contained value if
thiscontains a value.Otherwise, throws the
ExceptionTconstructed from the error.- Template Parameters
ExceptionT – exception type constructable from
value_type &- Throws
If – the result type contains an error throws exception of type
ExceptionT.- Returns
The contained value or doesn’t return normally.
Monadic operations
Inspired by and designed to be compatible with monadic operations of
std::optionalfrom C++23.-
template<std::invocable<value_type&> F>
inline constexpr auto and_then(F &&f) & Returns the result of invocation of
fon the contained value if it exists.Otherwise, returns the contained error in the return type.
The return type must be a specialization of
Resultwith the same error type.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The result of
for the contained error.
-
template<std::invocable<const value_type&> F>
inline constexpr auto and_then(F &&f) const & Returns the result of invocation of
fon the contained value if it exists.Otherwise, returns the contained error in the return type.
The return type must be a specialization of
Resultwith the same error type.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The result of
for the contained error.
-
template<std::invocable<value_type&&> F>
inline constexpr auto and_then(F &&f) && Returns the result of invocation of
fon the contained value if it exists.Otherwise, returns the contained error in the return type.
The return type must be a specialization of
Resultwith the same error type.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The result of
for the contained error.
-
template<std::invocable<error_type&> F>
inline constexpr auto or_else(F &&f) & Returns the contained value in the return type if it contains a value.
Otherwise, returns the result of invocation of
fon the contained error.The return type must be a specialization of
Resultwith the same value type.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The contained value or the result of
f.
-
template<std::invocable<const error_type&> F>
inline constexpr auto or_else(F &&f) const & Returns the contained value in the return type if it contains a value.
Otherwise, returns the result of invocation of
fon the contained error.The return type must be a specialization of
Resultwith the same value type.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The contained value or the result of
f.
-
template<std::invocable<error_type&&> F>
inline constexpr auto or_else(F &&f) && Returns the contained value in the return type if it contains a value.
Otherwise, returns the result of invocation of
fon the contained error.The return type must be a specialization of
Resultwith the same value type.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The contained value or the result of
f.
-
template<std::invocable<> F>
inline constexpr auto or_else(F &&f) const Returns the contained value in the return type if it contains a value.
Otherwise, returns the result of
f.The return type must be a specialization of
Resultwith the same value type.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The contained value or the result of
f.
-
template<std::invocable<> F>
inline constexpr auto or_else(F &&f) && Returns the contained value in the return type if it contains a value.
Otherwise, returns the result of
f.The return type must be a specialization of
Resultwith the same value type.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The contained value or the result of
f.
Transform operations
-
template<std::invocable<value_type&> F>
inline constexpr auto transform(F &&f) & Returns
Resultwith the result of invocation offon the contained value as the new value if it exists.Otherwise, returns the contained error in the return type.
The return type of
fwill be the value type of the returnedResult.- Parameters
f – a suitable function or Callable object that returns the new value type
- Returns
The result of
for the contained error.
-
template<std::invocable<const value_type&> F>
inline constexpr auto transform(F &&f) const & Returns
Resultwith the result of invocation offon the contained value as the new value if it exists.Otherwise, returns the contained error in the return type.
The return type of
fwill be the value type of the returnedResult.- Parameters
f – a suitable function or Callable object that returns the new value type
- Returns
The result of
for the contained error.
-
template<std::invocable<value_type&&> F>
inline constexpr auto transform(F &&f) && Returns
Resultwith the result of invocation offon the contained value as the new value if it exists.Otherwise, returns the contained error in the return type.
The return type of
fwill be the value type of the returnedResult.- Parameters
f – a suitable function or Callable object that returns the new value type
- Returns
The result of
for the contained error.
-
template<std::invocable<error_type&> F>
inline constexpr auto transform_error(F &&f) & Returns the contained value in the return type if it contains a value.
Otherwise, returns
Resultwith the result of invocation offon the contained error as the new error.The return type of
fwill be the error type of the returnedResult.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The contained value or the result of
f.
-
template<std::invocable<const error_type&> F>
inline constexpr auto transform_error(F &&f) const & Returns the contained value in the return type if it contains a value.
Otherwise, returns
Resultwith the result of invocation offon the contained error as the new error.The return type of
fwill be the error type of the returnedResult.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The contained value or the result of
f.
-
template<std::invocable<error_type&&> F>
inline constexpr auto transform_error(F &&f) && Returns the contained value in the return type if it contains a value.
Otherwise, returns
Resultwith the result of invocation offon the contained error as the new error.The return type of
fwill be the error type of the returnedResult.- Parameters
f – a suitable function or Callable object that returns a
Result- Returns
The contained value or the result of
f.
Match operations
-
template<detail::hint_match_visitor<value_type&, error_type&> Vis>
inline constexpr auto match(Vis &&vis) & Returns the result of invocation of
visonstd::true_typeand the contained value if it exists.Otherwise, returns the result of invocation of
visonstd::false_typeand the contained error.vishas to be invocable withstd::true_type, value_type &and withstd::false_type, error_type &and has to have the same return type.viscannot be invocable just withvalue_type &or just witherror_type &.- Parameters
vis – a suitable function or Callable object
- Returns
The result of
vis.
-
template<detail::hint_match_visitor<const value_type&, const error_type&> Vis>
inline constexpr auto match(Vis &&vis) const & Returns the result of invocation of
visonstd::true_typeand the contained value if it exists.Otherwise, returns the result of invocation of
visonstd::false_typeand the contained error.vishas to be invocable withstd::true_type, const value_type &and withstd::false_type, const error_type &and has to have the same return type.viscannot be invocable just withconst value_type &or just withconst error_type &.- Parameters
vis – a suitable function or Callable object
- Returns
The result of
vis.
-
template<detail::hint_match_visitor<value_type&&, error_type&&> Vis>
inline constexpr auto match(Vis &&vis) && Returns the result of invocation of
visonstd::true_typeand the contained value if it exists.Otherwise, returns the result of invocation of
visonstd::false_typeand the contained error.vishas to be invocable withstd::true_type, value_type &&and withstd::false_type, error_type &&and has to have the same return type.viscannot be invocable just withvalue_type &&or just witherror_type &&.- Parameters
vis – a suitable function or Callable object
- Returns
The result of
vis.
-
template<detail::no_hint_match_visitor<value_type&, error_type&> Vis>
inline constexpr auto match(Vis &&vis) & Returns the result of invocation of
vison the contained value if it exists.Otherwise, returns the result of invocation of
vison the contained error.vishas to be invocable withvalue_type &and witherror_type &and has to have the same return type.viscannot be invocable withstd::true_type, value_type &or withstd::false_type, error_type &.- Parameters
vis – a suitable function or Callable object
- Returns
The result of
vis.
-
template<detail::no_hint_match_visitor<const value_type&, const error_type&> Vis>
inline constexpr auto match(Vis &&vis) const & Returns the result of invocation of
vison the contained value if it exists.Otherwise, returns the result of invocation of
vison the contained error.vishas to be invocable withconst value_type &and withconst error_type &and has to have the same return type.viscannot be invocable withstd::true_type, const value_type &or withstd::false_type, const error_type &.- Parameters
vis – a suitable function or Callable object
- Returns
The result of
vis.
-
template<detail::no_hint_match_visitor<value_type&&, error_type&&> Vis>
inline constexpr auto match(Vis &&vis) && Returns the result of invocation of
vison the contained value if it exists.Otherwise, returns the result of invocation of
vison the contained error.vishas to be invocable withvalue_type &&and witherror_type &&and has to have the same return type.viscannot be invocable withstd::true_type, value_type &&or withstd::false_type, error_type &&.- Parameters
vis – a suitable function or Callable object
- Returns
The result of
vis.
-
static inline constexpr Result value(const value_type &val)
-
struct TypePlaceholder
Result value/error type placeholder.
Used as a type placeholder so the other type of result doesn’t have to be specified by the user.
The functionality of
ResultwithTypePlaceholderis similar tostd::nullopt_t.Public Functions
-
TypePlaceholder() = delete
-
TypePlaceholder() = delete
Functions reference
-
template<typename ValueT>
inline constexpr auto atoms::result_value(ValueT value) -> Result<ValueT, detail::TypePlaceholder> Creates
Resultfrom value.The created
Resultis implicitly convertible toResultwith any error type.
-
template<typename ValueT, typename ...Args>
inline constexpr auto atoms::make_result_value(Args&&... args) -> Result<ValueT, detail::TypePlaceholder> Creates
Resultwith value constructed in-place fromargs… .The created
Resultis implicitly convertible toResultwith any error type.- Parameters
args – arguments to be passed to the constructor of value
- Returns
the contructed
Resultobject.
-
template<typename ErrorT>
inline constexpr auto atoms::result_error(ErrorT error) -> Result<detail::TypePlaceholder, ErrorT> Creates
Resultfrom error.The created
Resultis implicitly convertible toResultwith any value type.
-
template<typename ErrorT, typename ...Args>
inline constexpr auto atoms::make_result_error(Args&&... args) -> Result<detail::TypePlaceholder, ErrorT> Creates
Resultwith error constructed in-place fromargs… .The created
Resultis implicitly convertible toResultwith any value type.- Parameters
args – arguments to be passed to the constructor of error
- Returns
the contructed
Resultobject.