MCPcopy Create free account
hub / github.com/LemLib/LemLib / do_write_float

Method do_write_float

include/fmt/format.h:2382–2476  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2380
2381template <typename OutputIt, typename DecimalFP, typename Char, typename Grouping = digit_grouping<Char>>
2382FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f, const format_specs<Char>& specs,
2383 float_specs fspecs, locale_ref loc) -> OutputIt {
2384 auto significand = f.significand;
2385 int significand_size = get_significand_size(f);
2386 const Char zero = static_cast<Char>('0');
2387 auto sign = fspecs.sign;
2388 size_t size = to_unsigned(significand_size) + (sign ? 1 : 0);
2389 using iterator = reserve_iterator<OutputIt>;
2390
2391 Char decimal_point = fspecs.locale ? detail::decimal_point<Char>(loc) : static_cast<Char>('.');
2392
2393 int output_exp = f.exponent + significand_size - 1;
2394 auto use_exp_format = [=]() {
2395 if (fspecs.format == float_format::exp) return true;
2396 if (fspecs.format != float_format::general) return false;
2397 // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
2398 // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
2399 const int exp_lower = -4, exp_upper = 16;
2400 return output_exp < exp_lower || output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper);
2401 };
2402 if (use_exp_format()) {
2403 int num_zeros = 0;
2404 if (fspecs.showpoint) {
2405 num_zeros = fspecs.precision - significand_size;
2406 if (num_zeros < 0) num_zeros = 0;
2407 size += to_unsigned(num_zeros);
2408 } else if (significand_size == 1) {
2409 decimal_point = Char();
2410 }
2411 auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
2412 int exp_digits = 2;
2413 if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
2414
2415 size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
2416 char exp_char = fspecs.upper ? 'E' : 'e';
2417 auto write = [=](iterator it) {
2418 if (sign) *it++ = detail::sign<Char>(sign);
2419 // Insert a decimal point after the first digit and add an exponent.
2420 it = write_significand(it, significand, significand_size, 1, decimal_point);
2421 if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
2422 *it++ = static_cast<Char>(exp_char);
2423 return write_exponent<Char>(output_exp, it);
2424 };
2425 return specs.width > 0 ? write_padded<align::right>(out, specs, size, write)
2426 : base_iterator(out, write(reserve(out, size)));
2427 }
2428
2429 int exp = f.exponent + significand_size;
2430 if (f.exponent >= 0) {
2431 // 1234e5 -> 123400000[.0+]
2432 size += to_unsigned(f.exponent);
2433 int num_zeros = fspecs.precision - exp;
2434 abort_fuzzing_if(num_zeros > 5000);
2435 if (fspecs.showpoint) {
2436 ++size;
2437 if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 0;
2438 if (num_zeros > 0) size += to_unsigned(num_zeros);
2439 }

Callers

nothing calls this directly

Calls 7

to_unsignedFunction · 0.85
fill_nFunction · 0.85
base_iteratorFunction · 0.85
writeFunction · 0.85
abort_fuzzing_ifFunction · 0.85
reserveFunction · 0.70
count_separatorsMethod · 0.45

Tested by

no test coverage detected