| 2063 | |
| 2064 | // Size and padding computation separate from write_int to avoid template bloat. |
| 2065 | struct size_padding { |
| 2066 | unsigned size; |
| 2067 | unsigned padding; |
| 2068 | |
| 2069 | FMT_CONSTEXPR size_padding(int num_digits, unsigned prefix, |
| 2070 | const format_specs& specs) |
| 2071 | : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) { |
| 2072 | if (specs.align() == align::numeric) { |
| 2073 | auto width = to_unsigned(specs.width); |
| 2074 | if (width > size) { |
| 2075 | padding = width - size; |
| 2076 | size = width; |
| 2077 | } |
| 2078 | } else if (specs.precision > num_digits) { |
| 2079 | size = (prefix >> 24) + to_unsigned(specs.precision); |
| 2080 | padding = to_unsigned(specs.precision - num_digits); |
| 2081 | } |
| 2082 | } |
| 2083 | }; |
| 2084 | |
| 2085 | template <typename Char, typename OutputIt, typename T> |
| 2086 | FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg, |
| 2087 | const format_specs& specs) -> OutputIt { |
| 2088 | static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, ""); |
| 2089 | |
| 2090 | constexpr size_t buffer_size = num_bits<T>(); |
| 2091 | char buffer[buffer_size]; |
| 2092 | if (is_constant_evaluated()) fill_n(buffer, buffer_size, '\0'); |
| 2093 | const char* begin = nullptr; |
| 2094 | const char* end = buffer + buffer_size; |
| 2095 | |
| 2096 | auto abs_value = arg.abs_value; |
| 2097 | auto prefix = arg.prefix; |
| 2098 | switch (specs.type()) { |
| 2099 | default: FMT_ASSERT(false, ""); FMT_FALLTHROUGH; |
| 2100 | case presentation_type::none: |
| 2101 | case presentation_type::dec: |
| 2102 | begin = do_format_decimal(buffer, abs_value, buffer_size); |
| 2103 | break; |
| 2104 | case presentation_type::hex: |
| 2105 | begin = do_format_base2e(4, buffer, abs_value, buffer_size, specs.upper()); |
| 2106 | if (specs.alt()) |
| 2107 | prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0'); |
| 2108 | break; |
| 2109 | case presentation_type::oct: { |
| 2110 | begin = do_format_base2e(3, buffer, abs_value, buffer_size); |
| 2111 | // Octal prefix '0' is counted as a digit, so only add it if precision |
| 2112 | // is not greater than the number of digits. |
| 2113 | auto num_digits = end - begin; |
| 2114 | if (specs.alt() && specs.precision <= num_digits && abs_value != 0) |
| 2115 | prefix_append(prefix, '0'); |
| 2116 | break; |
| 2117 | } |
| 2118 | case presentation_type::bin: |
| 2119 | begin = do_format_base2e(1, buffer, abs_value, buffer_size); |
| 2120 | if (specs.alt()) |
| 2121 | prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0'); |
| 2122 | break; |
no test coverage detected