Improve path formatter

This commit is contained in:
Victor Zverovich 2023-07-20 15:25:35 -07:00
parent 77e0b0e228
commit b2728a3170
3 changed files with 65 additions and 52 deletions

View File

@ -532,49 +532,6 @@ inline std::tm gmtime(
namespace detail {
// DEPRECATED!
template <typename Char>
FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
format_specs<Char>& specs) -> const Char* {
FMT_ASSERT(begin != end, "");
auto align = align::none;
auto p = begin + code_point_length(begin);
if (end - p <= 0) p = begin;
for (;;) {
switch (to_ascii(*p)) {
case '<':
align = align::left;
break;
case '>':
align = align::right;
break;
case '^':
align = align::center;
break;
}
if (align != align::none) {
if (p != begin) {
auto c = *begin;
if (c == '}') return begin;
if (c == '{') {
throw_format_error("invalid fill character '{'");
return begin;
}
specs.fill = {begin, to_unsigned(p - begin)};
begin = p + 1;
} else {
++begin;
}
break;
} else if (p == begin) {
break;
}
p = begin;
}
specs.align = align;
return begin;
}
// Writes two-digit numbers a, b and c separated by sep to buf.
// The method by Pavel Novikov based on
// https://johnnylee-sde.github.io/Fast-unsigned-integer-to-time-string/.

View File

@ -2380,6 +2380,49 @@ FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
return base_iterator(out, it);
}
// DEPRECATED!
template <typename Char>
FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
format_specs<Char>& specs) -> const Char* {
FMT_ASSERT(begin != end, "");
auto align = align::none;
auto p = begin + code_point_length(begin);
if (end - p <= 0) p = begin;
for (;;) {
switch (to_ascii(*p)) {
case '<':
align = align::left;
break;
case '>':
align = align::right;
break;
case '^':
align = align::center;
break;
}
if (align != align::none) {
if (p != begin) {
auto c = *begin;
if (c == '}') return begin;
if (c == '{') {
throw_format_error("invalid fill character '{'");
return begin;
}
specs.fill = {begin, to_unsigned(p - begin)};
begin = p + 1;
} else {
++begin;
}
break;
} else if (p == begin) {
break;
}
p = begin;
}
specs.align = align;
return begin;
}
// A floating-point presentation format.
enum class float_format : unsigned char {
general, // General: exponent notation or fixed point based on magnitude.

View File

@ -89,20 +89,33 @@ inline void write_escaped_path<std::filesystem::path::value_type>(
FMT_EXPORT
template <typename Char>
struct formatter<std::filesystem::path, Char>
: formatter<basic_string_view<Char>, Char> {
struct formatter<std::filesystem::path, Char> {
private:
format_specs<Char> specs_;
detail::arg_ref<Char> width_ref_;
public:
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
auto out = formatter<basic_string_view<Char>, Char>::parse(ctx);
this->set_debug_format(false);
return out;
auto it = ctx.begin(), end = ctx.end();
if (it == end) return it;
it = detail::parse_align(it, end, specs_);
if (it == end) return it;
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
if (it != end && *it == '?') ++it;
return it;
}
template <typename FormatContext>
auto format(const std::filesystem::path& p, FormatContext& ctx) const ->
typename FormatContext::iterator {
auto format(const std::filesystem::path& p, FormatContext& ctx) const {
auto specs = specs_;
detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
ctx);
auto quoted = basic_memory_buffer<Char>();
detail::write_escaped_path(quoted, p);
return formatter<basic_string_view<Char>, Char>::format(
basic_string_view<Char>(quoted.data(), quoted.size()), ctx);
return detail::write(
ctx.out(), basic_string_view<Char>(quoted.data(), quoted.size()), specs);
}
};
FMT_END_NAMESPACE