Monero
Loading...
Searching...
No Matches
expect< T > Class Template Reference

#include <expect.h>

Public Types

using value_type = T
using error_type = std::error_code

Public Member Functions

 expect ()=delete
 expect (std::error_code const &code) noexcept
 expect (T val) noexcept(std::is_nothrow_move_constructible< T >())
 Store a value, val, in the expect object.
 expect (expect const &src) noexcept(std::is_nothrow_copy_constructible< T >())
template<typename U, typename = detail::enable_if<is_convertible<U const&>()>>
 expect (expect< U > const &src) noexcept(std::is_nothrow_constructible< T, U const & >())
 Copy conversion from U to T.
 expect (expect &&src) noexcept(std::is_nothrow_move_constructible< T >())
template<typename U, typename = detail::enable_if<is_convertible<U>()>>
 expect (expect< U > &&src) noexcept(std::is_nothrow_constructible< T, U >())
 Move conversion from U to T.
 ~expect () noexcept
expectoperator= (expect const &src) noexcept(std::is_nothrow_copy_constructible< T >() &&std::is_nothrow_copy_assignable< T >())
T && value () &&
*return pre has_value ()`. T *operator->() noexcept
*return pre has_value ()`. T const *operator->() const noexcept
*return pre has_value ()`. T &operator*() noexcept
*return pre has_value ()`. T const &operator*() const noexcept
template<typename U>
bool equal (expect< U > const &rhs) const noexcept(noexcept(*std::declval< expect< T > >()== *rhs))
*return False if has_value ()`
*return False if otherwise error ()

Public Attributes

*return Value

Private Member Functions

Tget () noexcept
T constget () const noexcept
template<typename U>
void store (U &&value) noexcept(std::is_nothrow_constructible< T, U >())
void maybe_throw () const

Static Private Member Functions

template<typename U>
static constexpr bool is_convertible () noexcept

Private Attributes

std::error_code code_
std::aligned_storage< sizeof(T), alignof(T)>::type storage_

Detailed Description

template<typename T>
class expect< T >

expect<T> is a value or error implementation, similar to Rust std::result or various C++ proposals (boost::expected, boost::outcome). This implementation currently has a strict error type, std::error_code, and a templated value type T. expect<T> is implicitly convertible from T or std::error_code, and one expect<T> object type is implicitly convertible to another expect<U> object iff the destination value type can be implicitly constructed from the source value type (i.e. struct U { ... U(T src) { ...} ... };).

operator== and operator!= are the only comparison operators provided; comparison between different value types is allowed provided the two values types have a operator== defined between them (i.e. assert(expect<int>{100} == expect<short>{100});). Comparisons can also be done against std::error_code objects or error code enums directly (i.e. assert(expect<int>{make_error_code(common_error::kInvalidArgument)} == error::kInvalidArgument)). Comparison of default constructed std::error_code will always fail. "Generic" comparisons can be done with std::error_condition via the matches method only (i.e. assert(expect<int>{make_error_code{common_error::kInvalidErrorCode}.matches(std::errc::invalid_argument))), operator== and operator!= will not work with std::errc or std::error_condition. A comparison with matches is more expensive because an equivalency between error categories is computed, but is recommended when an error can be one of several categories (this is going to be the case in nearly every situation when calling a function from another C++ struct/class).

expect<void> is a special case with no stored value. It is used by functions that can fail, but otherwise would return void. It is useful for consistency; all macros, standalone functions, and comparison operators work with expect<void>.

Note
See src/common/error.h for creating a custom error enum.

Member Typedef Documentation

◆ error_type

template<typename T>
using expect< T >::error_type = std::error_code

◆ value_type

template<typename T>
using expect< T >::value_type = T

Constructor & Destructor Documentation

◆ expect() [1/7]

template<typename T>
expect< T >::expect ( )
delete

◆ expect() [2/7]

template<typename T>
expect< T >::expect ( std::error_code const & code)
inlinenoexcept

Store an error, code, in the expect object. If code creates a std::error_code object whose .value() == 0, then error() will be set to common_error::kInvalidErrorCode.

◆ expect() [3/7]

template<typename T>
expect< T >::expect ( T val)
inlinenoexcept

Store a value, val, in the expect object.

◆ expect() [4/7]

template<typename T>
expect< T >::expect ( expect< T > const & src)
inlinenoexcept

◆ expect() [5/7]

template<typename T>
template<typename U, typename = detail::enable_if<is_convertible<U const&>()>>
expect< T >::expect ( expect< U > const & src)
inlinenoexcept

Copy conversion from U to T.

◆ expect() [6/7]

template<typename T>
expect< T >::expect ( expect< T > && src)
inlinenoexcept

◆ expect() [7/7]

template<typename T>
template<typename U, typename = detail::enable_if<is_convertible<U>()>>
expect< T >::expect ( expect< U > && src)
inlinenoexcept

Move conversion from U to T.

◆ ~expect()

template<typename T>
expect< T >::~expect ( )
inlinenoexcept

Member Function Documentation

◆ equal()

template<typename T>
template<typename U>
bool expect< T >::equal ( expect< U > const & rhs) const
inlinenoexcept
Note
This function is noexcept when U == T is noexcept.
Returns
True if has_value() == rhs.has_value() and if values or errors are equal.

◆ error()

template<typename T>
*return False if otherwise expect< T >::error ( )

◆ get() [1/2]

template<typename T>
T const & expect< T >::get ( ) const
inlineprivatenoexcept

◆ get() [2/2]

template<typename T>
T & expect< T >::get ( )
inlineprivatenoexcept

◆ has_value() [1/5]

template<typename T>
*return False if expect< T >::has_value ( )

◆ has_value() [2/5]

template<typename T>
*return pre expect< T >::has_value ( ) &
inlinenoexcept

◆ has_value() [3/5]

template<typename T>
*return pre expect< T >::has_value ( ) ->() noexcept
inline

◆ has_value() [4/5]

template<typename T>
*return pre expect< T >::has_value ( ) const &
inlinenoexcept

◆ has_value() [5/5]

template<typename T>
*return pre expect< T >::has_value ( ) const ->() const noexcept
inline

◆ is_convertible()

template<typename T>
template<typename U>
constexpr bool expect< T >::is_convertible ( )
inlinestaticconstexprprivatenoexcept

◆ maybe_throw()

template<typename T>
void expect< T >::maybe_throw ( ) const
inlineprivate

◆ operator=()

template<typename T>
expect & expect< T >::operator= ( expect< T > const & src)
inlinenoexcept

◆ store()

template<typename T>
template<typename U>
void expect< T >::store ( U && value)
inlineprivatenoexcept

◆ value()

template<typename T>
T && expect< T >::value ( ) &&
inline

Move src into this. If src.has_value() && addressof(src) != this then src.value() will be in a "moved from state". */ expect& operator=(expect&& src) noexcept(std::is_nothrow_move_constructible<T>() && std::is_nothrow_move_assignable<T>()) { if (this != std::addressof(src)) { if (has_value() && src.has_value()) get() = std::move(src.get()); else if (has_value()) get().~T(); else if (src.has_value()) store(std::move(src.get())); code_ = src.error(); } return *this; } @iverbatim \return True if this is storing a value instead of an error. @endiverbatim\ilinebr explicit operator bool() const noexcept { return has_value(); } @iverbatim \return True if this is storing an error instead of a value. @endiverbatim\ilinebr bool has_error() const noexcept { return bool(code_); } @iverbatim \return True if this is storing a value instead of an error. @endiverbatim\ilinebr bool has_value() const noexcept { return !has_error(); } @iverbatim \return Error - always safe to call. Empty when !has_error(). @endiverbatim\ilinebr std::error_code error() const noexcept { return code_; } @iverbatim \return Value if has_value() otherwise \throw std::system_error{error()}. @endiverbatim\ilinebr T& value() & { maybe_throw(); return get(); } @iverbatim \return Value if has_value() otherwise \throw std::system_error{error()}`. T const& value() const & { maybe_throw(); return get(); }

/*! Same as other overloads, but expressions such as foo(bar().value()) will automatically perform moves with no copies.

Member Data Documentation

◆ code_

template<typename T>
std::error_code expect< T >::code_
private

◆ storage_

template<typename T>
std::aligned_storage<sizeof(T),alignof(T)>::type expect< T >::storage_
private

◆ Value

template<typename T>
*return expect< T >::Value

The documentation for this class was generated from the following file: