///////////////////////////////////////////////////////////////////////////// /// \brief The class template result
manages result results from APIs, /// while encoding possible failure conditions. /// /// A common use-case for result is the return value of a function that /// may fail. As opposed to other approaches, such as std::pair<T,bool>
/// or std::optional
, result
more accurately conveys the intent of the /// user along with the failure condition to the caller. This effectively /// produces an orthogonal error handling mechanism that allows for exception /// safety while also allowing discrete testability of the return type. /// /// result<T,E>
types may contain a T
value, which signifies that an /// operation succeeded in producing the result value of type T
. If an /// result
does not contain a T
value, it will always contain an E
/// error condition instead. /// /// An result<T,E>
can always be queried for a possible error case by /// calling the error()
function, even if it contains a value. /// In the case that a result<T,E>
contains a value object, this will /// simply return an E
object constructed through default aggregate /// construction, as if through the expression E{}
, which is assumed to be /// a “valid” (no-error) state for an E
type. /// For example: /// /// * std::error_code{}
produces a default-construct error-code, which is /// the “no error” state, /// * integral (or enum) error codes produce a 0
value (no error), thanks to /// zero-initialization, /// * std::exception_ptr{}
produces a null-pointer, /// * std::string{}
produces an empty string ""
, /// * etc. /// /// When a result<T,E>
contains either a value or error, the storage for /// that object is guaranteed to be allocated as part of the result /// object’s footprint, i.e. no dynamic memory allocation ever takes place. /// Thus, a result object models an object, not a pointer, even though the /// operator*()
and operator->()
are defined. /// /// When an object of type result<T,E>
is contextually converted to /// bool
, the conversion returns true
if the object contains a value and /// false
if it contains an error. /// /// result
objects do not have a “valueless” state like variant
s do. /// Once a result
has been constructed with a value or error, the /// active underlying type can only be changed through assignment which may /// is only enabled if construction is guaranteed to be non-throwing. This /// ensures that a valueless state cannot occur naturally. /// /// Example Use: /// \code /// auto to_string(int x) -> resultstd::string /// { /// try { /// return std::stoi(x); /// } catch (const std::invalid_argument&) { /// return fail(std::errc::invalid_argument); /// } catch (const std::std::out_of_range&) { /// return fail(std::errc::result_out_of_range); /// } /// } /// \endcode /// /// \note If using C++17 or above, fail
can be replaced with /// failure{...}
thanks to CTAD. /// /// \tparam T the underlying value type /// \tparam E the underlying error type ///////////////////////////////////////////////////////////////////////////
Class result<T, E>
#include <Geode/external/result/result.hpp>
Examples0
Public static methods0
Public member functions51
template<typename U=T,typename = typename std::enable_if<std::is_constructible<U>::value>::type>voidresult<type-parameter-0-0, type-parameter-0-1>()
/// \brief Default-constructs a result with the underlying value type /// active /// /// This constructor is only enabled if T
is default-constructible /// /// ### Examples /// /// Basic Usage: /// /// cpp /// assert(cpp::result<std::string,int>{} == std::string{}); ///
template<typename T2,typename E2>voidresult<type-parameter-0-0, type-parameter-0-1>()
/// { /// \brief Converting copy constructor /// /// If \p other contains a value, constructs a result object /// that contains a value, initialized as if direct-initializing /// (but not direct-list-initializing) an object of type T
with the /// expression *other
. /// /// If \p other contains an error, constructs a result object that /// contains an error, initialized as if direct-initializing /// (but not direct-list-initializing) an object of type E
. /// /// \note This constructor does not participate in overload resolution /// unless the following conditions are met: /// - std::is_constructible_v<T, const U&>
is true
/// - T is not constructible or convertible from any expression /// of type (possibly const) result<T2,E2>
/// - E is not constructible or convertible from any expression /// of type (possible const) result<T2,E2>
/// /// \note This constructor is explicit if and only if /// std::is_convertible_v<const T2&, T>
or /// std::is_convertible_v<const E2&, E>
is false
/// /// ### Examples /// /// Basic Usage: /// /// cpp /// const auto r = cpp::result<int,int>{42}; /// const auto s = cpp::result<long,long>{r}; /// /// assert(r == s); ///
/// /// \param other the other type to convert
template<typename T2,typename E2>voidresult<type-parameter-0-0, type-parameter-0-1>()
template<typename T2,typename E2>voidresult<type-parameter-0-0, type-parameter-0-1>()
/// { /// \brief Converting move constructor /// /// If \p other contains a value, constructs a result object /// that contains a value, initialized as if direct-initializing /// (but not direct-list-initializing) an object of type T with the /// expression std::move(*other)
. /// /// If \p other contains an error, constructs a result object that /// contains an error, initialized as if direct-initializing /// (but not direct-list-initializing) an object of type E&&. /// /// \note This constructor does not participate in overload resolution /// unless the following conditions are met: /// - std::is_constructible_v<T, const U&>
is true
/// - T is not constructible or convertible from any expression /// of type (possibly const) result<T2,E2>
/// - E is not constructible or convertible from any expression /// of type (possible const) result<T2,E2>
/// /// \note This constructor is explicit if and only if /// std::is_convertible_v<const T2&, T>
or /// std::is_convertible_v<const E2&, E>
is false
/// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<std::unique_ptr<Derived>,int>{ /// std::make_unique<Derived>() /// }; /// const auto s = cpp::result<std::unique_ptr<Base>,long>{ /// std::move(r) /// }; ///
/// /// \param other the other type to convert
template<typename T2,typename E2>voidresult<type-parameter-0-0, type-parameter-0-1>()
template<typename...Args,typename = typename std::enable_if<std::is_constructible<T,Args...>::value>::type>voidresult<type-parameter-0-0, type-parameter-0-1>(,Args &&...args)
/// \brief Constructs a result object that contains a value /// /// The value is initialized as if direct-initializing (but not /// direct-list-initializing) an object of type T
from the arguments /// std::forward<Args>(args)...
/// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<std::string,int>{ /// cpp::in_place, "Hello world" /// }; ///
/// /// \param args the arguments to pass to T’s constructor
template<typename U,typename...Args,typename = typename std::enable_if<std::is_constructible<T, std::initializer_list<U>&, Args...>::value>::type>voidresult<type-parameter-0-0, type-parameter-0-1>(,,Args &&...args)
/// \brief Constructs a result object that contains a value /// /// The value is initialized as if direct-initializing (but not /// direct-list-initializing) an object of type T
from the arguments /// std::forward<std::initializer_list<U>>(ilist)
, /// std::forward<Args>(args)...
/// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<std::string,int>{ /// cpp::in_place, {'H','e','l','l','o'} /// }; ///
/// /// \param ilist An initializer list of entries to forward /// \param args the arguments to pass to T’s constructor
template<typename...Args,typename = typename std::enable_if<std::is_constructible<E,Args...>::value>::type>voidresult<type-parameter-0-0, type-parameter-0-1>(,Args &&...args)
/// \brief Constructs a result object that contains an error /// /// the value is initialized as if direct-initializing (but not /// direct-list-initializing) an object of type E
from the arguments /// std::forward<Args>(args)...
/// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<int,std::string>{ /// cpp::in_place_error, "Hello world" /// }; ///
/// /// \param args the arguments to pass to E’s constructor
template<typename U,typename...Args,typename = typename std::enable_if<std::is_constructible<E, std::initializer_list<U>&, Args...>::value>::type>voidresult<type-parameter-0-0, type-parameter-0-1>(,,Args &&...args)
/// \brief Constructs a result object that contains an error /// /// The value is initialized as if direct-initializing (but not /// direct-list-initializing) an object of type E
from the arguments /// std::forward<std::initializer_list<U>>(ilist)
, /// std::forward<Args>(args)...
/// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<int,std::string>{ /// cpp::in_place_error, {'H','e','l','l','o'} /// }; ///
/// /// \param ilist An initializer list of entries to forward /// \param args the arguments to pass to Es constructor
template<typename E2,typename = typename std::enable_if<std::is_constructible<E,const E2&>::value>::type>voidresult<type-parameter-0-0, type-parameter-0-1>()
/// { /// \brief Constructs the underlying error of this result /// /// \note This constructor only participates in overload resolution if /// E
is constructible from \p e /// /// ### Examples /// /// Basic Usage: /// /// cpp /// cpp::result<int,int> r = cpp::fail(42); /// /// auto get_error_result() -> cpp::result<int,std::string> { /// return cpp::fail("hello world!"); /// } ///
/// /// \param e the failure error
template<typename E2,typename = typename std::enable_if<std::is_constructible<E,E2&&>::value>::type>voidresult<type-parameter-0-0, type-parameter-0-1>()
template<typename U>voidresult<type-parameter-0-0, type-parameter-0-1>(U&&value)
/// { /// \brief Constructs a result object that contains a value /// /// The value is initialized as if direct-initializing (but not /// direct-list-initializing) an object of type T with the expression /// value. /// /// \note This constructor is constexpr if the constructor of T /// selected by direct-initialization is constexpr /// /// \note This constructor does not participate in overload /// resolution unless std::is_constructible_v<T, U&&>
is true /// and decay_t<U>
is neither in_place_t
, in_place_error_t
, /// nor a result
type. /// /// \note This constructor is explicit if and only if /// std::is_convertible_v<U&&, T>
is false
/// /// ### Examples /// /// Basic Usage: /// /// cpp /// cpp::result<int,int> r = 42; /// /// auto get_value() -> cpp::result<std::string,int> { /// return "hello world!"; // implicit conversion /// } ///
/// /// \param value the value to copy
template<typename U>voidresult<type-parameter-0-0, type-parameter-0-1>(U&&value)
cpp::bitwizeshift::result&operator=()
/// \brief Copy assigns the result stored in \p other /// /// \note This assignment operator only participates in overload resolution /// if the following conditions are met: /// - std::is_nothrow_copy_constructible_v<T>
is true
, and /// - std::is_nothrow_copy_constructible_v<E>
is true
/// this restriction guarantees that no ’ /// /// \note This assignment operator is defined as trivial if the following /// conditions are all true
: /// - std::is_trivially_copy_constructible<T>::value
/// - std::is_trivially_copy_constructible<E>::value
/// - std::is_trivially_copy_assignable<T>::value
/// - std::is_trivially_copy_assignable<E>::value
/// - std::is_trivially_destructible<T>::value
/// - std::is_trivially_destructible<E>::value
/// /// \param other the other result to copy
cpp::bitwizeshift::result&operator=()
/// \brief Move assigns the result stored in \p other /// /// \note This assignment operator only participates in overload resolution /// if the following conditions are met: /// - /// \brief Copy-converts the state of \p other /// /// If both /// \brief Move-converts the state of \p other /// /// If both /// \brief Perfect-forwarded assignment /// /// Depending on whether /// { /// \brief Perfect-forwarded assignment /// /// Depending on whether /// { /// \brief Retrieves a pointer to the contained value /// /// This operator exists to give /// { /// \brief Retrieves a reference to the contained value /// /// This operator exists to give /// \brief Returns /// \brief Returns /// { /// \brief Returns a reference to the contained value /// /// This function provides checked (throwing) access to the underlying /// value. The constness and refness of this result is propagated to the /// underlying reference. /// /// If this contains an error, an exception is thrown containing the /// underlying error. The error is consumed propagating the same constness /// and refness of this result. /// /// ### Examples /// /// Basic Usage: /// /// /// { /// \brief Returns the contained error, if one exists, or a /// default-constructed error value /// /// The /// { /// \brief Asserts an expectation that this result contains an error, /// throwing a bad_result_access on failure /// /// If this function is invoked from an rvalue of /// { /// \brief Returns the contained value if /// { /// \brief Returns the contained error if /// \brief Returns a result containing \p value if this result contains /// a value, otherwise returns a result containing the current /// error. /// /// ### Examples /// /// Basic Usage: /// /// /// { /// \brief Invokes the function \p fn with the value of this result as /// the argument /// /// If this result contains an error, a result of the error is returned /// /// The function being called must return a /// { /// \brief Invokes the function \p fn with the value of this result as /// the argument /// /// If this result is an error, the result of this function is that /// error. Otherwise this function wraps the result and returns it as an /// result. /// /// If this is called on an rvalue of /// { /// \brief Invokes the function \p fn with the error of this result as /// the argument /// /// If this result contains a value, the result of this function is that /// value. Otherwise the function is called with that error and returns the /// result as a result. /// /// If this is called on an rvalue of /// { /// \brief Invokes the function \p fn with the error of this result as /// the argument /// /// If this result contains a value, a result of the value is returned /// /// The function being called must return a std::is_nothrow_copy_constructible_v<T>
is true
, and /// - std::is_nothrow_copy_constructible_v<E>
is true
/// this restriction guarantees that no ’valueless_by_exceptionstate /// may occur. /// /// \note This assignment operator is defined as trivial if the following /// conditions are all
true: /// -
std::is_trivially_move_constructible/// -
std::is_trivially_move_constructible/// -
std::is_trivially_move_assignable/// -
std::is_trivially_move_assignable/// -
std::is_trivially_destructible/// -
std::is_trivially_destructibletemplate<typename T2,typename E2,typename = typename std::enable_if<detail::result_is_copy_convert_assignable<T,E,T2,E2>::value>::type>cpp::bitwizeshift::result&operator=()
*this
and \p other contain either values or errors, the /// underlying value is constructed as if through assignment. /// /// Otherwise if *this
contains a value, but \p other contains an error, /// then the contained value is destroyed by calling its destructor. *this
/// will no longer contain a value after the call, and will now contain E
/// constructed as if direct-initializing (but not direct-list-initializing) /// an object with an argument of const E2&
. /// /// If \p other contains a value and *this
contains an error, then the /// contained error is destroyed by calling its destructor. *this
now /// contains a value constructed as if direct-initializing (but not /// direct-list-initializing) an object with an argument of const T2&
. /// /// \note The function does not participate in overload resolution unless /// - std::is_nothrow_constructible_v<T, const T2&>
, /// std::is_assignable_v<T&, const T2&>
, /// std::is_nothrow_constructible_v<E, const E2&>
, /// std::is_assignable_v<E&, const E2&>
are all true. /// - T is not constructible, convertible, or assignable from any /// expression of type (possibly const) result<T2,E2>
/// /// \param other the other result object to convert /// \return reference to (*this)
template<typename T2,typename E2,typename = typename std::enable_if<detail::result_is_move_convert_assignable<T,E,T2,E2>::value>::type>cpp::bitwizeshift::result&operator=()
*this
and \p other contain either values or errors, the /// underlying value is constructed as if through move-assignment. /// /// Otherwise if *this
contains a value, but \p other contains an error, /// then the contained value is destroyed by calling its destructor. *this
/// will no longer contain a value after the call, and will now contain E
/// constructed as if direct-initializing (but not direct-list-initializing) /// an object with an argument of E2&&
. /// /// If \p other contains a value and *this
contains an error, then the /// contained error is destroyed by calling its destructor. *this
now /// contains a value constructed as if direct-initializing (but not /// direct-list-initializing) an object with an argument of T2&&
. /// /// \note The function does not participate in overload resolution unless /// - std::is_nothrow_constructible_v<T, T2&&>
, /// std::is_assignable_v<T&, T2&&>
, /// std::is_nothrow_constructible_v<E, E2&&>
, /// std::is_assignable_v<E&, E2&&>
are all true. /// - T is not constructible, convertible, or assignable from any /// expression of type (possibly const) result<T2,E2>
/// /// \param other the other result object to convert /// \return reference to (*this)
template<typename U,typename = typename std::enable_if<detail::result_is_value_assignable<T,U>::value>::type>cpp::bitwizeshift::result&operator=(
*this
contains a value before the call, the /// contained value is either direct-initialized from std::forward(value) /// or assigned from std::forward(value). /// /// \note The function does not participate in overload resolution unless /// - std::decay_t<U>
is not a result type, /// - std::decay_t<U>
is not a failure type /// - std::is_nothrow_constructible_v<T, U>
is true
/// - std::is_assignable_v<T&, U>
is true
/// - and at least one of the following is true
: /// - T
is not a scalar type; /// - std::decay_t<U>
is not T
. /// /// \param value to assign to the contained value /// \return reference to (*this)
template<typename E2,typename = typename std::enable_if<detail::result_is_failure_assignable<E,const E2&>::value>::type>cpp::bitwizeshift::result&operator=()
*this
contains an error before the call, the /// contained error is either direct-initialized via forwarding the error, /// or assigned from forwarding the error /// /// \note The function does not participate in overload resolution unless /// - std::is_nothrow_constructible_v<E, E2>
is true
, and /// - std::is_assignable_v<E&, E2>
is true
/// /// \param other the failure value to assign to this /// \return reference to (*this)
template<typename E2,typename = typename std::enable_if<detail::result_is_failure_assignable<E,E2&&>::value>::type>cpp::bitwizeshift::result&operator=()
typename std::remove_reference<T>::type*operator->()
result
an optional
-like API for cases /// where it’s known that the result
already contains a value. /// /// Care must be taken to ensure that this is only used in safe contexts /// where a T
value is active. /// /// \note The behavior is undefined if *this
does not contain a value. /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<Widget,int>{ /// make_widget() /// }; /// /// r->do_something(); ///
/// /// \return a pointer to the contained valuetypename std::remove_reference<typename std::add_const<T>::type>::type*operator->()const
typename std::add_lvalue_reference<T>::typeoperator*()
result
an optional
-like API for cases /// where it’s known that the result
already contains a value. /// /// Care must be taken to ensure that this is only used in safe contexts /// where a T
value is active. /// /// \note The behaviour is undefined if *this
does not contain a value /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<Widget,int>{ /// make_widget() /// }; /// /// (*r).do_something(); /// /// consume(*r); ///
/// /// \return a reference to the contained valuetypename std::add_rvalue_reference<T>::typeoperator*()
typename std::add_lvalue_reference<typename std::add_const<T>::type>::typeoperator*()const
typename std::add_rvalue_reference<typename std::add_const<T>::type>::typeoperator*()const
boolhas_value()const
true
if *this
contains a value /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto get_result() -> cpp::result<int, int>; /// auto r = get_result(); /// if (r.has_value()) { ... } /// /// assert(cpp::result<int,int>{42}.has_value()); /// /// assert(!cpp::result<int,int>{cpp::fail(42)}.has_value()); ///
/// /// \return true
if *this
contains a value, false
if *this
/// contains an errorboolhas_error()const
true
if *this
contains an error /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto get_result() -> cpp::result<int, int>; /// /// auto r = get_result(); /// if (r.has_error()) { ... } /// /// assert(!cpp::result<int,int>{42}.has_error()); /// /// assert(cpp::result<int,int>{cpp::fail(42)}.has_error()); ///
/// /// \return true
if *this
contains an error, false
if *this
/// contains a valuetypename std::add_lvalue_reference<T>::typevalue()
cpp /// assert(cpp::result<int,int>{42}.value() == 42); /// /// auto r = cpp::result<std::unique_ptr<int>,int>{ /// std::make_unique<int>(42) /// }; /// auto s = std::move(r).value(); /// /// try { /// auto r = cpp::result<int,int>{ cpp::fail(42) }; /// auto v = r.value(); /// } catch (const cpp::bad_result_access<int>& e) { /// assert(e.error() == 42); /// } ///
/// /// \throws bad_result_access*this
does not contain a value. /// /// \return the value of *this
typename std::add_rvalue_reference<T>::typevalue()
typename std::add_lvalue_reference<typename std::add_const<T>::type>::typevalue()const
typename std::add_rvalue_reference<typename std::add_const<T>::type>::typevalue()const
Eerror()const
error()
function will not throw any exceptions if E
does not /// throw any exceptions for the copy or move construction. /// /// This is to limit the possible scope for exceptions, and to allow the /// error type to be treated as a “status”-like type, where the /// default-constructed case is considered the “good” state. /// /// If this function is invoked on an rvalue of a result, the error is /// returned via move-construction /// /// ### Requires /// /// * std::is_default_constructible<E>::value
is true
/// * std::is_copy_constructible<E>::value
or /// std::is_move_constructible<E>::value
is true
/// * E{}
represents the “good” (non-error) state /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<int,std::error_code>{ 42 }; /// assert(r.error() == std::error_code{}); /// /// auto r = cpp::result<int,std::error_code>{ /// cpp::fail(std::io_errc::stream) /// }; /// /// assert(r.error() == std::io_errc::stream); ///
/// /// \return the error or a default-constructed error valueEerror()
template<typename String,typename = typename std::enable_if<( std::is_convertible<String,const std::string&>::value && std::is_copy_constructible<E>::value )>::type>typename std::add_lvalue_reference<T>::typeexpect(
result
, then this will /// consume the underlying error first, if there is one. /// /// \note This function exists as a means to allow for results to be marked /// used
without requiring directly inspecting the underlying value. /// This is, in effect, equivalent to assert(res.has_value())
, /// however it uses exceptions to ensure the stack can be unwound, and /// exceptions invoked. /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto start_service() -> cpp::result<void,int>; /// /// start_service().expect("Service failed to start!"); ///
/// /// \param message the message to provide to this expectation /// /// \return the value of *this
template<typename String,typename = typename std::enable_if<( std::is_convertible<String,const std::string&>::value && std::is_move_constructible<E>::value )>::type>typename std::add_rvalue_reference<T>::typeexpect(
template<typename String,typename = typename std::enable_if<( std::is_convertible<String,const std::string&>::value && std::is_copy_constructible<E>::value )>::type>typename std::add_lvalue_reference<typename std::add_const<T>::type>::typeexpect(
template<typename String,typename = typename std::enable_if<( std::is_convertible<String,const std::string&>::value && std::is_copy_constructible<E>::value )>::type>typename std::add_rvalue_reference<typename std::add_const<T>::type>::typeexpect(
template<typename U>typename std::remove_reference<T>::typevalue_or(
*this
has a value, /// otherwise returns \p default_value. /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<int,int>{42}; /// assert(r.value_or(0) == 42); /// /// auto r = cpp::result<int,int>{cpp::fail(42)}; /// assert(r.value_or(0) == 0); ///
/// /// \param default_value the value to use in case *this
contains an error /// \return the contained value or \p default_valuetemplate<typename U>typename std::remove_reference<T>::typevalue_or(
template<typename U>cpp::bitwizeshift::result::error_typeerror_or(
*this
has an error, /// otherwise returns \p default_error. /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto r = cpp::result<int,int>{42}; /// assert(r.error_or(0) == cpp::fail(0)); /// /// auto r = cpp::result<int,int>{cpp::fail(42)}; /// assert(r.error_or(0) == cpp::fail(42)); ///
/// /// \param default_error the error to use in case *this
is empty /// \return the contained value or \p default_errortemplate<typename U>cpp::bitwizeshift::result::error_typeerror_or(
template<typename U>cpp::bitwizeshift::result<typename std::decay<U>::type,E>and_then(
cpp /// auto r = cpp::result<int,int>{42}; /// assert(r.and_then(100) == 100); /// /// auto r = cpp::result<int,int>{cpp::fail(42)}; /// assert(r.and_then(100) == cpp::fail(42)); ///
/// /// \param value the value to return as a result /// \return a result of \p value if this contains a valuetemplate<typename Fn>std::invoke_result_t<Fn,const Tconst&>flat_map(
result
type or the program /// is ill-formed /// /// If this is called on an rvalue of result
which contains an error, /// the returned result
is constructed from an rvalue of that error. /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto to_string(int) -> cpp::result<std::string,int>; /// auto r = cpp::result<int,int>{42}; /// assert(r.flat_map(to_string) == "42"); /// /// auto r = cpp::result<int,int>{cpp::fail(42)}; /// assert(r.flat_map(to_string) == cpp::fail(42)); ///
/// /// \param fn the function to invoke with this /// \return The result of the function being calledtemplate<typename Fn>std::invoke_result_t<Fn,T&&>flat_map(
template<typename Fn>cpp::bitwizeshift::result<std::invoke_result_t<Fn,const Tconst&>,E>map(
result
which contains an error, /// the returned result
is constructed from an rvalue of that error. /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto to_string(int) -> std::string; /// auto r = cpp::result<int,int>{42}; /// assert(r.map(to_string) == "42"); /// /// auto r = cpp::result<int,int>{cpp::fail(42)}; /// assert(r.map(to_string) == cpp::fail(42)); ///
/// /// \param fn the function to invoke with this /// \return The result result of the function invokedtemplate<typename Fn>cpp::bitwizeshift::result<std::invoke_result_t<Fn,T&&>,E>map(
template<typename Fn>cpp::bitwizeshift::result<T,std::invoke_result_t<Fn,const Econst&>>map_error(
result
which contains a value, /// the returned result
is constructed from an rvalue of that value. /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto to_string(int) -> std::string; /// auto r = cpp::result<int,int>{42}; /// assert(r.map_error(to_string) == 42); /// /// auto r = cpp::result<int,int>{cpp::fail(42)}; /// assert(r.map_error(to_string) == cpp::fail("42")); /// /// auto r = cpp::result<std::string,int>{}; /// auto s = r.map(std::string::size); // 's' contains 'result<size_t,int>' ///
/// /// \param fn the function to invoke with this /// \return The result result of the function invokedtemplate<typename Fn>cpp::bitwizeshift::result<T,std::invoke_result_t<Fn,E&&>>map_error(
template<typename Fn>std::invoke_result_t<Fn,const Econst&>flat_map_error(
result
type or the program /// is ill-formed /// /// If this is called on an rvalue of result
which contains an error, /// the returned result
is constructed from an rvalue of that error. /// /// ### Examples /// /// Basic Usage: /// /// cpp /// auto to_string(int) -> cpp::result<int,std::string>; /// auto r = cpp::result<int,int>{42}; /// assert(r.flat_map(to_string) == 42); /// /// auto r = cpp::result<int,int>{cpp::fail(42)}; /// assert(r.flat_map(to_string) == cpp::fail("42")); ///
/// /// \param fn the function to invoke with this /// \return The result of the function being calledtemplate<typename Fn>std::invoke_result_t<Fn,E&&>flat_map_error(
Fields0
Protected member functions0
Protected fields0