23 #include <double-conversion/double-conversion.h> 30 static constexpr std::size_t
size = 256;
45 template <std::
size_t Base, std::
size_t Size,
bool Upper = false>
47 static_assert(
Base <= 36,
"Base is unrepresentable");
50 constexpr
explicit make_item(std::size_t index_) : index(index_) {}
51 constexpr
char alpha(std::size_t ord)
const {
52 return ord < 10 ?
'0' + ord : (Upper ?
'A' :
'a') + (ord - 10);
58 constexpr std::array<char, Size>
operator()(std::size_t index)
const {
59 return make_array_with<Size>(
make_item{index});
65 static constexpr std::size_t
size = 256;
99 using ::double_conversion::DoubleToStringConverter;
100 using ::double_conversion::StringBuilder;
108 const char* infinitySymbol = isupper(arg.
presentation) ?
"INF" :
"inf";
109 const char* nanSymbol = isupper(arg.
presentation) ?
"NAN" :
"nan";
110 char exponentSymbol = isupper(arg.
presentation) ?
'E' :
'e';
117 constexpr
int bufLen = 2 +
118 constexpr_max(2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint +
119 DoubleToStringConverter::kMaxFixedDigitsAfterPoint,
121 8 + DoubleToStringConverter::kMaxExponentialDigits,
122 7 + DoubleToStringConverter::kMaxPrecisionDigits));
124 StringBuilder
builder(buf + 1, bufLen - 1);
139 auto flags = DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN |
140 (arg.
trailingDot ? DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT
150 if (arg.
precision > DoubleToStringConverter::kMaxFixedDigitsAfterPoint) {
151 arg.
precision = DoubleToStringConverter::kMaxFixedDigitsAfterPoint;
153 DoubleToStringConverter conv(
163 conv.ToFixed(val, arg.
precision, &builder),
164 "fixed double conversion failed");
169 if (arg.
precision > DoubleToStringConverter::kMaxExponentialDigits) {
170 arg.
precision = DoubleToStringConverter::kMaxExponentialDigits;
173 DoubleToStringConverter conv(
188 if (arg.
precision < DoubleToStringConverter::kMinPrecisionDigits) {
189 arg.
precision = DoubleToStringConverter::kMinPrecisionDigits;
190 }
else if (arg.
precision > DoubleToStringConverter::kMaxPrecisionDigits) {
191 arg.
precision = DoubleToStringConverter::kMaxPrecisionDigits;
193 DoubleToStringConverter conv(
202 arg.
enforce(conv.ToShortest(val, &builder));
209 int len = builder.position();
217 if (plusSign && (*p !=
'-' && *p !=
'n' && *p !=
'N')) {
221 }
else if (*p ==
'-') {
229 auto b = fullArgString.begin();
230 auto end = fullArgString.end();
233 auto p =
static_cast<const char*
>(memchr(
b,
':',
size_t(
end -
b)));
267 unsigned char uSign =
static_cast<unsigned char>(*p);
283 enforce(align == Align::DEFAULT,
"alignment specified twice");
285 align = Align::PAD_AFTER_SIGN;
295 }
while (p !=
end && *p >=
'0' && *p <=
'9');
300 width = kDynamicWidth;
307 if (*p >=
'0' && *p <=
'9') {
308 widthIndex = readInt();
314 }
else if (*p >=
'0' && *p <=
'9') {
323 thousandsSeparator =
true;
331 while (p !=
end && *p >=
'0' && *p <=
'9') {
336 if (p !=
end && *p ==
'.') {
355 error(
"extra characters in format string");
359 enforce(keyEmpty(),
"index not allowed");
363 precision == kDefaultPrecision,
"precision not allowed on integers");
367 !basePrefix,
"base prefix ('#') specifier only allowed on integers");
370 "thousands separator (',') only allowed on integers");
374 align != Align::PAD_AFTER_SIGN,
375 "'='alignment only allowed on numbers");
376 enforce(sign == Sign::DEFAULT,
"sign specifier only allowed on numbers");
378 !basePrefix,
"base prefix ('#') specifier only allowed on integers");
381 "thousands separator (',') only allowed on integers");
389 uint32_t separator_size = (remaining_digits - 1) / 3;
390 uint32_t result_size = remaining_digits + separator_size;
391 *end_buffer = *end_buffer + separator_size;
394 uint32_t buffer_write_index = result_size - 1;
395 uint32_t buffer_read_index = remaining_digits - 1;
396 start_buffer[buffer_write_index + 1] = 0;
402 uint32_t current_group_size = std::max<uint32_t>(
403 1, std::min<uint32_t>(remaining_digits, next_group_size));
406 for (
uint32_t i = 0;
i < current_group_size;
i++) {
407 start_buffer[buffer_write_index--] = start_buffer[buffer_read_index--];
411 if (buffer_write_index < buffer_write_index + 1) {
412 start_buffer[buffer_write_index--] =
',';
417 remaining_digits -= current_group_size;
423 :
std::out_of_range(kMessagePrefix.str() + key.str()) {}
FOLLY_STORAGE_CONSTEXPR auto formatAlignTable
const std::array< std::array< char, 3 >, 512 > formatOctal
FOLLY_STORAGE_CONSTEXPR auto formatSignTable
—— Concurrent Priority Queue Implementation ——
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
const std::array< std::array< char, 8 >, 256 > formatBinary
constexpr T constexpr_max(T a)
constexpr T constexpr_pow(T base, std::size_t exp)
auto end(TestAdlIterable &instance)
const std::array< std::array< char, 2 >, 256 > formatHexUpper
#define FOLLY_STORAGE_CONSTEXPR
AtomicCounter< T, DeterministicAtomic > Base
const std::array< std::array< char, 2 >, 256 > formatHexLower
void insertThousandsGroupingUnsafe(char *start_buffer, char **end_buffer)
constexpr auto make_array_with(MakeItem const &make)
basic_fbstring< char > fbstring
Range< const char * > StringPiece
#define FOLLY_FALLTHROUGH