4.6.0
Freundlich's C++ toolkit
Loading...
Searching...
No Matches
fcppt.either

Description

An optional with an error type.

Motivation

The downside of exceptions, which are the usual way to handle errors in C++, is that they do not appear in the type system. If a function changes which exceptions it throws, all the code that uses the function will still compile. This can make keeping track of which errors to handle where extremely difficult. Instead of having a function that throws an exception, i.e.

int example_function()
{
// some code
// ...
if (error())
{
throw std::runtime_error{"something went wrong"};
}
return 1;
}

we can move the exception into the return type instead, like so:

int_or_exception example_function2()
{
// some code
// ...
if (error())
{
return int_or_exception{std::runtime_error{"something went wrong"}};
}
return int_or_exception{1};
}

In the first example, where the exception is used, a caller has to know that such an exception may be thrown and catch it.

void caller()
{
try
{
int const result{example_function()};
std::cout << "result is " << result << '\n';
}
catch (std::runtime_error const &) // NOLINT(bugprone-empty-catch)
{
// do something else
}
}

In the second example, where the either is used, we cannot ignore that an error can occur. The simplest way to deconstruct an either<F,S> is to call the fcppt::either::match function. It gets two lambdas, where the first one receives F and the second one receives S.

void caller2()
{
example_function2(),
[](std::runtime_error const &) {
// do something else
},
[](int const _result) { std::cout << "result is " << _result << '\n'; });
}

In general, an either<F,S> is basically the same as a std::variant<F,S> but with additional meaning assigned to F and S. This becomes apparant in functions like fcppt::either::map, fcppt::either::apply and fcppt::either::bind.

Note
Either does not make exceptions obsolete. They are still crucial to implement RAII, and there might be cases where it is simply not desired to make an error explicit in the type system.

Operations

The simplest operation on eithers is fcppt::either::map. It allows us to transform the success value while keeping the error value. For example, consider a function that might return an int, which we want to transform into a string. This can be done as follows:

{
return fcppt::either::map(get_int(), [](int const _value) { return std::to_string(_value); });
}

We often have to chain multiple eithers together. For example, if we want to call two functions, each of which can fail, we only want to produce a result if both succeeed. This can be done with fcppt::either::apply.

{
[](int const _value1, int const _value2) {
return std::to_string(_value1) + " " + std::to_string(_value2);
},
get_int(),
get_int());
}

Note that since fcppt::either::apply is a variadic template, so it can work on arbitrarly many eithers, the function is its first parameter.

Another, even more basic operation, is fcppt::either::bind. As an example, let us look at how reading from a std::istream would work using eithers. Consider a function that tries to read an int and if that succeeds tries to read a string.

using int_string_pair = std::pair<int, std::string>;
int_string_pair read_stream_raw(std::istream &_stream)
{
int result_int{0};
if (!(_stream >> result_int))
{
throw std::runtime_error{"error"};
}
std::string result_string{};
if (!(_stream >> result_string))
{
throw std::runtime_error{"error"};
}
return int_string_pair{result_int, result_string};
}

First note that the function reading from the stream, which is operator>> , uses a reference parameter to store its result. Since operator>> returns a reference to _stream, the expression !(_stream >> something) checks if reading something produced an error. If that is the case, we cannot use the stream to read more data, and we need to abort early.

To do this with eithers instead, first, let us encapsulate reading a single value in a template function which returns an either.

template <typename Type>
{
Type result{};
return _stream >> result ? return_type{result} : return_type{std::runtime_error{"error"}};
}

Then, we can use this function to read the two eithers in succession, which is done using fcppt::either::bind.

fcppt::either::object<std::runtime_error, int_string_pair> read_stream_either(std::istream &_stream)
{
return fcppt::either::bind(read<int>(_stream), [&_stream](int const _int_value) {
read<std::string>(_stream), [_int_value](std::string const &_string_value) {
return std::make_pair(_int_value, _string_value);
});
});
}

Note that the difference to using fcppt::either::apply is that the second operation is not done if the first one returned an error. Unfortunately, chaining more of these operations together creates more and more nested code. In other programming languages like Haskell, there is special notation to bring every operation on the same indentation level, called the Do-Notation.

If at some point you want to turn an either back into an exception, you can use fcppt::either::to_exception.

int_string_pair either_to_exception(std::istream &_stream)
{
read_stream_either(_stream), [](std::runtime_error const &_error) { return _error; });
}

Errors

When functions return optional errors but no success values, it can be more convenient to handle such cases as eithers. An fcppt::either::error is an either with a success type that only has one value, which is fcppt::unit. For example:

auto either_error(fcppt::optional::object<error_code> const _error)
{
return fcppt::either::map(either_error, [](fcppt::either::no_error) {
// Do something in case of no error.
return do_something();
});
}

Header files

Header file Description
object_fwd.hpp Contains fcppt::either::object either's declaration.
object_decl.hpp Contains fcppt::either::object either's definition.
object_impl.hpp Contains the definition of fcppt::either::object either's member functions.
object.hpp Includes object_impl.hpp and comparison.hpp.
apply.hpp Contains fcppt::either::apply.
bind.hpp Contains fcppt::either::bind.
comparison.hpp Contains operator== and operator!=.
error_fwd.hpp Contains fcppt::either::error error's declaration.
error.hpp Contains fcppt::either::error error's definition.
error_from_optional.hpp Contains fcppt::either::error_from_optional.
failure_opt.hpp Contains fcppt::either::failure_opt.
first_success.hpp Contains fcppt::either::first_success.
from_optional.hpp Contains fcppt::either::from_optional.
make_failure.hpp Contains fcppt::either::make_failure.
make_success.hpp Contains fcppt::either::make_success.
map.hpp Contains fcppt::either::map.
map_failure.hpp Contains fcppt::either::map_failure.
match.hpp Contains fcppt::either::match.
no_error_fwd.hpp Contains fcppt::either::no_error no_error's declaration.
no_error.hpp Contains fcppt::either::no_error no_error's definition.
output.hpp Contains operator<<.
sequence.hpp Contains fcppt::either::sequence.
sequence_error.hpp Contains fcppt::either::sequence_error.
success_opt.hpp Contains fcppt::either::success_opt.
to_exception.hpp Contains fcppt::either::to_exception.
try_call.hpp Contains fcppt::either::try_call.

Classes

class  fcppt::either::object< Failure, Success >
 

Typedefs

template<typename Failure >
using fcppt::either::error = fcppt::either::object<Failure, fcppt::either::no_error>
 An either without a success value.
 
template<fcppt::either::object_concept Either>
using fcppt::either::failure_move_type
 The moved failure type of an either.
 
template<fcppt::either::object_concept Either>
using fcppt::either::failure_reference_type = decltype(std::declval<Either>().get_failure_unsafe())
 The failure reference type of an either.
 
template<fcppt::either::object_concept Either>
using fcppt::either::failure_type = typename std::remove_cvref_t<Either>::failure
 The failure type of an either.
 
template<fcppt::either::object_concept Either>
using fcppt::either::success_move_type
 The moved success type of an either.
 
template<fcppt::either::object_concept Either>
using fcppt::either::success_reference_type = decltype(std::declval<Either>().get_success_unsafe())
 The success reference type of an either.
 
template<fcppt::either::object_concept Either>
using fcppt::either::success_type = typename std::remove_cvref_t<Either>::success
 The success type of an either.
 

Functions

template<fcppt::either::object_concept Either1, fcppt::either::object_concept... Eithers, fcppt::concepts::invocable_move< fcppt::either::success_move_type< Either1 >, fcppt::either::success_move_type< Eithers >... > Function>
requires ( std::is_same_v<fcppt::either::failure_type<Either1>, fcppt::either::failure_type<Eithers>> &&...)
fcppt::either::object< fcppt::either::failure_type< Either1 >, std::invoke_result_t< Function, fcppt::either::success_move_type< Either1 >, fcppt::either::success_move_type< Eithers >... > > fcppt::either::apply (Function const &_function, Either1 &&_either1, Eithers &&..._eithers)
 Applies a function to several eithers.
 
template<fcppt::either::object_concept Either, fcppt::concepts::invocable_move< fcppt::either::success_move_type< Either > > Function>
requires fcppt::either::is_object_v< std::invoke_result_t<Function, fcppt::either::success_move_type<Either>>> && std::is_same_v< fcppt::either::failure_type<Either>, fcppt::either::failure_type< std::invoke_result_t<Function, fcppt::either::success_move_type<Either>>>>
std::invoke_result_t< Function, fcppt::either::success_move_type< Either > > fcppt::either::bind (Either &&_either, Function const &_function)
 Monadic bind on the success type of an either.
 
template<typename Failure , typename Success >
bool fcppt::either::operator== (fcppt::either::object< Failure, Success > const &_a, fcppt::either::object< Failure, Success > const &_b)
 Compares two eithers for equality.
 
template<typename Failure , typename Success >
bool fcppt::either::operator!= (fcppt::either::object< Failure, Success > const &_a, fcppt::either::object< Failure, Success > const &_b)
 Compares two eithers for inequality.
 
template<fcppt::concepts::invocable_move Failure, fcppt::concepts::invocable_move Success>
fcppt::either::object< std::invoke_result_t< Failure >, std::invoke_result_t< Success > > fcppt::either::construct (bool const _value, Success const &_success, Failure const &_failure)
 Constructs an either by calling one of two functions.
 
template<fcppt::optional::object_concept Optional>
fcppt::either::error< fcppt::optional::value_type< Optional > > fcppt::either::error_from_optional (Optional &&_optional)
 Converts an optional error to an either.
 
template<fcppt::either::object_concept Either>
fcppt::optional::object< fcppt::either::failure_type< Either > > fcppt::either::failure_opt (Either &&_either)
 Returns the failure type as an optional.
 
template<typename Functions >
requires fcppt::concepts::invocable_move<fcppt::type_traits::value_type<Functions>> && fcppt::either::is_object_v<std::invoke_result_t<fcppt::type_traits::value_type<Functions>>>
fcppt::either::object< std::vector< fcppt::either::failure_type< std::invoke_result_t< fcppt::type_traits::value_type< Functions > > > >, fcppt::either::success_type< std::invoke_result_t< fcppt::type_traits::value_type< Functions > > > > fcppt::either::first_success (Functions const &_functions)
 Call a container of functions, returning their first success or a container of failures.
 
template<fcppt::optional::object_concept Optional, fcppt::concepts::invocable_move FailureFunction>
fcppt::either::object< std::invoke_result_t< FailureFunction >, fcppt::optional::value_type< Optional > > fcppt::either::from_optional (Optional &&_optional, FailureFunction const &_failure_function)
 Converts an optional to an either.
 
template<fcppt::either::object_concept Either>
requires fcppt::either::is_object_v<fcppt::either::success_type<Either>> && std::is_same_v< fcppt::either::failure_type<Either>, fcppt::either::failure_type<fcppt::either::success_type<Either>>>
fcppt::either::object< fcppt::either::failure_type< Either >, fcppt::either::success_type< fcppt::either::success_type< Either > > > fcppt::either::join (Either &&_either)
 Removes one layer of eithers.
 
template<fcppt::concepts::invocable_move Next, fcppt::concepts::invocable< fcppt::either::success_type< std::invoke_result_t< Next > > > Loop>
requires fcppt::either::is_object_v<std::invoke_result_t<Next>>
fcppt::either::failure_type< std::invoke_result_t< Next > > fcppt::either::loop (Next const &_next, Loop const &_loop)
 Loops a function returning an either.
 
template<fcppt::concepts::move_constructible Success, typename Failure >
fcppt::either::object< std::remove_cvref_t< Failure >, Success > fcppt::either::make_failure (Failure &&_failure)
 Create an either with a failure.
 
template<fcppt::concepts::move_constructible Failure, typename Success >
fcppt::either::object< Failure, std::remove_cvref_t< Success > > fcppt::either::make_success (Success &&_success)
 Create an either with a success.
 
template<fcppt::either::object_concept Either, fcppt::concepts::invocable_move< fcppt::either::success_move_type< Either > > Function>
fcppt::either::object< fcppt::either::failure_type< Either >, std::invoke_result_t< Function, fcppt::either::success_move_type< Either > > > fcppt::either::map (Either &&_either, Function const &_function)
 Maps over the success type of an either.
 
template<fcppt::either::object_concept Either, fcppt::concepts::invocable_move< fcppt::either::failure_move_type< Either > > Function>
fcppt::either::object< std::invoke_result_t< Function, fcppt::either::failure_move_type< Either > >, fcppt::either::success_type< Either > > fcppt::either::map_failure (Either &&_either, Function const &_function)
 Maps over the failure type of an either.
 
template<fcppt::either::object_concept Either, fcppt::concepts::invocable< fcppt::either::failure_move_type< Either > > FailureFunction, fcppt::concepts::invocable< fcppt::either::success_move_type< Either > > SuccessFunction>
requires std::is_same_v< std::invoke_result_t<SuccessFunction, fcppt::either::success_move_type<Either>>, std::invoke_result_t<FailureFunction, fcppt::either::failure_move_type<Either>>>
std::invoke_result_t< SuccessFunction, fcppt::either::success_move_type< Either > > fcppt::either::match (Either &&_either, FailureFunction const &_failure_function, SuccessFunction const &_success_function)
 Matches on the two cases of an either.
 
bool fcppt::either::operator== (fcppt::either::no_error const &, fcppt::either::no_error const &)
 Comparison of fcppt::either::no_error.
 
template<typename Ch , typename Traits >
std::basic_ostream< Ch, Traits > & fcppt::either::operator<< (std::basic_ostream< Ch, Traits > &_stream, fcppt::either::no_error const &)
 Outputs fcppt::either::no_error.
 
template<typename Failure , typename Success , typename Ch , typename Traits >
std::basic_ostream< Ch, Traits > & fcppt::either::operator<< (std::basic_ostream< Ch, Traits > &_stream, fcppt::either::object< Failure, Success > const &_either)
 Outputs an either to a basic_ostream.
 
template<fcppt::either::object_concept Result, typename Source >
Result fcppt::either::sequence (Source &&_source)
 Sequences a container of eithers.
 
template<typename Sequence , fcppt::concepts::invocable_move< fcppt::container::to_value_type< std::remove_reference_t< Sequence > > > Function>
requires fcppt::either::is_object_v<std::invoke_result_t< Function, fcppt::container::to_value_type<std::remove_reference_t<Sequence>>>> && std::is_same_v< fcppt::either::success_type<std::invoke_result_t< Function, fcppt::container::to_value_type<std::remove_reference_t<Sequence>>>>, fcppt::either::no_error>
std::invoke_result_t< Function, fcppt::container::to_value_type< std::remove_reference_t< Sequence > > > fcppt::either::sequence_error (Sequence &&_sequence, Function const &_function)
 Folds over a range, breaking out on the first error.
 
template<fcppt::either::object_concept Either>
fcppt::optional::object< fcppt::either::success_type< Either > > fcppt::either::success_opt (Either &&_either)
 Returns the success type as an optional.
 
template<fcppt::either::object_concept Either, fcppt::concepts::invocable_move< fcppt::either::failure_move_type< Either > > MakeException>
fcppt::either::success_move_type< Either > fcppt::either::to_exception (Either &&_either, MakeException const _make_exception)
 Returns the success value contained in an either or throws an exception.
 
template<fcppt::concepts::move_constructible Exception, fcppt::concepts::invocable_move Function, fcppt::concepts::invocable_move< Exception > ToException>
FCPPT_PP_PUSH_WARNING fcppt::either::object< std::invoke_result_t< ToException, Exception >, std::invoke_result_t< Function > > fcppt::either::try_call (Function const &_function, ToException const &_to_exception)
 Catches exceptions of a function call and puts the result in an either.
 

Variables

template<typename T >
constexpr bool fcppt::either::is_object_v = fcppt::either::is_object<T>::value
 Checks if a given type is an fcppt::either::object.
 

Typedef Documentation

◆ error

template<typename Failure >
using fcppt::either::error = fcppt::either::object<Failure, fcppt::either::no_error>

An either without a success value.

An either with a failure but no success value. This is useful in case errors are returned as optionals.

◆ failure_move_type

◆ failure_reference_type

using fcppt::either::failure_reference_type = decltype(std::declval<Either>().get_failure_unsafe())

The failure reference type of an either.

◆ failure_type

using fcppt::either::failure_type = typename std::remove_cvref_t<Either>::failure

The failure type of an either.

◆ success_move_type

◆ success_reference_type

using fcppt::either::success_reference_type = decltype(std::declval<Either>().get_success_unsafe())

The success reference type of an either.

◆ success_type

using fcppt::either::success_type = typename std::remove_cvref_t<Either>::success

The success type of an either.

Function Documentation

◆ apply()

template<fcppt::either::object_concept Either1, fcppt::either::object_concept... Eithers, fcppt::concepts::invocable_move< fcppt::either::success_move_type< Either1 >, fcppt::either::success_move_type< Eithers >... > Function>
requires ( std::is_same_v<fcppt::either::failure_type<Either1>, fcppt::either::failure_type<Eithers>> &&...)
fcppt::either::object< fcppt::either::failure_type< Either1 >, std::invoke_result_t< Function, fcppt::either::success_move_type< Either1 >, fcppt::either::success_move_type< Eithers >... > > fcppt::either::apply ( Function const & _function,
Either1 && _either1,
Eithers &&... _eithers )
nodiscard

Applies a function to several eithers.

For eithers e_1 = _either1 and e_2, ..., e_n = _eithers. If there is a smallest i such that e_i is set to failure f, then f is returned. Otherwise, e_1, ...., e_n are set to successes s_1,...,s_n and the result is _function(s_1,...,s_n).

◆ bind()

template<fcppt::either::object_concept Either, fcppt::concepts::invocable_move< fcppt::either::success_move_type< Either > > Function>
requires fcppt::either::is_object_v< std::invoke_result_t<Function, fcppt::either::success_move_type<Either>>> && std::is_same_v< fcppt::either::failure_type<Either>, fcppt::either::failure_type< std::invoke_result_t<Function, fcppt::either::success_move_type<Either>>>>
std::invoke_result_t< Function, fcppt::either::success_move_type< Either > > fcppt::either::bind ( Either && _either,
Function const & _function )
nodiscard

Monadic bind on the success type of an either.

If _either is set to success s, then _function(s) is returned. Otherwise, the failure in _either is returned.

◆ construct()

fcppt::either::object< std::invoke_result_t< Failure >, std::invoke_result_t< Success > > fcppt::either::construct ( bool const _value,
Success const & _success,
Failure const & _failure )
nodiscard

Constructs an either by calling one of two functions.

If _value is true then _success() is returned. Otherwise, _failure() is returned.

◆ error_from_optional()

template<fcppt::optional::object_concept Optional>
fcppt::either::error< fcppt::optional::value_type< Optional > > fcppt::either::error_from_optional ( Optional && _optional)
nodiscard

Converts an optional error to an either.

If _optional is set to x, then x is returned as the failure value.

◆ failure_opt()

fcppt::optional::object< fcppt::either::failure_type< Either > > fcppt::either::failure_opt ( Either && _either)
nodiscard

Returns the failure type as an optional.

◆ first_success()

template<typename Functions >
requires fcppt::concepts::invocable_move<fcppt::type_traits::value_type<Functions>> && fcppt::either::is_object_v<std::invoke_result_t<fcppt::type_traits::value_type<Functions>>>
fcppt::either::object< std::vector< fcppt::either::failure_type< std::invoke_result_t< fcppt::type_traits::value_type< Functions > > > >, fcppt::either::success_type< std::invoke_result_t< fcppt::type_traits::value_type< Functions > > > > fcppt::either::first_success ( Functions const & _functions)
nodiscard

Call a container of functions, returning their first success or a container of failures.

For _functions = (f_1,...,f_n), let i be the smallest index such that f_i() returns success s, in which case the result is s. If there is no such index, then all functions return failures e_1,...,e_n and the result is (e_1,...,_e_n).

Template Parameters
FunctionsA container of functions callable as fcppt::either::object<F,S> ()

TODO(concepts)

◆ from_optional()

fcppt::either:: object< std::invoke_result_t< FailureFunction >, fcppt::optional::value_type< Optional > > fcppt::either::from_optional ( Optional && _optional,
FailureFunction const & _failure_function )
nodiscard

Converts an optional to an either.

If _optional is set to x, then x is returned as the success value, otherwise _failure_function() is returned as the failure value.

Template Parameters
FailureFunctionMust be a function callable as R () where R is the failure type

◆ join()

Removes one layer of eithers.

If the outer either has failure f_1, then f_1 is returned. Otherwise, if the inner either has failure f_2, then f_2 is returned. Otherwise, the success value of the inner either is returned.

◆ loop()

template<fcppt::concepts::invocable_move Next, fcppt::concepts::invocable< fcppt::either::success_type< std::invoke_result_t< Next > > > Loop>
requires fcppt::either::is_object_v<std::invoke_result_t<Next>>
fcppt::either::failure_type< std::invoke_result_t< Next > > fcppt::either::loop ( Next const & _next,
Loop const & _loop )
nodiscard

Loops a function returning an either.

Calls _next repeatedly until it returns a failure, which is then returned as the result. Each success value that is returned until then is passed to _loop.

◆ make_failure()

template<fcppt::concepts::move_constructible Success, typename Failure >
fcppt::either::object< std::remove_cvref_t< Failure >, Success > fcppt::either::make_failure ( Failure && _failure)
inlinenodiscard

Create an either with a failure.

Template Parameters
SuccessThe success type of the either.

◆ make_success()

template<fcppt::concepts::move_constructible Failure, typename Success >
fcppt::either::object< Failure, std::remove_cvref_t< Success > > fcppt::either::make_success ( Success && _success)
inlinenodiscard

Create an either with a success.

Template Parameters
FailureThe failure type of the either.

◆ map()

fcppt::either::object< fcppt::either::failure_type< Either >, std::invoke_result_t< Function, fcppt::either::success_move_type< Either > > > fcppt::either::map ( Either && _either,
Function const & _function )
nodiscard

Maps over the success type of an either.

If _either is set to success s, r = _function(s) is called and the result is either<Either::failure,decltype(r)>(r). Otherwise, the failure in _either is returned.

◆ map_failure()

fcppt::either::object< std::invoke_result_t< Function, fcppt::either::failure_move_type< Either > >, fcppt::either::success_type< Either > > fcppt::either::map_failure ( Either && _either,
Function const & _function )

Maps over the failure type of an either.

If _either is set to failure f, r = _function(f) is called and the result is either<decltype(r),Either::success>(r). Otherwise, the success in _either is returned.

◆ match()

template<fcppt::either::object_concept Either, fcppt::concepts::invocable< fcppt::either::failure_move_type< Either > > FailureFunction, fcppt::concepts::invocable< fcppt::either::success_move_type< Either > > SuccessFunction>
requires std::is_same_v< std::invoke_result_t<SuccessFunction, fcppt::either::success_move_type<Either>>, std::invoke_result_t<FailureFunction, fcppt::either::failure_move_type<Either>>>
std::invoke_result_t< SuccessFunction, fcppt::either::success_move_type< Either > > fcppt::either::match ( Either && _either,
FailureFunction const & _failure_function,
SuccessFunction const & _success_function )
nodiscard

Matches on the two cases of an either.

If _either is set to success s, then _success_function(s) is returned. Otherwise, _either is set to failure f and _failure_function(f) is returned.

◆ operator!=()

template<typename Failure , typename Success >
bool fcppt::either::operator!= ( fcppt::either::object< Failure, Success > const & _a,
fcppt::either::object< Failure, Success > const & _b )
nodiscard

Compares two eithers for inequality.

TODO(concepts)

◆ operator<<() [1/2]

template<typename Ch , typename Traits >
std::basic_ostream< Ch, Traits > & fcppt::either::operator<< ( std::basic_ostream< Ch, Traits > & _stream,
fcppt::either::no_error const &  )
inline

◆ operator<<() [2/2]

template<typename Failure , typename Success , typename Ch , typename Traits >
std::basic_ostream< Ch, Traits > & fcppt::either::operator<< ( std::basic_ostream< Ch, Traits > & _stream,
fcppt::either::object< Failure, Success > const & _either )

Outputs an either to a basic_ostream.

TODO(concepts)

◆ operator==() [1/2]

bool fcppt::either::operator== ( fcppt::either::no_error const & ,
fcppt::either::no_error const &  )
inlinenodiscard

Comparison of fcppt::either::no_error.

◆ operator==() [2/2]

template<typename Failure , typename Success >
bool fcppt::either::operator== ( fcppt::either::object< Failure, Success > const & _a,
fcppt::either::object< Failure, Success > const & _b )
nodiscard

Compares two eithers for equality.

TODO(concepts)

◆ sequence()

template<fcppt::either::object_concept Result, typename Source >
Result fcppt::either::sequence ( Source && _source)
nodiscard

Sequences a container of eithers.

Let _source be a container [e_1,...e_n], where e_i has type fcppt::either::object<F,S_i>. If there is an i such that e_i has failure f and there is no j < i such that e_j has a failure, then f is returned. Otherwise, all eithers have success values, [s_1,...,s_n], and Result{s_1,...,s_n} is returned.

TODO(concepts)

◆ sequence_error()

template<typename Sequence , fcppt::concepts::invocable_move< fcppt::container::to_value_type< std::remove_reference_t< Sequence > > > Function>
requires fcppt::either::is_object_v<std::invoke_result_t< Function, fcppt::container::to_value_type<std::remove_reference_t<Sequence>>>> && std::is_same_v< fcppt::either::success_type<std::invoke_result_t< Function, fcppt::container::to_value_type<std::remove_reference_t<Sequence>>>>, fcppt::either::no_error>
std:: invoke_result_t< Function, fcppt::container::to_value_type< std::remove_reference_t< Sequence > > > fcppt::either::sequence_error ( Sequence && _sequence,
Function const & _function )
nodiscard

Folds over a range, breaking out on the first error.

This function is similar to fcppt::either::sequence, except it does not produce an output sequence. Instead, _function returns fcppt::either::error, which on success contains an fcppt::unit. Let _sequence = [x_1, ..., x_n]. The algorithms calls _function(x_1), ..., _function(x_i), where _function(x_i) is either the first call that returns a failure, in which case the failure is returned as the result, or i=n, in which case success is returned.

Template Parameters
SequenceMust be a range.

TODO(concepts)

◆ success_opt()

fcppt::optional::object< fcppt::either::success_type< Either > > fcppt::either::success_opt ( Either && _either)
nodiscard

Returns the success type as an optional.

◆ to_exception()

fcppt::either::success_move_type< Either > fcppt::either::to_exception ( Either && _either,
MakeException const _make_exception )
inlinenodiscard

Returns the success value contained in an either or throws an exception.

If _either is set to success s, then s is returned. Otherwise, _either is set to failure f and the result of _make_exception(f) is thrown as an exception.

◆ try_call()

FCPPT_PP_PUSH_WARNING fcppt::either:: object< std::invoke_result_t< ToException, Exception >, std::invoke_result_t< Function > > fcppt::either::try_call ( Function const & _function,
ToException const & _to_exception )
nodiscard

Catches exceptions of a function call and puts the result in an either.

Calls _function in a try block. If _function returns s, then the result is success s. If the function throws an exception e of type Exception, then the result is the failure _to_exception(e).

Template Parameters
ExceptionThe exception type to be caught.

Variable Documentation

◆ is_object_v

template<typename T >
bool fcppt::either::is_object_v = fcppt::either::is_object<T>::value
inlineconstexpr

Checks if a given type is an fcppt::either::object.