From 7013ff9aeba9240bb2145e337169b4df64f7e372 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Mon, 2 Aug 2021 16:10:56 -0400 Subject: [PATCH] Update nonstd::optional to v3.4.0 --- src/nonstd/optional.hpp | 142 ++++++++++++++++++++++++++++++---------- 1 file changed, 107 insertions(+), 35 deletions(-) diff --git a/src/nonstd/optional.hpp b/src/nonstd/optional.hpp index 133673a9..8b371e5a 100644 --- a/src/nonstd/optional.hpp +++ b/src/nonstd/optional.hpp @@ -12,7 +12,7 @@ #define NONSTD_OPTIONAL_LITE_HPP #define optional_lite_MAJOR 3 -#define optional_lite_MINOR 2 +#define optional_lite_MINOR 4 #define optional_lite_PATCH 0 #define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH) @@ -26,6 +26,20 @@ #define optional_OPTIONAL_NONSTD 1 #define optional_OPTIONAL_STD 2 +// tweak header support: + +#ifdef __has_include +# if __has_include() +# include +# endif +#define optional_HAVE_TWEAK_HEADER 1 +#else +#define optional_HAVE_TWEAK_HEADER 0 +//# pragma message("optional.hpp: Note: Tweak header not supported.") +#endif + +// optional selection and configuration: + #if !defined( optional_CONFIG_SELECT_OPTIONAL ) # define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD ) #endif @@ -33,7 +47,10 @@ // Control presence of exception handling (try and auto discover): #ifndef optional_CONFIG_NO_EXCEPTIONS -# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) +# if _MSC_VER +# include // for _HAS_EXCEPTIONS +# endif +# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) # define optional_CONFIG_NO_EXCEPTIONS 0 # else # define optional_CONFIG_NO_EXCEPTIONS 1 @@ -293,18 +310,28 @@ namespace nonstd { #define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900) #define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910) -#define optional_CPP11_140_490 ((optional_CPP11_OR_GREATER_ && optional_COMPILER_GNUC_VERSION >= 490) || (optional_COMPILER_MSVC_VER >= 1910)) - #define optional_CPP14_000 (optional_CPP14_OR_GREATER) #define optional_CPP17_000 (optional_CPP17_OR_GREATER) +// gcc >= 4.9, msvc >= vc14.1 (vs17): +#define optional_CPP11_140_G490 ((optional_CPP11_OR_GREATER_ && optional_COMPILER_GNUC_VERSION >= 490) || (optional_COMPILER_MSVC_VER >= 1910)) + +// clang >= 3.5, msvc >= vc11 (vs12): +#define optional_CPP11_110_C350 ( optional_CPP11_110 && !optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) ) + +// clang >= 3.5, gcc >= 5.0, msvc >= vc11 (vs12): +#define optional_CPP11_110_C350_G500 \ + ( optional_CPP11_110 && \ + !( optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) \ + || optional_BETWEEN( optional_COMPILER_GNUC_VERSION , 1, 500 ) ) ) + // Presence of C++11 language features: #define optional_HAVE_CONSTEXPR_11 optional_CPP11_140 #define optional_HAVE_IS_DEFAULT optional_CPP11_140 #define optional_HAVE_NOEXCEPT optional_CPP11_140 #define optional_HAVE_NULLPTR optional_CPP11_100 -#define optional_HAVE_REF_QUALIFIER optional_CPP11_140_490 +#define optional_HAVE_REF_QUALIFIER optional_CPP11_140_G490 #define optional_HAVE_INITIALIZER_LIST optional_CPP11_140 // Presence of C++14 language features: @@ -324,6 +351,13 @@ namespace nonstd { #define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION ) #define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION ) +#define optional_HAVE_IS_ASSIGNABLE optional_CPP11_110_C350 +#define optional_HAVE_IS_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350 +#define optional_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE optional_CPP11_110_C350 +#define optional_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350 +#define optional_HAVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE optional_CPP11_110_C350_G500 +#define optional_HAVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350_G500 + // C++ feature usage: #if optional_HAVE( CONSTEXPR_11 ) @@ -419,6 +453,12 @@ namespace nonstd { namespace optional_lite { namespace std11 { +template< class T, T v > struct integral_constant { enum { value = v }; }; +template< bool B > struct bool_constant : integral_constant{}; + +typedef bool_constant< true > true_type; +typedef bool_constant< false > false_type; + #if optional_CPP11_OR_GREATER using std::move; #else @@ -432,16 +472,42 @@ namespace std11 { template< typename T, typename F > struct conditional { typedef F type; }; #endif // optional_HAVE_CONDITIONAL -// gcc < 5: -#if optional_CPP11_OR_GREATER -#if optional_BETWEEN( optional_COMPILER_GNUC_VERSION, 1, 500 ) - template< typename T > struct is_trivially_copy_constructible : std::true_type{}; - template< typename T > struct is_trivially_move_constructible : std::true_type{}; +#if optional_HAVE( IS_ASSIGNABLE ) + using std::is_assignable; +#else + template< class T, class U > struct is_assignable : std11::true_type{}; +#endif + +#if optional_HAVE( IS_MOVE_CONSTRUCTIBLE ) + using std::is_move_constructible; #else + template< class T > struct is_move_constructible : std11::true_type{}; +#endif + +#if optional_HAVE( IS_NOTHROW_MOVE_ASSIGNABLE ) + using std::is_nothrow_move_assignable; +#else + template< class T > struct is_nothrow_move_assignable : std11::true_type{}; +#endif + +#if optional_HAVE( IS_NOTHROW_MOVE_CONSTRUCTIBLE ) + using std::is_nothrow_move_constructible; +#else + template< class T > struct is_nothrow_move_constructible : std11::true_type{}; +#endif + +#if optional_HAVE( IS_TRIVIALLY_COPY_CONSTRUCTIBLE ) using std::is_trivially_copy_constructible; - using std::is_trivially_move_constructible; +#else + template< class T > struct is_trivially_copy_constructible : std11::true_type{}; #endif + +#if optional_HAVE( IS_TRIVIALLY_MOVE_CONSTRUCTIBLE ) + using std::is_trivially_move_constructible; +#else + template< class T > struct is_trivially_move_constructible : std11::true_type{}; #endif + } // namespace std11 #if optional_CPP11_OR_GREATER @@ -464,10 +530,10 @@ using std::swap; struct is_swappable { template< typename T, typename = decltype( swap( std::declval(), std::declval() ) ) > - static std::true_type test( int /*unused*/ ); + static std11::true_type test( int /*unused*/ ); template< typename > - static std::false_type test(...); + static std11::false_type test(...); }; struct is_nothrow_swappable @@ -481,10 +547,10 @@ struct is_nothrow_swappable } template< typename T > - static auto test( int /*unused*/ ) -> std::integral_constant()>{} + static auto test( int /*unused*/ ) -> std11::integral_constant()>{} template< typename > - static auto test(...) -> std::false_type; + static auto test(...) -> std11::false_type; }; } // namespace detail @@ -712,6 +778,12 @@ union storage_t ::new( value_ptr() ) value_type( std::move( v ) ); } + template< class... Args > + storage_t( nonstd_lite_in_place_t(T), Args&&... args ) + { + emplace( std::forward(args)... ); + } + template< class... Args > void emplace( Args&&... args ) { @@ -891,13 +963,13 @@ public: // 3 (C++11) - move-construct from optional template< typename U = T optional_REQUIRES_T( - std::is_move_constructible::value + std11::is_move_constructible::value || std11::is_trivially_move_constructible::value ) > optional_constexpr14 optional( optional && other ) // NOLINTNEXTLINE( performance-noexcept-move-constructor ) - noexcept( std::is_nothrow_move_constructible::value ) + noexcept( std11::is_nothrow_move_constructible::value ) : has_value_( other.has_value() ) { if ( other.has_value() ) @@ -1043,7 +1115,7 @@ public: > optional_constexpr explicit optional( U && value ) : has_value_( true ) - , contained( T{ std::forward( value ) } ) + , contained( nonstd_lite_in_place(T), std::forward( value ) ) {} // 8b (C++11) - non-explicit move construct from value @@ -1058,7 +1130,7 @@ public: // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) optional_constexpr /*non-explicit*/ optional( U && value ) : has_value_( true ) - , contained( std::forward( value ) ) + , contained( nonstd_lite_in_place(T), std::forward( value ) ) {} #else // optional_CPP11_OR_GREATER @@ -1101,8 +1173,8 @@ public: ) operator=( optional const & other ) noexcept( - std::is_nothrow_move_assignable::value - && std::is_nothrow_move_constructible::value + std11::is_nothrow_move_assignable::value + && std11::is_nothrow_move_constructible::value ) #else optional & operator=( optional const & other ) @@ -1121,7 +1193,7 @@ public: optional_REQUIRES_R( optional &, true -// std::is_move_constructible::value +// std11::is_move_constructible::value // && std::is_move_assignable::value ) operator=( optional && other ) noexcept @@ -1138,7 +1210,7 @@ public: optional_REQUIRES_R( optional &, std::is_constructible::value - && std::is_assignable::value + && std11::is_assignable::value && !std::is_same::type, nonstd_lite_in_place_t(U)>::value && !std::is_same::type, optional>::value && !(std::is_scalar::value && std::is_same::type>::value) @@ -1176,7 +1248,7 @@ public: optional_REQUIRES_R( optional&, std::is_constructible< T , U const &>::value - && std::is_assignable< T&, U const &>::value + && std11::is_assignable< T&, U const &>::value && !std::is_constructible & >::value && !std::is_constructible && >::value && !std::is_constructible const & >::value @@ -1185,10 +1257,10 @@ public: && !std::is_convertible< optional && , T>::value && !std::is_convertible< optional const & , T>::value && !std::is_convertible< optional const &&, T>::value - && !std::is_assignable< T&, optional & >::value - && !std::is_assignable< T&, optional && >::value - && !std::is_assignable< T&, optional const & >::value - && !std::is_assignable< T&, optional const && >::value + && !std11::is_assignable< T&, optional & >::value + && !std11::is_assignable< T&, optional && >::value + && !std11::is_assignable< T&, optional const & >::value + && !std11::is_assignable< T&, optional const && >::value ) #else optional& @@ -1206,7 +1278,7 @@ public: optional_REQUIRES_R( optional&, std::is_constructible< T , U>::value - && std::is_assignable< T&, U>::value + && std11::is_assignable< T&, U>::value && !std::is_constructible & >::value && !std::is_constructible && >::value && !std::is_constructible const & >::value @@ -1215,10 +1287,10 @@ public: && !std::is_convertible< optional && , T>::value && !std::is_convertible< optional const & , T>::value && !std::is_convertible< optional const &&, T>::value - && !std::is_assignable< T&, optional & >::value - && !std::is_assignable< T&, optional && >::value - && !std::is_assignable< T&, optional const & >::value - && !std::is_assignable< T&, optional const && >::value + && !std11::is_assignable< T&, optional & >::value + && !std11::is_assignable< T&, optional && >::value + && !std11::is_assignable< T&, optional const & >::value + && !std11::is_assignable< T&, optional const && >::value ) operator=( optional && other ) { @@ -1260,7 +1332,7 @@ public: void swap( optional & other ) #if optional_CPP11_OR_GREATER noexcept( - std::is_nothrow_move_constructible::value + std11::is_nothrow_move_constructible::value && std17::is_nothrow_swappable::value ) #endif @@ -1626,7 +1698,7 @@ inline optional_constexpr bool operator>=( U const & v, optional const & x ) template< typename T #if optional_CPP11_OR_GREATER optional_REQUIRES_T( - std::is_move_constructible::value + std11::is_move_constructible::value && std17::is_swappable::value ) #endif >