Skip to content

Commit 4ccada9

Browse files
committed
fmtlib#2954: Use conjunction and disjunction substitute to make formatter specializations for ranges and maps more robust (especially for Visual Studio compiler family)
1 parent e92c7c1 commit 4ccada9

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

include/fmt/ranges.h

+25-16
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ template <class Tuple, class F> void for_each(Tuple&& tup, F&& f) {
246246
for_each(indexes, std::forward<Tuple>(tup), std::forward<F>(f));
247247
}
248248

249-
#if FMT_MSC_VERSION
249+
#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920
250250
// Older MSVC doesn't get the reference type correctly for arrays.
251251
template <typename R> struct range_reference_type_impl {
252252
using type = decltype(*detail::range_begin(std::declval<R&>()));
@@ -396,15 +396,18 @@ template <typename R, typename Char>
396396
struct formatter<
397397
R, Char,
398398
enable_if_t<
399-
fmt::is_range<R, Char>::value
400-
// Workaround a bug in MSVC 2019 and earlier.
401-
#if !FMT_MSC_VERSION
402-
&&
403-
(is_formattable<detail::uncvref_type<detail::maybe_const_range<R>>,
404-
Char>::value ||
405-
detail::has_fallback_formatter<
406-
detail::uncvref_type<detail::maybe_const_range<R>>, Char>::value)
399+
conjunction<fmt::is_range<R, Char>
400+
// Workaround a bug in MSVC 2017 and earlier.
401+
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1920
402+
,
403+
disjunction<
404+
is_formattable<detail::uncvref_type<detail::maybe_const_range<R>>,
405+
Char>,
406+
detail::has_fallback_formatter<
407+
detail::uncvref_type<detail::maybe_const_range<R>>, Char>
408+
>
407409
#endif
410+
>::value
408411
>> {
409412

410413
using range_type = detail::maybe_const_range<R>;
@@ -457,14 +460,20 @@ struct formatter<
457460
template <typename T, typename Char>
458461
struct formatter<
459462
T, Char,
460-
enable_if_t<detail::is_map<T>::value
461-
// Workaround a bug in MSVC 2019 and earlier.
462-
#if !FMT_MSC_VERSION
463-
&& (is_formattable<detail::uncvref_first_type<T>, Char>::value ||
464-
detail::has_fallback_formatter<detail::uncvref_first_type<T>, Char>::value)
465-
&& (is_formattable<detail::uncvref_second_type<T>, Char>::value ||
466-
detail::has_fallback_formatter<detail::uncvref_second_type<T>, Char>::value)
463+
enable_if_t<conjunction<detail::is_map<T>
464+
// Workaround a bug in MSVC 2017 and earlier.
465+
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1920
466+
,
467+
disjunction<
468+
is_formattable<detail::uncvref_first_type<T>, Char>,
469+
detail::has_fallback_formatter<detail::uncvref_first_type<T>, Char>
470+
>,
471+
disjunction<
472+
is_formattable<detail::uncvref_second_type<T>, Char>,
473+
detail::has_fallback_formatter<detail::uncvref_second_type<T>, Char>
474+
>
467475
#endif
476+
>::value
468477
>> {
469478
template <typename ParseContext>
470479
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {

0 commit comments

Comments
 (0)