Electroneum
Public Types | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
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. More...
 
 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. More...
 
 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. More...
 
 ~expect () noexcept
 
expectoperator= (expect const &src) noexcept(std::is_nothrow_copy_constructible< T >() &&std::is_nothrow_copy_assignable< T >())
 
expectoperator= (expect &&src) noexcept(std::is_nothrow_move_constructible< T >() &&std::is_nothrow_move_assignable< T >())
 
 operator bool () const noexcept
 
bool has_error () const noexcept
 
bool has_value () const noexcept
 
std::error_code error () const noexcept
 
Tvalue () &
 
T const & value () const &
 
T && value () &&
 
Toperator-> () noexcept
 
T const * operator-> () const noexcept
 
Toperator* () noexcept
 
T const & operator* () const noexcept
 
template<typename U >
bool equal (expect< U > const &rhs) const noexcept(noexcept(*std::declval< expect< T >>()== *rhs))
 
bool equal (std::error_code const &rhs) const noexcept
 
template<typename U , typename = detail::enable_if<!std::is_constructible<std::error_code, U>::value>>
bool equal (U const &rhs) const noexcept(noexcept(*std::declval< expect< T >>()==rhs))
 
bool matches (std::error_condition const &rhs) const noexcept
 

Private Member Functions

Tget () noexcept
 
T const & get () 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() [1/3]

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.

◆ equal() [2/3]

template<typename T >
bool expect< T >::equal ( std::error_code const &  rhs) const
inlinenoexcept
Returns
False if has_value(), otherwise error() == rhs.

◆ equal() [3/3]

template<typename T >
template<typename U , typename = detail::enable_if<!std::is_constructible<std::error_code, U>::value>>
bool expect< T >::equal ( U const &  rhs) const
inlinenoexcept
Note
This function is noexcept when U == T is noexcept.
Returns
False if has_error(), otherwise value() == rhs.

◆ error()

template<typename T >
std::error_code expect< T >::error ( ) const
inlinenoexcept
Returns
Error - always safe to call. Empty when !has_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_error()

template<typename T >
bool expect< T >::has_error ( ) const
inlinenoexcept
Returns
True if this is storing an error instead of a value.

◆ has_value()

template<typename T >
bool expect< T >::has_value ( ) const
inlinenoexcept
Returns
True if this is storing a value instead of an error.

◆ is_convertible()

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

◆ matches()

template<typename T >
bool expect< T >::matches ( std::error_condition const &  rhs) const
inlinenoexcept
Returns
False if has_value(), otherwise error() == rhs.

◆ maybe_throw()

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

◆ operator bool()

template<typename T >
expect< T >::operator bool ( ) const
inlineexplicitnoexcept
Returns
True if this is storing a value instead of an error.

◆ operator*() [1/2]

template<typename T >
T const& expect< T >::operator* ( ) const
inlinenoexcept
Returns
Value,
Precondition
has_value().

◆ operator*() [2/2]

template<typename T >
T& expect< T >::operator* ( )
inlinenoexcept
Returns
Value,
Precondition
has_value().

◆ operator->() [1/2]

template<typename T >
T const* expect< T >::operator-> ( ) const
inlinenoexcept
Returns
Value,
Precondition
has_value().

◆ operator->() [2/2]

template<typename T >
T* expect< T >::operator-> ( )
inlinenoexcept
Returns
Value,
Precondition
has_value().

◆ operator=() [1/2]

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

Move src into this. If src.has_value() && addressof(src) != this then `src.value() will be in a "moved from state".

◆ operator=() [2/2]

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() [1/3]

template<typename T >
T& expect< T >::value ( ) &
inline
Returns
Value if has_value() otherwise
Exceptions
<tt>std::system_error{error()}</tt>.

◆ value() [2/3]

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

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

◆ value() [3/3]

template<typename T >
T const& expect< T >::value ( ) const &
inline
Returns
Value if has_value() otherwise
Exceptions
<tt>std::system_error{error()}</tt>.

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

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