19 #include "absl/strings/internal/str_format/arg.h"
25 #include <type_traits>
27 #include "absl/base/port.h"
28 #include "absl/strings/internal/str_format/float_conversion.h"
29 #include "absl/strings/numbers.h"
42 void ReducePadding(
size_t n,
size_t *
capacity) {
47 struct MakeUnsigned : std::make_unsigned<T> {};
58 struct IsSigned : std::is_signed<T> {};
72 void PrintAsOct(
T v) {
76 *--p =
static_cast<char>(
'0' + (
static_cast<size_t>(
v) & 7));
86 void PrintAsDec(
T v) {
99 PrintAsDec(
u, add_neg);
102 void PrintAsDec(
uint128 v,
bool add_neg =
false) {
124 template <
typename T>
125 void PrintAsHexLower(
T v) {
133 if (
sizeof(
T) == 1)
break;
146 template <
typename T>
147 void PrintAsHexUpper(
T v) {
153 *--p =
"0123456789ABCDEF"[
static_cast<size_t>(
v) & 15];
167 static_assert(
'-' <
'0',
"The check below verifies both.");
172 bool is_negative()
const {
return start_[0] ==
'-'; }
183 string_view BaseIndicator(
const IntDigits &as_digits,
184 const FormatConversionSpecImpl
conv) {
194 if (alt &&
hex && !as_digits.without_neg_or_zero().empty()) {
201 string_view SignColumn(
bool neg,
const FormatConversionSpecImpl
conv) {
211 bool ConvertCharImpl(
unsigned char v,
const FormatConversionSpecImpl
conv,
212 FormatSinkImpl *
sink) {
215 ReducePadding(1, &
fill);
222 bool ConvertIntImplInnerSlow(
const IntDigits &as_digits,
223 const FormatConversionSpecImpl
conv,
224 FormatSinkImpl *
sink) {
230 string_view formatted = as_digits.without_neg_or_zero();
231 ReducePadding(formatted, &
fill);
234 ReducePadding(sign, &
fill);
237 ReducePadding(base_indicator, &
fill);
240 bool precision_specified =
precision >= 0;
241 if (!precision_specified)
249 if (formatted.
empty() || *formatted.
begin() !=
'0') {
250 int needed =
static_cast<int>(formatted.
size()) + 1;
256 ReducePadding(num_zeroes, &
fill);
265 num_zeroes += num_left_spaces;
278 template <
typename T>
279 bool ConvertIntArg(
T v,
const FormatConversionSpecImpl
conv,
280 FormatSinkImpl *
sink) {
289 case static_cast<uint8_t>(FormatConversionCharInternal::c):
290 return ConvertCharImpl(
static_cast<unsigned char>(
v),
conv,
sink);
292 case static_cast<uint8_t>(FormatConversionCharInternal::o):
293 as_digits.PrintAsOct(
static_cast<U
>(
v));
296 case static_cast<uint8_t>(FormatConversionCharInternal::x):
297 as_digits.PrintAsHexLower(
static_cast<U
>(
v));
299 case static_cast<uint8_t>(FormatConversionCharInternal::X):
300 as_digits.PrintAsHexUpper(
static_cast<U
>(
v));
303 case static_cast<uint8_t>(FormatConversionCharInternal::u):
304 as_digits.PrintAsDec(
static_cast<U
>(
v));
307 case static_cast<uint8_t>(FormatConversionCharInternal::d):
308 case static_cast<uint8_t>(FormatConversionCharInternal::i):
309 as_digits.PrintAsDec(
v);
312 case static_cast<uint8_t>(FormatConversionCharInternal::a):
313 case static_cast<uint8_t>(FormatConversionCharInternal::e):
314 case static_cast<uint8_t>(FormatConversionCharInternal::f):
315 case static_cast<uint8_t>(FormatConversionCharInternal::g):
316 case static_cast<uint8_t>(FormatConversionCharInternal::A):
317 case static_cast<uint8_t>(FormatConversionCharInternal::E):
318 case static_cast<uint8_t>(FormatConversionCharInternal::F):
319 case static_cast<uint8_t>(FormatConversionCharInternal::G):
330 return ConvertIntImplInnerSlow(as_digits,
conv,
sink);
333 template <
typename T>
334 bool ConvertFloatArg(
T v,
const FormatConversionSpecImpl
conv,
335 FormatSinkImpl *
sink) {
340 inline bool ConvertStringArg(
string_view v,
const FormatConversionSpecImpl
conv,
341 FormatSinkImpl *
sink) {
356 return {ConvertStringArg(
v,
conv,
sink)};
362 return {ConvertStringArg(
v,
conv,
sink)};
375 len = std::strlen(
v);
391 as_digits.PrintAsHexLower(
v.value);
392 return {ConvertIntImplInnerSlow(as_digits,
conv,
sink)};