Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Range formatter #2983

Merged
merged 10 commits into from
Jul 29, 2022
17 changes: 16 additions & 1 deletion include/fmt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1652,6 +1652,11 @@ auto copy_str(InputIt begin, InputIt end, appender out) -> appender {
return out;
}

template <typename Char, typename R, typename OutputIt>
FMT_CONSTEXPR auto copy_str_range(R&& rng, OutputIt out) -> OutputIt {
brevzin marked this conversation as resolved.
Show resolved Hide resolved
return detail::copy_str<Char>(rng.begin(), rng.end(), out);
}

#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
// A workaround for gcc 4.8 to make void_t work in a SFINAE context.
template <typename... Ts> struct void_t_impl { using type = void; };
Expand Down Expand Up @@ -2806,7 +2811,8 @@ FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs<Char>& specs,
template <typename ErrorHandler = error_handler>
FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type,
ErrorHandler&& eh = {}) -> bool {
if (type == presentation_type::none || type == presentation_type::string)
if (type == presentation_type::none || type == presentation_type::string ||
type == presentation_type::debug)
return true;
if (type != presentation_type::pointer) eh.on_error("invalid type specifier");
return false;
Expand Down Expand Up @@ -3068,6 +3074,15 @@ struct formatter<T, Char,
return it;
}

template <detail::type U = detail::type_constant<T, Char>::value,
enable_if_t<(U == detail::type::string_type ||
U == detail::type::cstring_type ||
U == detail::type::char_type),
int> = 0>
FMT_CONSTEXPR void set_debug_format() {
specs_.type = presentation_type::debug;
}

template <typename FormatContext>
FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
-> decltype(ctx.out());
Expand Down
14 changes: 11 additions & 3 deletions include/fmt/ostream.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,22 @@ template <typename T> struct streamed_view { const T& value; };

// Formats an object of type T that has an overloaded ostream operator<<.
template <typename Char>
struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
struct basic_ostream_formatter {
private:
formatter<basic_string_view<Char>, Char> underlying_;

brevzin marked this conversation as resolved.
Show resolved Hide resolved
public:
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
return underlying_.parse(ctx);
}

template <typename T, typename OutputIt>
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx) const
-> OutputIt {
auto buffer = basic_memory_buffer<Char>();
format_value(buffer, value, ctx.locale());
return formatter<basic_string_view<Char>, Char>::format(
{buffer.data(), buffer.size()}, ctx);
return underlying_.format({buffer.data(), buffer.size()}, ctx);
brevzin marked this conversation as resolved.
Show resolved Hide resolved
}
};

Expand Down
Loading