1212#define NONSTD_OPTIONAL_LITE_HPP
1313
1414#define optional_lite_MAJOR 3
15- #define optional_lite_MINOR 5
15+ #define optional_lite_MINOR 6
1616#define optional_lite_PATCH 0
1717
1818#define optional_lite_VERSION optional_STRINGIFY (optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH)
4444# define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD )
4545#endif
4646
47+ // Control presence of extensions:
48+
49+ #ifndef optional_CONFIG_NO_EXTENSIONS
50+ #define optional_CONFIG_NO_EXTENSIONS 0
51+ #endif
52+
4753// Control presence of exception handling (try and auto discover):
4854
4955#ifndef optional_CONFIG_NO_EXCEPTIONS
5056# if defined(_MSC_VER)
5157# include < cstddef> // for _HAS_EXCEPTIONS
5258# endif
53- # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
59+ # if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (defined( _HAS_EXCEPTIONS) && (_HAS_EXCEPTIONS) )
5460# define optional_CONFIG_NO_EXCEPTIONS 0
5561# else
5662# define optional_CONFIG_NO_EXCEPTIONS 1
5763# endif
5864#endif
5965
60- // C++ language version detection (C++20 is speculative):
66+ // C++ language version detection (C++23 is speculative):
6167// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
6268
6369#ifndef optional_CPLUSPLUS
7379#define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L )
7480#define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L )
7581#define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L )
76- #define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L )
82+ #define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202002L )
83+ #define optional_CPP23_OR_GREATER ( optional_CPLUSPLUS >= 202300L )
7784
7885// C++ language version (represent 98 as 3):
7986
@@ -782,7 +789,7 @@ union storage_t
782789
783790 void construct_value ( value_type && v )
784791 {
785- ::new ( value_ptr () ) value_type ( std::move ( v ) );
792+ ::new ( const_cast < void *>( static_cast < const volatile void *>( value_ptr ()) ) ) value_type ( std::move ( v ) );
786793 }
787794
788795 template < class ... Args >
@@ -794,13 +801,13 @@ union storage_t
794801 template < class ... Args >
795802 void emplace ( Args&&... args )
796803 {
797- ::new ( value_ptr () ) value_type ( std::forward<Args>(args)... );
804+ ::new ( const_cast < void *>( static_cast < const volatile void *>( value_ptr ()) ) ) value_type ( std::forward<Args>(args)... );
798805 }
799806
800807 template < class U , class ... Args >
801808 void emplace ( std::initializer_list<U> il, Args&&... args )
802809 {
803- ::new ( value_ptr () ) value_type ( il, std::forward<Args>(args)... );
810+ ::new ( const_cast < void *>( static_cast < const volatile void *>( value_ptr ()) ) ) value_type ( il, std::forward<Args>(args)... );
804811 }
805812
806813#endif
@@ -1485,7 +1492,40 @@ class optional
14851492 return has_value () ? contained.value () : static_cast <value_type>( v );
14861493 }
14871494
1488- #endif // optional_CPP11_OR_GREATER
1495+ #endif // optional_HAVE( REF_QUALIFIER )
1496+
1497+ #if !optional_CONFIG_NO_EXTENSIONS
1498+ #if optional_HAVE( REF_QUALIFIER )
1499+
1500+ template < typename F >
1501+ optional_constexpr value_type value_or_eval ( F f ) const &
1502+ {
1503+ return has_value () ? contained.value () : f ();
1504+ }
1505+
1506+ template < typename F >
1507+ optional_constexpr14 value_type value_or_eval ( F f ) &&
1508+ {
1509+ if ( has_value () )
1510+ {
1511+ return std::move ( contained.value () );
1512+ }
1513+ else
1514+ {
1515+ return f ();
1516+ }
1517+ }
1518+
1519+ #else
1520+
1521+ template < typename F >
1522+ optional_constexpr value_type value_or_eval ( F f ) const
1523+ {
1524+ return has_value () ? contained.value () : f ();
1525+ }
1526+
1527+ #endif // optional_HAVE( REF_QUALIFIER )
1528+ #endif // !optional_CONFIG_NO_EXTENSIONS
14891529
14901530 // x.x.3.6, modifiers
14911531
@@ -1515,7 +1555,7 @@ class optional
15151555 void initialize ( V && value )
15161556 {
15171557 assert ( ! has_value () );
1518- contained.construct_value ( std::move ( value ) );
1558+ contained.construct_value ( std::forward<V> ( value ) );
15191559 has_value_ = true ;
15201560 }
15211561
@@ -1530,185 +1570,185 @@ class optional
15301570// Relational operators
15311571
15321572template < typename T, typename U >
1533- inline optional_constexpr bool operator ==( optional<T> const & x, optional<U> const & y )
1573+ optional_nodiscard optional_constexpr bool operator ==( optional<T> const & x, optional<U> const & y )
15341574{
15351575 return bool (x) != bool (y) ? false : !bool ( x ) ? true : *x == *y;
15361576}
15371577
15381578template < typename T, typename U >
1539- inline optional_constexpr bool operator !=( optional<T> const & x, optional<U> const & y )
1579+ optional_nodiscard optional_constexpr bool operator !=( optional<T> const & x, optional<U> const & y )
15401580{
15411581 return !(x == y);
15421582}
15431583
15441584template < typename T, typename U >
1545- inline optional_constexpr bool operator <( optional<T> const & x, optional<U> const & y )
1585+ optional_nodiscard optional_constexpr bool operator <( optional<T> const & x, optional<U> const & y )
15461586{
15471587 return (!y) ? false : (!x) ? true : *x < *y;
15481588}
15491589
15501590template < typename T, typename U >
1551- inline optional_constexpr bool operator >( optional<T> const & x, optional<U> const & y )
1591+ optional_nodiscard optional_constexpr bool operator >( optional<T> const & x, optional<U> const & y )
15521592{
15531593 return (y < x);
15541594}
15551595
15561596template < typename T, typename U >
1557- inline optional_constexpr bool operator <=( optional<T> const & x, optional<U> const & y )
1597+ optional_nodiscard optional_constexpr bool operator <=( optional<T> const & x, optional<U> const & y )
15581598{
15591599 return !(y < x);
15601600}
15611601
15621602template < typename T, typename U >
1563- inline optional_constexpr bool operator >=( optional<T> const & x, optional<U> const & y )
1603+ optional_nodiscard optional_constexpr bool operator >=( optional<T> const & x, optional<U> const & y )
15641604{
15651605 return !(x < y);
15661606}
15671607
15681608// Comparison with nullopt
15691609
15701610template < typename T >
1571- inline optional_constexpr bool operator ==( optional<T> const & x, nullopt_t /* unused*/ ) optional_noexcept
1611+ optional_nodiscard optional_constexpr bool operator ==( optional<T> const & x, nullopt_t /* unused*/ ) optional_noexcept
15721612{
15731613 return (!x);
15741614}
15751615
15761616template < typename T >
1577- inline optional_constexpr bool operator ==( nullopt_t /* unused*/ , optional<T> const & x ) optional_noexcept
1617+ optional_nodiscard optional_constexpr bool operator ==( nullopt_t /* unused*/ , optional<T> const & x ) optional_noexcept
15781618{
15791619 return (!x);
15801620}
15811621
15821622template < typename T >
1583- inline optional_constexpr bool operator !=( optional<T> const & x, nullopt_t /* unused*/ ) optional_noexcept
1623+ optional_nodiscard optional_constexpr bool operator !=( optional<T> const & x, nullopt_t /* unused*/ ) optional_noexcept
15841624{
15851625 return bool (x);
15861626}
15871627
15881628template < typename T >
1589- inline optional_constexpr bool operator !=( nullopt_t /* unused*/ , optional<T> const & x ) optional_noexcept
1629+ optional_nodiscard optional_constexpr bool operator !=( nullopt_t /* unused*/ , optional<T> const & x ) optional_noexcept
15901630{
15911631 return bool (x);
15921632}
15931633
15941634template < typename T >
1595- inline optional_constexpr bool operator <( optional<T> const & /* unused*/ , nullopt_t /* unused*/ ) optional_noexcept
1635+ optional_nodiscard optional_constexpr bool operator <( optional<T> const & /* unused*/ , nullopt_t /* unused*/ ) optional_noexcept
15961636{
15971637 return false ;
15981638}
15991639
16001640template < typename T >
1601- inline optional_constexpr bool operator <( nullopt_t /* unused*/ , optional<T> const & x ) optional_noexcept
1641+ optional_nodiscard optional_constexpr bool operator <( nullopt_t /* unused*/ , optional<T> const & x ) optional_noexcept
16021642{
16031643 return bool (x);
16041644}
16051645
16061646template < typename T >
1607- inline optional_constexpr bool operator <=( optional<T> const & x, nullopt_t /* unused*/ ) optional_noexcept
1647+ optional_nodiscard optional_constexpr bool operator <=( optional<T> const & x, nullopt_t /* unused*/ ) optional_noexcept
16081648{
16091649 return (!x);
16101650}
16111651
16121652template < typename T >
1613- inline optional_constexpr bool operator <=( nullopt_t /* unused*/ , optional<T> const & /* unused*/ ) optional_noexcept
1653+ optional_nodiscard optional_constexpr bool operator <=( nullopt_t /* unused*/ , optional<T> const & /* unused*/ ) optional_noexcept
16141654{
16151655 return true ;
16161656}
16171657
16181658template < typename T >
1619- inline optional_constexpr bool operator >( optional<T> const & x, nullopt_t /* unused*/ ) optional_noexcept
1659+ optional_nodiscard optional_constexpr bool operator >( optional<T> const & x, nullopt_t /* unused*/ ) optional_noexcept
16201660{
16211661 return bool (x);
16221662}
16231663
16241664template < typename T >
1625- inline optional_constexpr bool operator >( nullopt_t /* unused*/ , optional<T> const & /* unused*/ ) optional_noexcept
1665+ optional_nodiscard optional_constexpr bool operator >( nullopt_t /* unused*/ , optional<T> const & /* unused*/ ) optional_noexcept
16261666{
16271667 return false ;
16281668}
16291669
16301670template < typename T >
1631- inline optional_constexpr bool operator >=( optional<T> const & /* unused*/ , nullopt_t /* unused*/ ) optional_noexcept
1671+ optional_nodiscard optional_constexpr bool operator >=( optional<T> const & /* unused*/ , nullopt_t /* unused*/ ) optional_noexcept
16321672{
16331673 return true ;
16341674}
16351675
16361676template < typename T >
1637- inline optional_constexpr bool operator >=( nullopt_t /* unused*/ , optional<T> const & x ) optional_noexcept
1677+ optional_nodiscard optional_constexpr bool operator >=( nullopt_t /* unused*/ , optional<T> const & x ) optional_noexcept
16381678{
16391679 return (!x);
16401680}
16411681
16421682// Comparison with T
16431683
16441684template < typename T, typename U >
1645- inline optional_constexpr bool operator ==( optional<T> const & x, U const & v )
1685+ optional_nodiscard optional_constexpr bool operator ==( optional<T> const & x, U const & v )
16461686{
16471687 return bool (x) ? *x == v : false ;
16481688}
16491689
16501690template < typename T, typename U >
1651- inline optional_constexpr bool operator ==( U const & v, optional<T> const & x )
1691+ optional_nodiscard optional_constexpr bool operator ==( U const & v, optional<T> const & x )
16521692{
16531693 return bool (x) ? v == *x : false ;
16541694}
16551695
16561696template < typename T, typename U >
1657- inline optional_constexpr bool operator !=( optional<T> const & x, U const & v )
1697+ optional_nodiscard optional_constexpr bool operator !=( optional<T> const & x, U const & v )
16581698{
16591699 return bool (x) ? *x != v : true ;
16601700}
16611701
16621702template < typename T, typename U >
1663- inline optional_constexpr bool operator !=( U const & v, optional<T> const & x )
1703+ optional_nodiscard optional_constexpr bool operator !=( U const & v, optional<T> const & x )
16641704{
16651705 return bool (x) ? v != *x : true ;
16661706}
16671707
16681708template < typename T, typename U >
1669- inline optional_constexpr bool operator <( optional<T> const & x, U const & v )
1709+ optional_nodiscard optional_constexpr bool operator <( optional<T> const & x, U const & v )
16701710{
16711711 return bool (x) ? *x < v : true ;
16721712}
16731713
16741714template < typename T, typename U >
1675- inline optional_constexpr bool operator <( U const & v, optional<T> const & x )
1715+ optional_nodiscard optional_constexpr bool operator <( U const & v, optional<T> const & x )
16761716{
16771717 return bool (x) ? v < *x : false ;
16781718}
16791719
16801720template < typename T, typename U >
1681- inline optional_constexpr bool operator <=( optional<T> const & x, U const & v )
1721+ optional_nodiscard optional_constexpr bool operator <=( optional<T> const & x, U const & v )
16821722{
16831723 return bool (x) ? *x <= v : true ;
16841724}
16851725
16861726template < typename T, typename U >
1687- inline optional_constexpr bool operator <=( U const & v, optional<T> const & x )
1727+ optional_nodiscard optional_constexpr bool operator <=( U const & v, optional<T> const & x )
16881728{
16891729 return bool (x) ? v <= *x : false ;
16901730}
16911731
16921732template < typename T, typename U >
1693- inline optional_constexpr bool operator >( optional<T> const & x, U const & v )
1733+ optional_nodiscard optional_constexpr bool operator >( optional<T> const & x, U const & v )
16941734{
16951735 return bool (x) ? *x > v : false ;
16961736}
16971737
16981738template < typename T, typename U >
1699- inline optional_constexpr bool operator >( U const & v, optional<T> const & x )
1739+ optional_nodiscard optional_constexpr bool operator >( U const & v, optional<T> const & x )
17001740{
17011741 return bool (x) ? v > *x : true ;
17021742}
17031743
17041744template < typename T, typename U >
1705- inline optional_constexpr bool operator >=( optional<T> const & x, U const & v )
1745+ optional_nodiscard optional_constexpr bool operator >=( optional<T> const & x, U const & v )
17061746{
17071747 return bool (x) ? *x >= v : false ;
17081748}
17091749
17101750template < typename T, typename U >
1711- inline optional_constexpr bool operator >=( U const & v, optional<T> const & x )
1751+ optional_nodiscard optional_constexpr bool operator >=( U const & v, optional<T> const & x )
17121752{
17131753 return bool (x) ? v >= *x : true ;
17141754}
0 commit comments