| 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; |
| 2123 | case presentation_type::chr: |
| 2124 | return write_char<Char>(out, static_cast<Char>(abs_value), specs); |
| 2125 | } |
| 2126 | |
| 2127 | // Write an integer in the format |
| 2128 | // <left-padding><prefix><numeric-padding><digits><right-padding> |
| 2129 | // prefix contains chars in three lower bytes and the size in the fourth byte. |
| 2130 | int num_digits = static_cast<int>(end - begin); |
| 2131 | // Slightly faster check for specs.width == 0 && specs.precision == -1. |
| 2132 | if ((specs.width | (specs.precision + 1)) == 0) { |
| 2133 | auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24)); |
| 2134 | for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) |
| 2135 | *it++ = static_cast<Char>(p & 0xff); |
| 2136 | return base_iterator(out, copy<Char>(begin, end, it)); |
| 2137 | } |
| 2138 | auto sp = size_padding(num_digits, prefix, specs); |
| 2139 | unsigned padding = sp.padding; |
| 2140 | return write_padded<Char, align::right>( |
| 2141 | out, specs, sp.size, [=](reserve_iterator<OutputIt> it) { |
| 2142 | for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8) |
| 2143 | *it++ = static_cast<Char>(p & 0xff); |
nothing calls this directly
no test coverage detected