diff --git a/include/fmt/core.h b/include/fmt/core.h index 45fd87ee..cd716880 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -103,7 +103,7 @@ #endif // Check if C++20 concepts is supported. -#if ((__cplusplus >= 202002L) && defined(__cpp_lib_concepts)) +#if ((__cplusplus >= 202002L) && defined(__cpp_lib_concepts) && !FMT_MSC_VER) # define FMT_HAS_CPP20_CONCEPTS 1 #else # define FMT_HAS_CPP20_CONCEPTS 0 diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index a571c37a..6118f2c5 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -51,11 +51,21 @@ template struct formatting_tuple { namespace detail { +// These are needed traits to allow correct resolution of the +// copy(...) function overloading for char[] and wchar_t[] +template using decay_t = typename std::decay::type; +template +using remove_pointer_t = typename std::remove_pointer::type; + +template struct is_char_like : std::false_type {}; +// Here we only add check for wchar_t, which is inline with the +// copy(...) overload below for char and wchar_t type. +template <> struct is_char_like : std::true_type {}; +template <> struct is_char_like : std::true_type {}; + template >>>, - char>)> + FMT_ENABLE_IF(!is_char_like>>>::value)> OutputIterator copy(const RangeT& range, OutputIterator out) { for (auto it = range.begin(), end = range.end(); it != end; ++it) *out++ = *it; @@ -63,7 +73,7 @@ OutputIterator copy(const RangeT& range, OutputIterator out) { } template )> + FMT_ENABLE_IF(is_char_like::value)> OutputIterator copy(const CharT* str, OutputIterator out) { while (*str) *out++ = *str++; return out;