From c6c830e20344e753f2a221311978cd3510ac0aa2 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sun, 11 Aug 2024 10:41:06 -0700 Subject: [PATCH] Make align a proper enum class --- include/fmt/base.h | 25 +++++++++++-------------- include/fmt/format.h | 30 ++++++++++++++++-------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index 65eebab8..188aca5b 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -2060,11 +2060,6 @@ FMT_EXPORT using format_args = basic_format_args; #else # define FMT_ENUM_UNDERLYING_TYPE(type) : type #endif -namespace align { -enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char){none, left, right, center, - numeric}; -} -using align_t = align::type; namespace sign { enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char){none, minus, plus, space}; } @@ -2119,10 +2114,12 @@ enum class presentation_type : unsigned char { hexfloat // 'a' or 'A' }; +enum class align { none, left, right, center, numeric }; + // Basic format specifiers for built-in and string types. class basic_specs { private: - // Upper 32-bit of data contain fill and lower 32-bit are arranged as follows: + // Data is arranged as follows: // // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 @@ -2159,7 +2156,7 @@ class basic_specs { max_fill_size = 4 }; - unsigned long long data_ = 1 << fill_size_shift; + unsigned long data_ = 1 << fill_size_shift; // Character (code unit) type is erased to prevent template bloat. char fill_data_[max_fill_size] = {' '}; @@ -2176,10 +2173,10 @@ class basic_specs { data_ = (data_ & ~type_mask) | static_cast(t); } - constexpr auto align() const -> align_t { - return static_cast((data_ & align_mask) >> align_shift); + constexpr auto align() const -> align { + return static_cast((data_ & align_mask) >> align_shift); } - FMT_CONSTEXPR void set_align(align_t a) { + FMT_CONSTEXPR void set_align(fmt::align a) { data_ = (data_ & ~align_mask) | (static_cast(a) << align_shift); } @@ -2346,7 +2343,7 @@ FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end, : error_value; } -FMT_CONSTEXPR inline auto parse_align(char c) -> align_t { +FMT_CONSTEXPR inline auto parse_align(char c) -> align { switch (c) { case '<': return align::left; @@ -2630,11 +2627,11 @@ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end, report_error("invalid fill character '{'"); return begin; } - auto align = parse_align(to_ascii(*fill_end)); - enter_state(state::align, align != align::none); + auto alignment = parse_align(to_ascii(*fill_end)); + enter_state(state::align, alignment != align::none); specs.set_fill( basic_string_view(begin, to_unsigned(fill_end - begin))); - specs.set_align(align); + specs.set_align(alignment); begin = fill_end + 1; } } diff --git a/include/fmt/format.h b/include/fmt/format.h index 1641d4c0..c3b1760f 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1731,17 +1731,19 @@ FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, // Writes the output of f, padded according to format specifications in specs. // size: output size in code units. // width: output display width in (terminal) column positions. -template FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs& specs, size_t size, size_t width, F&& f) -> OutputIt { - static_assert(align == align::left || align == align::right, ""); + static_assert(default_align == align::left || default_align == align::right, + ""); unsigned spec_width = to_unsigned(specs.width); size_t padding = spec_width > width ? spec_width - width : 0; // Shifts are encoded as string literals because static constexpr is not // supported in constexpr functions. - auto* shifts = align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01"; - size_t left_padding = padding >> shifts[specs.align()]; + auto* shifts = + default_align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01"; + size_t left_padding = padding >> shifts[static_cast(specs.align())]; size_t right_padding = padding - left_padding; auto it = reserve(out, size + padding * specs.fill_size()); if (left_padding != 0) it = fill(it, left_padding, specs); @@ -1750,17 +1752,17 @@ FMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs& specs, return base_iterator(out, it); } -template constexpr auto write_padded(OutputIt out, const format_specs& specs, size_t size, F&& f) -> OutputIt { - return write_padded(out, specs, size, size, f); + return write_padded(out, specs, size, size, f); } -template +template FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes, const format_specs& specs = {}) -> OutputIt { - return write_padded( + return write_padded( out, specs, bytes.size(), [bytes](reserve_iterator it) { const char* data = bytes.data(); return copy(data, data + bytes.size(), it); @@ -2321,22 +2323,22 @@ template FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, format_specs& specs) -> const Char* { FMT_ASSERT(begin != end, ""); - auto align = align::none; + auto alignment = align::none; auto p = begin + code_point_length(begin); if (end - p <= 0) p = begin; for (;;) { switch (to_ascii(*p)) { case '<': - align = align::left; + alignment = align::left; break; case '>': - align = align::right; + alignment = align::right; break; case '^': - align = align::center; + alignment = align::center; break; } - if (align != align::none) { + if (alignment != align::none) { if (p != begin) { auto c = *begin; if (c == '}') return begin; @@ -2355,7 +2357,7 @@ FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, } p = begin; } - specs.set_align(align); + specs.set_align(alignment); return begin; }