Skip to content

Commit

Permalink
🛠 Use universal references to SFINAE properly
Browse files Browse the repository at this point in the history
  • Loading branch information
ThePhD committed Jan 14, 2024
1 parent 036b35a commit c24a8cd
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 33 deletions.
17 changes: 11 additions & 6 deletions include/fmt/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -2804,7 +2804,9 @@ struct format_to_result {
/** Ensures old code relying on array-style output continues to work. */
FMT_CONSTEXPR operator OutputIt&() & noexcept { return out; }
/** Ensures old code relying on array-style output continues to work. */
FMT_CONSTEXPR operator OutputIt&&() && noexcept { return static_cast<OutputIt&&>(out); }
FMT_CONSTEXPR operator OutputIt&&() && noexcept {
return static_cast<OutputIt&&>(out);
}
/** Ensures old code relying on array-style output continues to work. */
FMT_CONSTEXPR operator const OutputIt&() const& noexcept { return out; }
};
Expand All @@ -2831,8 +2833,10 @@ inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }

/** Formats a string and writes the output to ``out``. */
template <typename OutputIt,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt {
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
char>::value)>
auto vformat_to(OutputIt&& out, string_view fmt, format_args args)
-> remove_cvref_t<OutputIt> {
auto&& buf = detail::get_buffer<char>(out);
detail::vformat_to(buf, fmt, args, {});
return detail::get_iterator(buf, out);
Expand Down Expand Up @@ -2861,9 +2865,10 @@ auto vformat_to(char (&out)[Size], string_view fmt, format_args args)
\endrst
*/
template <typename OutputIt, typename... T,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
FMT_INLINE auto format_to(OutputIt out, format_string<T...> fmt, T&&... args)
-> OutputIt {
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
char>::value)>
FMT_INLINE auto format_to(OutputIt&& out, format_string<T...> fmt, T&&... args)
-> remove_cvref_t<OutputIt> {
return vformat_to(out, fmt, fmt::make_format_args(args...));
}

Expand Down
15 changes: 9 additions & 6 deletions include/fmt/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,10 @@ inline auto format(const text_style& ts, format_string<T...> fmt, T&&... args)
Formats a string with the given text_style and writes the output to ``out``.
*/
template <typename OutputIt,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
auto vformat_to(OutputIt out, const text_style& ts, string_view fmt,
format_args args) -> OutputIt {
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
char>::value)>
auto vformat_to(OutputIt&& out, const text_style& ts, string_view fmt,
format_args args) -> remove_cvref_t<OutputIt> {
auto&& buf = detail::get_buffer<char>(out);
detail::vformat_to(buf, ts, fmt, args);
return detail::get_iterator(buf, out);
Expand Down Expand Up @@ -576,9 +577,11 @@ auto vformat_to(char (&out)[Size], const text_style& ts, string_view fmt,
\endrst
*/
template <typename OutputIt, typename... T,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
inline auto format_to(OutputIt out, const text_style& ts,
format_string<T...> fmt, T&&... args) -> OutputIt {
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
char>::value)>
inline auto format_to(OutputIt&& out, const text_style& ts,
format_string<T...> fmt, T&&... args)
-> remove_cvref_t<OutputIt> {
return vformat_to(out, ts, fmt, fmt::make_format_args(args...));
}

Expand Down
15 changes: 9 additions & 6 deletions include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -4415,10 +4415,11 @@ inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
}

template <typename OutputIt, typename Locale,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
char>::value&&
detail::is_locale<Locale>::value)>
auto vformat_to(OutputIt out, const Locale& loc, string_view fmt,
format_args args) -> OutputIt {
auto vformat_to(OutputIt&& out, const Locale& loc, string_view fmt,
format_args args) -> remove_cvref_t<OutputIt> {
using detail::get_buffer;
auto&& buf = get_buffer<char>(out);
detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
Expand All @@ -4436,10 +4437,12 @@ auto vformat_to(char (&out)[Size], const Locale& loc, string_view fmt,
}

template <typename OutputIt, typename Locale, typename... T,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
char>::value&&
detail::is_locale<Locale>::value)>
FMT_INLINE auto format_to(OutputIt out, const Locale& loc,
format_string<T...> fmt, T&&... args) -> OutputIt {
FMT_INLINE auto format_to(OutputIt&& out, const Locale& loc,
format_string<T...> fmt, T&&... args)
-> remove_cvref_t<OutputIt> {
return vformat_to(out, loc, fmt, fmt::make_format_args(args...));
}

Expand Down
36 changes: 21 additions & 15 deletions include/fmt/xchar.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,12 @@ inline auto format(const Locale& loc, const S& format_str, T&&... args)

template <typename OutputIt, typename S,
typename Char = detail::format_string_char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
Char>::value&&
detail::is_exotic_char<Char>::value)>
auto vformat_to(OutputIt out, const S& format_str,
typename detail::vformat_args<Char>::type args) -> OutputIt {
auto vformat_to(OutputIt&& out, const S& format_str,
typename detail::vformat_args<Char>::type args)
-> remove_cvref_t<OutputIt> {
auto&& buf = detail::get_buffer<Char>(out);
detail::vformat_to(buf, detail::to_string_view(format_str), args);
return detail::get_iterator(buf, out);
Expand All @@ -197,9 +199,11 @@ auto vformat_to(Char (&out)[Size], const S& format_str,

template <typename OutputIt, typename S, typename... T,
typename Char = detail::format_string_char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
Char>::value&&
detail::is_exotic_char<Char>::value)>
inline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {
inline auto format_to(OutputIt&& out, const S& fmt, T&&... args)
-> remove_cvref_t<OutputIt> {
return vformat_to(out, detail::to_string_view(fmt),
fmt::make_format_args<buffered_context<Char>>(args...));
}
Expand All @@ -215,12 +219,13 @@ inline auto format_to(Char (&out)[Size], const S& fmt, T&&... args)

template <typename Locale, typename S, typename OutputIt, typename... Args,
typename Char = detail::format_string_char_t<S>,
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&
FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
Char>::value&&
detail::is_locale<Locale>::value&&
detail::is_exotic_char<Char>::value)>
inline auto vformat_to(OutputIt out, const Locale& loc, const S& format_str,
inline auto vformat_to(OutputIt&& out, const Locale& loc, const S& format_str,
typename detail::vformat_args<Char>::type args)
-> OutputIt {
-> remove_cvref_t<OutputIt> {
auto&& buf = detail::get_buffer<Char>(out);
vformat_to(buf, detail::to_string_view(format_str), args,
detail::locale_ref(loc));
Expand All @@ -242,14 +247,15 @@ inline auto vformat_to(Char (&out)[Size], const Locale& loc,
return {out + buf.count(), out + Size};
}

template <typename OutputIt, typename Locale, typename S, typename... T,
typename Char = detail::format_string_char_t<S>,
bool enable = detail::is_output_iterator<OutputIt, Char>::value &&
detail::is_locale<Locale>::value &&
detail::is_exotic_char<Char>::value>
inline auto format_to(OutputIt out, const Locale& loc, const S& format_str,
template <
typename OutputIt, typename Locale, typename S, typename... T,
typename Char = detail::format_string_char_t<S>,
bool enable =
detail::is_output_iterator<remove_cvref_t<OutputIt>, Char>::value &&
detail::is_locale<Locale>::value && detail::is_exotic_char<Char>::value>
inline auto format_to(OutputIt&& out, const Locale& loc, const S& format_str,
T&&... args) ->
typename std::enable_if<enable, OutputIt>::type {
typename std::enable_if<enable, remove_cvref_t<OutputIt>>::type {
return vformat_to(out, loc, detail::to_string_view(format_str),
fmt::make_format_args<buffered_context<Char>>(args...));
}
Expand Down

0 comments on commit c24a8cd

Please sign in to comment.