All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
gears::utility::maybe< T > Class Template Reference

An optional data type. More...

Inherits MaybeBase< T >.

Public Types

using value_type = T
 

Public Member Functions

constexpr maybe () noexcept
 Constructs maybe in a disengaged state.
 
constexpr maybe (nothing_t) noexcept
 Constructs maybe in a disengaged state.
 
constexpr maybe (const T &value)
 Constructs maybe in an engaged state containing the value.
 
constexpr maybe (T &&value)
 Constructs maybe in an engaged state containing the value.
 
template<typename... Args>
constexpr maybe (in_place_t, Args &&...args)
 Constructs maybe in place. More...
 
 maybe (const maybe &rhs)
 Copy constructor. More...
 
 maybe (maybe &&rhs) noexcept(std::is_nothrow_move_constructible< T >())
 Move constructor. More...
 
maybeoperator= (nothing_t) noexcept
 Assignment with nothing. More...
 
maybeoperator= (const maybe &rhs)
 Copy assignment. Behaves similar to the copy constructor.
 
maybeoperator= (maybe &&rhs) noexcept(std::is_nothrow_move_assignable< T >()&&std::is_nothrow_move_constructible< T >())
 Move assignment. Behaves similar to the move constructor.
 
template<typename U , meta::EnableIf< std::is_constructible< T, meta::Decay< U >>, std::is_assignable< T, meta::Decay< U >>> = meta::_>
maybeoperator= (U &&value)
 Assigns maybe in an engaged state with the value given. More...
 
template<typename... Args>
void emplace (Args &&...args)
 Constructs the contained value in place. More...
 
constexpr operator bool () const noexcept
 Checks if the current state is engaged. More...
 
template<typename U >
constexpr T value_or (U &&value) const
 Accesses the contained value or a reasonable default. More...
 
constexpr const T * operator-> () const
 Returns a pointer to the contained value. More...
 
T * operator-> ()
 
constexpr const T & operator* () const
 Returns a reference to the contained value. More...
 
T & operator* ()
 
constexpr const T & value () const
 Accesses the contained value. More...
 
T & value ()
 

Related Functions

(Note that these are not member functions.)

template<typename T >
constexpr maybe< meta::Decay< T > > just (T &&t)
 Helper function to create an engaged maybe object. More...
 
Comparison with maybe<T> and maybe<T>

Compares the contained value of both maybe<T>s.

If both maybe<T> are disengaged, then the comparison returns true. If only one maybe<T> is disengaged, then the comparison returns false. Otherwise it uses the internal comparison operator on both contained values.

Parameters
lhsLeft hand side of the comparison
rhsRight hand side of the comparison
template<typename T >
constexpr bool operator== (const maybe< T > &lhs, const maybe< T > &rhs)
 Checks if two maybe<T> are equal.
 
template<typename T >
constexpr bool operator!= (const maybe< T > &lhs, const maybe< T > &rhs)
 Checks if two maybe<T> are not equal.
 
template<typename T >
constexpr bool operator< (const maybe< T > &lhs, const maybe< T > &rhs)
 Checks if one maybe<T> is less than another maybe<T>.
 
template<typename T >
constexpr bool operator> (const maybe< T > &lhs, const maybe< T > &rhs)
 Checks if one maybe<T> is greater than another maybe<T>.
 
template<typename T >
constexpr bool operator<= (const maybe< T > &lhs, const maybe< T > &rhs)
 Checks if one maybe<T> is less than or equal to another maybe<T>.
 
template<typename T >
constexpr bool operator>= (const maybe< T > &lhs, const maybe< T > &rhs)
 Checks if one maybe<T> is greater than or equal to another maybe<T>.
 
Comparison with nothing.

Compares maybe<T> with nothing.

For completeness sakes, you can compare nothing with maybe<T>. nothing will always evaluate to false. So all comparisons are based on truth values with maybe converted into a boolean true or false depending on the engaged state it is at. For example:

my_maybe == utility::nothing;
// bool(my_maybe) == false

Where bool(my_maybe) is given through operator bool()

Although only one comparison is shown, all comparison operators are overloaded for both directions.

template<typename T >
constexpr bool operator== (const maybe< T > &lhs, nothing_t) noexcept
 Compares with nothing
 
Comparisons with other values.

Compares the contained value with another value.

Although both directions are not shown, both directions of operator overloads are provided. Comparison is done through the operator overloaded, i.e. the operator== overload would compare the contained value and the other value with their operator==.

template<typename T >
constexpr bool operator== (const maybe< T > &lhs, const T &value)
 If the current state is disengaged, returns false. Otherwise compares.
 
template<typename T >
constexpr bool operator!= (const maybe< T > &lhs, const T &value)
 If the current state is disengaged, returns true. Otherwise compares.
 
template<typename T >
constexpr bool operator< (const maybe< T > &lhs, const T &value)
 If the current state is disengaged, returns true. Otherwise compares.
 
template<typename T >
constexpr bool operator> (const maybe< T > &lhs, const T &value)
 If the current state is disengaged, returns false. Otherwise compares.
 
template<typename T >
constexpr bool operator>= (const maybe< T > &lhs, const T &value)
 If the current state is disengaged, returns false. Otherwise compares.
 
template<typename T >
constexpr bool operator<= (const maybe< T > &lhs, const T &value)
 If the current state is disengaged, returns true. Otherwise compares.
 

Detailed Description

template<typename T>
class gears::utility::maybe< T >

Implements an optional data type, similar to Haskell's Maybe monad and Boost's boost::optional. It manages a value that might not be there, similar to a pointer being possibly null. A lot of effort to make maybe<T> be a possible constant expression was made. As a result of this, you can make maybe be a constexpr variable if needed.

The type to manage must not be nothing_t, in_place_t, a reference, or another maybe. This might change in the future, but for now this is the restriction in place.

maybe has two states – disengaged and engaged states. A disengaged state is when maybe does not contain a value, i.e. it contains nothing. An engaged state is when maybe does contain a value to manage.

Example:

#include <gears/utility.hpp>
#include <iostream>
namespace util = gears::utility;
util::maybe<int> special(int x) {
return x > 10 ? util::just(x * 10) : util::nothing;
}
int main() {
auto x = special(8);
auto y = special(25);
if(x) {
std::cout << "x has a value\n";
}
if(y) {
std::cout << "y has a value\n";
}
std::cout << x.value_or(20) << '\n' << y.value_or(10) << '\n';
}

Output:

y has a value
20
250
Template Parameters
TUnderlying type to manage.

Definition at line 53 of file traits.hpp.

Constructor & Destructor Documentation

template<typename T >
template<typename... Args>
constexpr gears::utility::maybe< T >::maybe ( in_place_t  ,
Args &&...  args 
)
inlineexplicit

Constructs maybe in place with the in_place tag.

Example:

#include <gears/utility.hpp>
#include <iostream>
#include <string>
namespace util = gears::utility;
struct my_class {
private:
std::string name;
public:
my_class(std::string name): name(std::move(name)) {
std::cout << "constructed\n";
}
my_class(my_class&& o): name(std::move(o.name)) {
std::cout << "moved\n";
}
};
int main() {
util::maybe<my_class> x(my_class{"Bob"});
std::cout << "---\n";
util::maybe<my_class> y(util::in_place, "Bob");
}

Output:

constructed
moved
---
constructed
Parameters
argsParameters to forward to the constructor.

Definition at line 203 of file maybe.hpp.

template<typename T >
gears::utility::maybe< T >::maybe ( const maybe< T > &  rhs)
inline

Copy constructs maybe. If rhs is disengaged, then the class is constructed as disengaged. Otherwise, the class is constructed as engaged.

Parameters
rhsOther maybe to copy from.

Definition at line 213 of file maybe.hpp.

template<typename T >
gears::utility::maybe< T >::maybe ( maybe< T > &&  rhs)
inlinenoexcept

Move constructs maybe. If rhs is disengaged, then the class is constructed as disengaged. Otherwise, the class is constructed as engaged. The move constructor of the internal class should not throw.

Parameters
rhsOther maybe to move from.

Definition at line 228 of file maybe.hpp.

Member Function Documentation

template<typename T >
template<typename... Args>
void gears::utility::maybe< T >::emplace ( Args &&...  args)
inline

Constructs the contained value in place. If the current state is engaged, then it is replaced with the newly constructed value. When replaced, then the destructor of the managed type is called. This works similar to the in_place_t constructor.

Parameters
argsParameter to forward to the managed type's constructor.

Definition at line 316 of file maybe.hpp.

template<typename T >
constexpr gears::utility::maybe< T >::operator bool ( ) const
inlineexplicitnoexcept

Checks if the current state is engaged.

Returns
true if the current state is engaged, false otherwise.

Definition at line 387 of file maybe.hpp.

template<typename T >
constexpr const T& gears::utility::maybe< T >::operator* ( ) const
inline

Returns a reference to the contained value. If the current state is disengaged, then the behaviour is undefined.

Returns
Reference to the contained value.

Definition at line 355 of file maybe.hpp.

template<typename T >
constexpr const T* gears::utility::maybe< T >::operator-> ( ) const
inline

Returns a pointer to the contained value. If the current state is disengaged, then the behaviour is undefined. This is should only be used for accessing member functions of the internal value.

struct my_class { int x; };
utility::maybe<my_class> stuff({ 10 });
// access my_class::x
std::cout << stuff->x;
Returns
Pointer to contained value.

Definition at line 338 of file maybe.hpp.

template<typename T >
maybe& gears::utility::maybe< T >::operator= ( nothing_t  )
inlinenoexcept

Assigns the internal data with nothing. This results in a disengaged state.

utility::maybe<int> x(4);
x = utility::nothing;

Definition at line 246 of file maybe.hpp.

template<typename T >
template<typename U , meta::EnableIf< std::is_constructible< T, meta::Decay< U >>, std::is_assignable< T, meta::Decay< U >>> = meta::_>
maybe& gears::utility::maybe< T >::operator= ( U &&  value)
inline

Assigns maybe in an engaged state with the value given. If current state is engaged, then the value is replaced with the one given, when replaced then the destructor of the managed type is called.

Parameters
valueThe value to assign to maybe.

Definition at line 295 of file maybe.hpp.

template<typename T >
constexpr const T& gears::utility::maybe< T >::value ( ) const
inline

Accesses the contained value. If the current state is disengaged, an exception is thrown.

Exceptions
gears::utility::bad_maybe_accessThrown if the current state is disengaged.
Returns
Returns the a reference to the contained value.

Definition at line 373 of file maybe.hpp.

template<typename T >
template<typename U >
constexpr T gears::utility::maybe< T >::value_or ( U &&  value) const
inline

Accesses the contained value of a reasonable default. Unlike value and operator* this does not return a reference but a copy.

Parameters
valueThe default value if the current state is disengaged.
Returns
The contained value or a default if current state is disengaged.

Definition at line 401 of file maybe.hpp.

Friends And Related Function Documentation

template<typename T >
constexpr maybe< meta::Decay< T > > just ( T &&  t)
related

Helper function to create an engaged maybe object. This typically moves or copies and does not create the contained value in place.

Parameters
tValue for the contained value.
Returns
A new maybe object that is engaged with the value.

Definition at line 417 of file maybe.hpp.