Skip to content

Commit

Permalink
Change requires to use a default template argument (#55, thanks to @i…
Browse files Browse the repository at this point in the history
…mprobablejan)

Fixes implementation of optional_REQUIRES_T(), see martinmoene/nonstd-lite-project#40
  • Loading branch information
martinmoene committed Mar 5, 2020
1 parent 357e69f commit ca3402c
Showing 1 changed file with 50 additions and 37 deletions.
87 changes: 50 additions & 37 deletions include/nonstd/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ namespace nonstd {
template< bool B = (__VA_ARGS__), typename std::enable_if<B, int>::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
Expand Down Expand Up @@ -432,6 +432,13 @@ namespace std11 {
template< typename T, typename F > struct conditional<false, T, F> { typedef F type; };
#endif // optional_HAVE_CONDITIONAL

#if optional_CPP11_OR_GREATER
template< typename T >
struct is_trivially_move_constructible
{
enum { value = std::is_trivially_constructible<T, T&&>::value };
};
#endif
} // namespace std11

#if optional_CPP11_OR_GREATER
Expand Down Expand Up @@ -865,13 +872,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<T>::value
)
// template< typename U = T
// optional_REQUIRES_T(
// std::is_copy_constructible<U>::value
// || std::is_trivially_copy_constructible<U>::value
// )
// >
#endif
)
optional_constexpr14 optional( optional const & other )
: has_value_( other.has_value() )
{
if ( other.has_value() )
Expand All @@ -883,12 +892,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<T>::value
template< typename U = T
optional_REQUIRES_T(
std::is_move_constructible<U>::value
|| std11::is_trivially_move_constructible<U>::value
)
// NOLINTNEXTLINE( performance-noexcept-move-constructor )
) noexcept( std::is_nothrow_move_constructible<T>::value )
>
optional_constexpr14 optional( optional && other )
// NOLINTNEXTLINE( performance-noexcept-move-constructor )
noexcept( std::is_nothrow_move_constructible<T>::value )
: has_value_( other.has_value() )
{
if ( other.has_value() )
Expand All @@ -898,9 +910,8 @@ class optional
}

// 4a (C++11) - explicit converting copy-construct from optional
template< typename U >
explicit optional( optional<U> const & other
optional_REQUIRES_A(
template< typename U
optional_REQUIRES_T(
std::is_constructible<T, U const &>::value
&& !std::is_constructible<T, optional<U> & >::value
&& !std::is_constructible<T, optional<U> && >::value
Expand All @@ -912,7 +923,8 @@ class optional
&& !std::is_convertible< optional<U> const &&, T>::value
&& !std::is_convertible< U const & , T>::value /*=> explicit */
)
)
>
explicit optional( optional<U> const & other )
: has_value_( other.has_value() )
{
if ( other.has_value() )
Expand All @@ -923,11 +935,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<U> const & other
template< typename U
#if optional_CPP11_OR_GREATER
optional_REQUIRES_A(
optional_REQUIRES_T(
std::is_constructible<T, U const &>::value
&& !std::is_constructible<T, optional<U> & >::value
&& !std::is_constructible<T, optional<U> && >::value
Expand All @@ -940,7 +950,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<U> const & other )
: has_value_( other.has_value() )
{
if ( other.has_value() )
Expand All @@ -952,9 +964,8 @@ class optional
#if optional_CPP11_OR_GREATER

// 5a (C++11) - explicit converting move-construct from optional
template< typename U >
explicit optional( optional<U> && other
optional_REQUIRES_A(
template< typename U
optional_REQUIRES_T(
std::is_constructible<T, U &&>::value
&& !std::is_constructible<T, optional<U> & >::value
&& !std::is_constructible<T, optional<U> && >::value
Expand All @@ -966,6 +977,8 @@ class optional
&& !std::is_convertible< optional<U> const &&, T>::value
&& !std::is_convertible< U &&, T>::value /*=> explicit */
)
>
explicit optional( optional<U> && other
)
: has_value_( other.has_value() )
{
Expand All @@ -976,10 +989,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<U> && other
optional_REQUIRES_A(
template< typename U
optional_REQUIRES_T(
std::is_constructible<T, U &&>::value
&& !std::is_constructible<T, optional<U> & >::value
&& !std::is_constructible<T, optional<U> && >::value
Expand All @@ -991,7 +1002,9 @@ class optional
&& !std::is_convertible< optional<U> const &&, T>::value
&& std::is_convertible< U &&, T>::value /*=> non-explicit */
)
)
>
// NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
/*non-explicit*/ optional( optional<U> && other )
: has_value_( other.has_value() )
{
if ( other.has_value() )
Expand Down Expand Up @@ -1023,30 +1036,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<T, U&&>::value
&& !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
&& !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
&& !std::is_convertible<U&&, T>::value /*=> explicit */
)
)
>
optional_constexpr explicit optional( U && value )
: has_value_( true )
, contained( T{ std::forward<U>( 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<T, U&&>::value
&& !std::is_same<typename std20::remove_cvref<U>::type, nonstd_lite_in_place_t(U)>::value
&& !std::is_same<typename std20::remove_cvref<U>::type, optional<T>>::value
&& std::is_convertible<U&&, T>::value /*=> non-explicit */
)
)
>
// NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions )
optional_constexpr /*non-explicit*/ optional( U && value )
: has_value_( true )
, contained( std::forward<U>( value ) )
{}
Expand Down

0 comments on commit ca3402c

Please sign in to comment.