Добавление пользовательского форматирования типов со всеми обычными опциями - PullRequest
2 голосов
/ 30 марта 2020

Я создал класс Decimal и хочу использовать библиотеку fmt. Я прочитал, что способ определения типа для форматера заключается в специализации fmt::formatter. Но в документах нет информации о том, как подключиться к существующей общей инфраструктуре. Например, коды форматирования для выравнивания полей и общей ширины и символа заполнения: это должен быть общий код, работающий с любым типом.
Как написать специализацию форматирования без повторной реализации всей спецификации с нуля?

Я хотел бы начать с того, чтобы сделать мой тип совместимым со спецификаторами форматирования с плавающей точкой, поэтому, когда тип изменяется с double на десятичный, он будет продолжать работать так же; но затем добавьте дополнительные функции, указывающие c к типу.

template <int S, int F>
struct fmt::formatter<Decimal<S,F>> {

constexpr auto parse(format_parse_context& ctx) {
    [[maybe_unused]] auto it = ctx.begin(), end = ctx.end();
    // dummy stub.  just take the whole thing
    it = std::find(ctx.begin(),end, '}');
    return it;
}

template <typename FormatContext>
auto format(const Dec& x, FormatContext& ctx) {
    constexpr size_t bufsize = 64;
    char buf[bufsize];
    const auto end = x.to_chars (buf, buf+bufsize, false);
    const std::string_view sv { buf, size_t(end-buf) };
    return std::copy(sv.begin(),sv.end(),ctx.out());
}
};

1 Ответ

2 голосов
/ 02 апреля 2020

{fmt} пока не предоставляет средств для анализа стандартных спецификаторов формата. Внутренне он использует fmt::internal::parse_format_specs. Его нужно немного очистить и перенести в publi c API для повторного использования.

...