@@ -1162,6 +1162,20 @@ using appender = basic_appender<char>;
1162
1162
1163
1163
namespace detail {
1164
1164
1165
+ template <typename T, typename Enable = void >
1166
+ struct locking : std::true_type {};
1167
+ template <typename T>
1168
+ struct locking <T, void_t <typename formatter<remove_cvref_t <T>>::nonlocking>>
1169
+ : std::false_type {};
1170
+
1171
+ template <typename T = int > FMT_CONSTEXPR inline auto is_locking () -> bool {
1172
+ return locking<T>::value;
1173
+ }
1174
+ template <typename T1, typename T2, typename ... Tail>
1175
+ FMT_CONSTEXPR inline auto is_locking () -> bool {
1176
+ return locking<T1>::value || is_locking<T2, Tail...>();
1177
+ }
1178
+
1165
1179
// An optimized version of std::copy with the output value type (T).
1166
1180
template <typename T, typename InputIt>
1167
1181
auto copy (InputIt begin, InputIt end, appender out) -> appender {
@@ -2796,6 +2810,8 @@ struct formatter<T, Char,
2796
2810
detail::dynamic_format_specs<Char> specs_;
2797
2811
2798
2812
public:
2813
+ using nonlocking = void ;
2814
+
2799
2815
template <typename ParseContext>
2800
2816
FMT_CONSTEXPR auto parse (ParseContext& ctx) -> const Char* {
2801
2817
if (ctx.begin () == ctx.end () || *ctx.begin () == ' }' ) return ctx.begin ();
@@ -2978,6 +2994,7 @@ FMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt,
2978
2994
2979
2995
FMT_API void vprint (string_view fmt, format_args args);
2980
2996
FMT_API void vprint (FILE* f, string_view fmt, format_args args);
2997
+ FMT_API void vprint_locked (FILE* f, string_view fmt, format_args args);
2981
2998
FMT_API void vprintln (FILE* f, string_view fmt, format_args args);
2982
2999
2983
3000
/* *
@@ -2993,8 +3010,9 @@ FMT_API void vprintln(FILE* f, string_view fmt, format_args args);
2993
3010
template <typename ... T>
2994
3011
FMT_INLINE void print (format_string<T...> fmt, T&&... args) {
2995
3012
const auto & vargs = fmt::make_format_args (args...);
2996
- return detail::is_utf8 () ? vprint (fmt, vargs)
2997
- : detail::vprint_mojibake (stdout, fmt, vargs);
3013
+ if (!detail::is_utf8 ()) return detail::vprint_mojibake (stdout, fmt, vargs);
3014
+ return detail::is_locking<T...>() ? vprint (fmt, vargs)
3015
+ : vprint_locked (stdout, fmt, vargs);
2998
3016
}
2999
3017
3000
3018
/* *
@@ -3010,8 +3028,9 @@ FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
3010
3028
template <typename ... T>
3011
3029
FMT_INLINE void print (FILE* f, format_string<T...> fmt, T&&... args) {
3012
3030
const auto & vargs = fmt::make_format_args (args...);
3013
- return detail::is_utf8 () ? vprint (f, fmt, vargs)
3014
- : detail::vprint_mojibake (f, fmt, vargs);
3031
+ if (!detail::is_utf8 ()) return detail::vprint_mojibake (f, fmt, vargs);
3032
+ return detail::is_locking<T...>() ? vprint (f, fmt, vargs)
3033
+ : vprint_locked (f, fmt, vargs);
3015
3034
}
3016
3035
3017
3036
/* *
0 commit comments