Detect types convertible to unformattable pointers

This commit is contained in:
Victor Zverovich 2021-11-13 08:26:27 -08:00
parent 094b66e81d
commit 5380ff4d88
2 changed files with 11 additions and 2 deletions

View File

@ -1370,8 +1370,11 @@ template <typename Context> struct arg_mapper {
// We use SFINAE instead of a const T* parameter to avoid conflicting with
// the C array overload.
template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value)>
FMT_CONSTEXPR auto map(T) -> unformattable_pointer {
template <
typename T,
FMT_ENABLE_IF(std::is_convertible<const T&, const void*>::value &&
!std::is_convertible<const T&, const char_type*>::value)>
FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer {
return {};
}

View File

@ -733,6 +733,10 @@ template <> struct formatter<nonconst_formattable> {
};
FMT_END_NAMESPACE
struct convertible_to_pointer {
operator const int*() const { return nullptr; }
};
TEST(core_test, is_formattable) {
static_assert(fmt::is_formattable<signed char*>::value, "");
static_assert(fmt::is_formattable<unsigned char*>::value, "");
@ -760,6 +764,8 @@ TEST(core_test, is_formattable) {
static_assert(!fmt::is_formattable<const nonconst_formattable&>::value, "");
#endif
static_assert(!fmt::is_formattable<convertible_to_pointer>::value, "");
static_assert(!fmt::is_formattable<signed char*, wchar_t>::value, "");
static_assert(!fmt::is_formattable<unsigned char*, wchar_t>::value, "");
static_assert(!fmt::is_formattable<const signed char*, wchar_t>::value, "");