diff --git a/include/nonstd/optional.hpp b/include/nonstd/optional.hpp index 915cd59..d407c33 100644 --- a/include/nonstd/optional.hpp +++ b/include/nonstd/optional.hpp @@ -401,7 +401,7 @@ namespace nonstd { template< bool B = (__VA_ARGS__), typename std::enable_if::type = 0 > #define optional_REQUIRES_T(...) \ - , typename = typename std::enable_if< (__VA_ARGS__), nonstd::optional_lite::detail::enabler >::type + , typename std::enable_if< (__VA_ARGS__), int >::type = 0 #define optional_REQUIRES_R(R, ...) \ typename std::enable_if< (__VA_ARGS__), R>::type @@ -432,6 +432,10 @@ namespace std11 { template< typename T, typename F > struct conditional { typedef F type; }; #endif // optional_HAVE_CONDITIONAL +#if optional_CPP11_OR_GREATER + template< class T > + struct is_trivially_move_constructible : std::is_trivially_constructible {}; +#endif } // namespace std11 #if optional_CPP11_OR_GREATER @@ -865,13 +869,15 @@ class optional {} // 2 - copy-construct - optional_constexpr14 optional( optional const & other #if optional_CPP11_OR_GREATER - optional_REQUIRES_A( - true || std::is_copy_constructible::value - ) + // template< typename U = T + // optional_REQUIRES_T( + // std::is_copy_constructible::value + // || std::is_trivially_copy_constructible::value + // ) + // > #endif - ) + optional_constexpr14 optional( optional const & other ) : has_value_( other.has_value() ) { if ( other.has_value() ) @@ -883,12 +889,15 @@ class optional #if optional_CPP11_OR_GREATER // 3 (C++11) - move-construct from optional - optional_constexpr14 optional( optional && other - optional_REQUIRES_A( - true || std::is_move_constructible::value + template< typename U = T + optional_REQUIRES_T( + std::is_move_constructible::value + || std11::is_trivially_move_constructible::value ) - // NOLINTNEXTLINE( performance-noexcept-move-constructor ) - ) noexcept( std::is_nothrow_move_constructible::value ) + > + optional_constexpr14 optional( optional && other ) + // NOLINTNEXTLINE( performance-noexcept-move-constructor ) + noexcept( std::is_nothrow_move_constructible::value ) : has_value_( other.has_value() ) { if ( other.has_value() ) @@ -898,9 +907,8 @@ class optional } // 4a (C++11) - explicit converting copy-construct from optional - template< typename U > - explicit optional( optional const & other - optional_REQUIRES_A( + template< typename U + optional_REQUIRES_T( std::is_constructible::value && !std::is_constructible & >::value && !std::is_constructible && >::value @@ -912,7 +920,8 @@ class optional && !std::is_convertible< optional const &&, T>::value && !std::is_convertible< U const & , T>::value /*=> explicit */ ) - ) + > + explicit optional( optional const & other ) : has_value_( other.has_value() ) { if ( other.has_value() ) @@ -923,11 +932,9 @@ class optional #endif // optional_CPP11_OR_GREATER // 4b (C++98 and later) - non-explicit converting copy-construct from optional - template< typename U > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - optional( optional const & other + template< typename U #if optional_CPP11_OR_GREATER - optional_REQUIRES_A( + optional_REQUIRES_T( std::is_constructible::value && !std::is_constructible & >::value && !std::is_constructible && >::value @@ -940,7 +947,9 @@ class optional && std::is_convertible< U const & , T>::value /*=> non-explicit */ ) #endif // optional_CPP11_OR_GREATER - ) + > + // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) + /*non-explicit*/ optional( optional const & other ) : has_value_( other.has_value() ) { if ( other.has_value() ) @@ -952,9 +961,8 @@ class optional #if optional_CPP11_OR_GREATER // 5a (C++11) - explicit converting move-construct from optional - template< typename U > - explicit optional( optional && other - optional_REQUIRES_A( + template< typename U + optional_REQUIRES_T( std::is_constructible::value && !std::is_constructible & >::value && !std::is_constructible && >::value @@ -966,6 +974,8 @@ class optional && !std::is_convertible< optional const &&, T>::value && !std::is_convertible< U &&, T>::value /*=> explicit */ ) + > + explicit optional( optional && other ) : has_value_( other.has_value() ) { @@ -976,10 +986,8 @@ class optional } // 5a (C++11) - non-explicit converting move-construct from optional - template< typename U > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - optional( optional && other - optional_REQUIRES_A( + template< typename U + optional_REQUIRES_T( std::is_constructible::value && !std::is_constructible & >::value && !std::is_constructible && >::value @@ -991,7 +999,9 @@ class optional && !std::is_convertible< optional const &&, T>::value && std::is_convertible< U &&, T>::value /*=> non-explicit */ ) - ) + > + // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) + /*non-explicit*/ optional( optional && other ) : has_value_( other.has_value() ) { if ( other.has_value() ) @@ -1023,30 +1033,30 @@ class optional {} // 8a (C++11) - explicit move construct from value - template< typename U = value_type > - optional_constexpr explicit optional( U && value - optional_REQUIRES_A( + template< typename U = T + optional_REQUIRES_T( std::is_constructible::value && !std::is_same::type, nonstd_lite_in_place_t(U)>::value && !std::is_same::type, optional>::value && !std::is_convertible::value /*=> explicit */ ) - ) + > + optional_constexpr explicit optional( U && value ) : has_value_( true ) , contained( T{ std::forward( value ) } ) {} // 8b (C++11) - non-explicit move construct from value - template< typename U = value_type > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - optional_constexpr optional( U && value - optional_REQUIRES_A( + template< typename U = T + optional_REQUIRES_T( std::is_constructible::value && !std::is_same::type, nonstd_lite_in_place_t(U)>::value && !std::is_same::type, optional>::value && std::is_convertible::value /*=> non-explicit */ ) - ) + > + // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) + optional_constexpr /*non-explicit*/ optional( U && value ) : has_value_( true ) , contained( std::forward( value ) ) {}