Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<type_traits>: Make is_nothrow_convertible a class template and ADL-proof #4318

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions stl/inc/type_traits
Original file line number Diff line number Diff line change
Expand Up @@ -1764,7 +1764,7 @@ constexpr auto invoke(_Callable&& _Obj, _Ty1&& _Arg1, _Types2&&... _Args2) noexc
#pragma warning(disable : 4365) // '%s': conversion from '%s' to '%s', signed/unsigned mismatch (/Wall)

template <class _From, class _To, bool = is_convertible_v<_From, _To>, bool = is_void_v<_To>>
_INLINE_VAR constexpr bool _Is_nothrow_convertible_v = noexcept(_Fake_copy_init<_To>(_STD declval<_From>()));
_INLINE_VAR constexpr bool _Is_nothrow_convertible_v = noexcept(_STD _Fake_copy_init<_To>(_STD declval<_From>()));

#pragma warning(pop)

Expand All @@ -1784,7 +1784,7 @@ _EXPORT_STD template <class _From, class _To>
inline constexpr bool is_nothrow_convertible_v = _Is_nothrow_convertible_v<_From, _To>;

_EXPORT_STD template <class _From, class _To>
using is_nothrow_convertible = _Is_nothrow_convertible<_From, _To>;
struct is_nothrow_convertible : bool_constant<_Is_nothrow_convertible_v<_From, _To>> {};
#endif // _HAS_CXX20

template <class _From, class _To, class = void>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,32 @@ STATIC_ASSERT(is_nothrow_convertible_v<int[1], int*>);
STATIC_ASSERT(!is_nothrow_convertible_v<int[], int[]>);
STATIC_ASSERT(!is_nothrow_convertible_v<int[], int[1]>);

// Also test GH-4317 <type_traits>: some traits are an aliases and fail when used with parameter pack
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved

template <class... Ts>
using aliased_is_nothrow_convertible = is_nothrow_convertible<Ts...>;

template <class T, template <class...> class Tmpl>
constexpr bool is_specialization_of_v = false;
template <class... Ts, template <class...> class Tmpl>
constexpr bool is_specialization_of_v<Tmpl<Ts...>, Tmpl> = true;

STATIC_ASSERT(is_specialization_of_v<is_nothrow_convertible<void, void>, is_nothrow_convertible>);
STATIC_ASSERT(!is_specialization_of_v<aliased_is_nothrow_convertible<void, void>, aliased_is_nothrow_convertible>);

#ifndef _M_CEE // TRANSITION, VSO-1659496
// Also test that is_nothrow_convertible/is_nothrow_convertible_v are ADL-proof

template <class T>
struct holder {
T t;
};

struct incomplete;

STATIC_ASSERT(is_nothrow_convertible<holder<incomplete>*, holder<incomplete>*>::value);
STATIC_ASSERT(is_nothrow_convertible_v<holder<incomplete>*, holder<incomplete>*>);
#endif // _M_CEE

// VSO_0105317_expression_sfinae and VSO_0000000_type_traits provide
// additional coverage of this machinery