header_utils
Loading...
Searching...
No Matches
ghassanpl::sentinel_optional< T, SENTINEL, EQ > Struct Template Reference

An equivalent to std::optional<T> except that instead of keeping an additional bool to indicate value presence, it uses one of the potential values of T as a "sentinel" value to indicate nullopt. More...

#include <soptional.h>

Public Types

using sentinel_type

Public Member Functions

constexpr sentinel_optional (std::nullopt_t) noexcept
template<class... TYPES, std::enable_if_t< std::is_constructible_v< T, TYPES... >, int > = 0>
constexpr sentinel_optional (std::in_place_t, TYPES &&... args) noexcept(std::is_nothrow_constructible_v< T, TYPES... >)
template<class U = T, std::enable_if_t< !std::is_same_v< remove_cvref_t< U >, sentinel_optional > &&!std::is_same_v< remove_cvref_t< U >, std::in_place_t > &&!std::is_same_v< std::remove_cv_t< U >, bool > &&std::is_constructible_v< T, U >, int > = 0>
constexpr sentinel_optional (U &&right) noexcept(std::is_nothrow_constructible_v< T, U >)
template<class U, std::enable_if_t< std::is_constructible_v< T, const U & >, int > = 0>
constexpr sentinel_optional (const sentinel_optional< U > &right) noexcept(std::is_nothrow_constructible_v< T, const U & >)
template<class U, std::enable_if_t< std::is_constructible_v< T, U >, int > = 0>
constexpr sentinel_optional (sentinel_optional< U > &&right) noexcept(std::is_nothrow_constructible_v< T, U >)
constexpr sentinel_optional & operator= (std::nullopt_t) noexcept
template<class U = T, std::enable_if_t< !std::is_same_v< sentinel_optional, remove_cvref_t< U > > &&std::is_constructible_v< T, U > &&std::is_assignable_v< T &, U >, int > = 0>
constexpr sentinel_optional & operator= (U &&right) noexcept(std::is_nothrow_assignable_v< T &, U > &&std::is_nothrow_constructible_v< T, U >)
template<class U, std::enable_if_t< !(std::is_same_v< T, U >||std::is_assignable_v< T &, sentinel_optional< U > & >||std::is_assignable_v< T &, const sentinel_optional< U > & >||std::is_assignable_v< T &, const sentinel_optional< U > >||std::is_assignable_v< T &, sentinel_optional< U > >) &&std::is_constructible_v< T, const U & > &&std::is_assignable_v< T &, const U & >, int > = 0>
constexpr sentinel_optional & operator= (const sentinel_optional< U > &right) noexcept(std::is_nothrow_assignable_v< T &, const U & > &&std::is_nothrow_constructible_v< T, const U & >)
template<class U, std::enable_if_t< !(std::is_same_v< T, U >||std::is_assignable_v< T &, sentinel_optional< U > & >||std::is_assignable_v< T &, const sentinel_optional< U > & >||std::is_assignable_v< T &, const sentinel_optional< U > >||std::is_assignable_v< T &, sentinel_optional< U > >) &&std::is_constructible_v< T, U > &&std::is_assignable_v< T &, U >, int > = 0>
constexpr sentinel_optional & operator= (sentinel_optional< U > &&right) noexcept(std::is_nothrow_assignable_v< T &, U > &&std::is_nothrow_constructible_v< T, U >)
template<class... TYPES>
constexpr T & emplace (TYPES &&... args) noexcept(std::is_nothrow_constructible_v< T, TYPES... >)
constexpr void assert_value () const
constexpr const T * operator-> () const
constexpr T * operator-> ()
constexpr T & operator* () &
constexpr const T & operator* () const &
constexpr T && operator* () &&
constexpr const T && operator* () const &&
constexpr bool has_value () const noexcept
constexpr operator bool () const noexcept
constexpr const T & value () const &
constexpr T & value () &
constexpr T && value () &&
constexpr const T && value () const &&
constexpr const T & raw_value () const &
 Returns the value without asserting has_value().
constexpr T & raw_value () &
 Returns the value without asserting has_value().
constexpr T && raw_value () &&
 Returns the value without asserting has_value().
constexpr const T && raw_value () const &&
 Returns the value without asserting has_value().
constexpr void reset () noexcept

Friends

constexpr bool operator== (const sentinel_optional &lhs, const sentinel_optional &rhs)
constexpr bool operator!= (const sentinel_optional &lhs, const sentinel_optional &rhs)
constexpr bool operator< (const sentinel_optional &lhs, const sentinel_optional &rhs)
constexpr bool operator<= (const sentinel_optional &lhs, const sentinel_optional &rhs)
constexpr bool operator> (const sentinel_optional &lhs, const sentinel_optional &rhs)
constexpr bool operator>= (const sentinel_optional &lhs, const sentinel_optional &rhs)
constexpr auto operator<=> (const sentinel_optional &lhs, const sentinel_optional &rhs)
constexpr bool operator== (const sentinel_optional &opt, std::nullopt_t)
constexpr auto operator<=> (const sentinel_optional &opt, std::nullopt_t)

Detailed Description

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
struct ghassanpl::sentinel_optional< T, SENTINEL, EQ >

An equivalent to std::optional<T> except that instead of keeping an additional bool to indicate value presence, it uses one of the potential values of T as a "sentinel" value to indicate nullopt.

This makes the value the same size/alignment as T while still keeping the optional API. Mostly useful for enums or special types, somewhat useful for floating-points, sometimes useful for pointers.

Note
This TECHNICALLY could work with C++17, but its only practically useful with C++20 since SENTINEL can be of more types, especially floats.
Template Parameters
Tthe value you want to hold
SENTINELa value that will represent the nullopt; needs to be assignable to T, and comparable with T using the EQ functor type
EQa functor type whose operator() will tell us if value == SENTINEL; exists because some types, like floats, cannot be straight-compared with NAN as a sentinel value

Definition at line 55 of file soptional.h.

Member Typedef Documentation

◆ sentinel_type

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
using ghassanpl::sentinel_optional< T, SENTINEL, EQ >::sentinel_type

Definition at line 57 of file soptional.h.

Constructor & Destructor Documentation

◆ sentinel_optional() [1/6]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
ghassanpl::sentinel_optional< T, SENTINEL, EQ >::sentinel_optional ( )
inlineconstexprnoexcept

Definition at line 61 of file soptional.h.

◆ sentinel_optional() [2/6]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
ghassanpl::sentinel_optional< T, SENTINEL, EQ >::sentinel_optional ( std::nullopt_t )
inlineconstexprnoexcept

Definition at line 62 of file soptional.h.

◆ sentinel_optional() [3/6]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
template<class... TYPES, std::enable_if_t< std::is_constructible_v< T, TYPES... >, int > = 0>
ghassanpl::sentinel_optional< T, SENTINEL, EQ >::sentinel_optional ( std::in_place_t ,
TYPES &&... args )
inlineexplicitconstexprnoexcept

Definition at line 65 of file soptional.h.

◆ sentinel_optional() [4/6]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
template<class U = T, std::enable_if_t< !std::is_same_v< remove_cvref_t< U >, sentinel_optional > &&!std::is_same_v< remove_cvref_t< U >, std::in_place_t > &&!std::is_same_v< std::remove_cv_t< U >, bool > &&std::is_constructible_v< T, U >, int > = 0>
ghassanpl::sentinel_optional< T, SENTINEL, EQ >::sentinel_optional ( U && right)
inlineconstexprnoexcept

Definition at line 76 of file soptional.h.

◆ sentinel_optional() [5/6]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
template<class U, std::enable_if_t< std::is_constructible_v< T, const U & >, int > = 0>
ghassanpl::sentinel_optional< T, SENTINEL, EQ >::sentinel_optional ( const sentinel_optional< U > & right)
inlineexplicitconstexprnoexcept

Definition at line 82 of file soptional.h.

◆ sentinel_optional() [6/6]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
template<class U, std::enable_if_t< std::is_constructible_v< T, U >, int > = 0>
ghassanpl::sentinel_optional< T, SENTINEL, EQ >::sentinel_optional ( sentinel_optional< U > && right)
inlineexplicitconstexprnoexcept

Definition at line 89 of file soptional.h.

Member Function Documentation

◆ assert_value()

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
void ghassanpl::sentinel_optional< T, SENTINEL, EQ >::assert_value ( ) const
inlineconstexpr

Definition at line 160 of file soptional.h.

◆ emplace()

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
template<class... TYPES>
T & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::emplace ( TYPES &&... args)
inlineconstexprnoexcept

Definition at line 154 of file soptional.h.

◆ has_value()

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
bool ghassanpl::sentinel_optional< T, SENTINEL, EQ >::has_value ( ) const
inlinenodiscardconstexprnoexcept

Definition at line 197 of file soptional.h.

◆ operator bool()

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator bool ( ) const
inlineexplicitconstexprnoexcept

Definition at line 198 of file soptional.h.

◆ operator*() [1/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
T & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator* ( ) &
inlinenodiscardconstexpr

Definition at line 173 of file soptional.h.

◆ operator*() [2/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
T && ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator* ( ) &&
inlinenodiscardconstexpr

Definition at line 185 of file soptional.h.

◆ operator*() [3/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
const T & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator* ( ) const &
inlinenodiscardconstexpr

Definition at line 179 of file soptional.h.

◆ operator*() [4/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
const T && ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator* ( ) const &&
inlinenodiscardconstexpr

Definition at line 191 of file soptional.h.

◆ operator->() [1/2]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
T * ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator-> ( )
inlinenodiscardconstexpr

Definition at line 167 of file soptional.h.

◆ operator->() [2/2]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
const T * ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator-> ( ) const
inlinenodiscardconstexpr

Definition at line 162 of file soptional.h.

◆ operator=() [1/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
template<class U, std::enable_if_t< !(std::is_same_v< T, U >||std::is_assignable_v< T &, sentinel_optional< U > & >||std::is_assignable_v< T &, const sentinel_optional< U > & >||std::is_assignable_v< T &, const sentinel_optional< U > >||std::is_assignable_v< T &, sentinel_optional< U > >) &&std::is_constructible_v< T, const U & > &&std::is_assignable_v< T &, const U & >, int > = 0>
sentinel_optional & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator= ( const sentinel_optional< U > & right)
inlineconstexprnoexcept

Definition at line 122 of file soptional.h.

◆ operator=() [2/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
template<class U, std::enable_if_t< !(std::is_same_v< T, U >||std::is_assignable_v< T &, sentinel_optional< U > & >||std::is_assignable_v< T &, const sentinel_optional< U > & >||std::is_assignable_v< T &, const sentinel_optional< U > >||std::is_assignable_v< T &, sentinel_optional< U > >) &&std::is_constructible_v< T, U > &&std::is_assignable_v< T &, U >, int > = 0>
sentinel_optional & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator= ( sentinel_optional< U > && right)
inlineconstexprnoexcept

Definition at line 143 of file soptional.h.

◆ operator=() [3/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
sentinel_optional & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator= ( std::nullopt_t )
inlineconstexprnoexcept

Definition at line 95 of file soptional.h.

◆ operator=() [4/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
template<class U = T, std::enable_if_t< !std::is_same_v< sentinel_optional, remove_cvref_t< U > > &&std::is_constructible_v< T, U > &&std::is_assignable_v< T &, U >, int > = 0>
sentinel_optional & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::operator= ( U && right)
inlineconstexprnoexcept

Definition at line 105 of file soptional.h.

◆ raw_value() [1/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
T & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::raw_value ( ) &
inlinenodiscardconstexpr

Returns the value without asserting has_value().

Definition at line 222 of file soptional.h.

◆ raw_value() [2/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
T && ghassanpl::sentinel_optional< T, SENTINEL, EQ >::raw_value ( ) &&
inlinenodiscardconstexpr

Returns the value without asserting has_value().

Definition at line 226 of file soptional.h.

◆ raw_value() [3/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
const T & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::raw_value ( ) const &
inlinenodiscardconstexpr

Returns the value without asserting has_value().

Definition at line 218 of file soptional.h.

◆ raw_value() [4/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
const T && ghassanpl::sentinel_optional< T, SENTINEL, EQ >::raw_value ( ) const &&
inlinenodiscardconstexpr

Returns the value without asserting has_value().

Definition at line 230 of file soptional.h.

◆ reset()

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
void ghassanpl::sentinel_optional< T, SENTINEL, EQ >::reset ( )
inlineconstexprnoexcept

Definition at line 265 of file soptional.h.

◆ value() [1/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
T & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::value ( ) &
inlinenodiscardconstexpr

Definition at line 204 of file soptional.h.

◆ value() [2/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
T && ghassanpl::sentinel_optional< T, SENTINEL, EQ >::value ( ) &&
inlinenodiscardconstexpr

Definition at line 208 of file soptional.h.

◆ value() [3/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
const T & ghassanpl::sentinel_optional< T, SENTINEL, EQ >::value ( ) const &
inlinenodiscardconstexpr

Definition at line 200 of file soptional.h.

◆ value() [4/4]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
const T && ghassanpl::sentinel_optional< T, SENTINEL, EQ >::value ( ) const &&
inlinenodiscardconstexpr

Definition at line 212 of file soptional.h.

◆ operator!=

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
bool operator!= ( const sentinel_optional< T, SENTINEL, EQ > & lhs,
const sentinel_optional< T, SENTINEL, EQ > & rhs )
friend

Definition at line 271 of file soptional.h.

◆ operator<

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
bool operator< ( const sentinel_optional< T, SENTINEL, EQ > & lhs,
const sentinel_optional< T, SENTINEL, EQ > & rhs )
friend

Definition at line 275 of file soptional.h.

◆ operator<=

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
bool operator<= ( const sentinel_optional< T, SENTINEL, EQ > & lhs,
const sentinel_optional< T, SENTINEL, EQ > & rhs )
friend

Definition at line 279 of file soptional.h.

◆ operator<=> [1/2]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
auto operator<=> ( const sentinel_optional< T, SENTINEL, EQ > & lhs,
const sentinel_optional< T, SENTINEL, EQ > & rhs )
friend

Definition at line 291 of file soptional.h.

◆ operator<=> [2/2]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
auto operator<=> ( const sentinel_optional< T, SENTINEL, EQ > & opt,
std::nullopt_t  )
friend

Definition at line 297 of file soptional.h.

◆ operator== [1/2]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
bool operator== ( const sentinel_optional< T, SENTINEL, EQ > & lhs,
const sentinel_optional< T, SENTINEL, EQ > & rhs )
friend

Definition at line 267 of file soptional.h.

◆ operator== [2/2]

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
bool operator== ( const sentinel_optional< T, SENTINEL, EQ > & opt,
std::nullopt_t  )
friend

Definition at line 296 of file soptional.h.

◆ operator>

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
bool operator> ( const sentinel_optional< T, SENTINEL, EQ > & lhs,
const sentinel_optional< T, SENTINEL, EQ > & rhs )
friend

Definition at line 283 of file soptional.h.

◆ operator>=

template<typename T, auto SENTINEL = T{}, typename EQ = detail::better_equal_to>
bool operator>= ( const sentinel_optional< T, SENTINEL, EQ > & lhs,
const sentinel_optional< T, SENTINEL, EQ > & rhs )
friend

Definition at line 287 of file soptional.h.