Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 aliases and fail when used with parameter packs

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