| 2696 | template <typename Range> |
| 2697 | template <typename T> |
| 2698 | void basic_writer<Range>::write_double(T value, const format_specs &spec) { |
| 2699 | // Check type. |
| 2700 | float_spec_handler handler(static_cast<char>(spec.type)); |
| 2701 | internal::handle_float_type_spec(handler.type, handler); |
| 2702 | |
| 2703 | char sign = 0; |
| 2704 | // Use signbit instead of value < 0 because the latter is always |
| 2705 | // false for NaN. |
| 2706 | if (std::signbit(value)) { |
| 2707 | sign = '-'; |
| 2708 | value = -value; |
| 2709 | } else if (spec.has(SIGN_FLAG)) { |
| 2710 | sign = spec.has(PLUS_FLAG) ? '+' : ' '; |
| 2711 | } |
| 2712 | |
| 2713 | struct write_inf_or_nan_t { |
| 2714 | basic_writer &writer; |
| 2715 | format_specs spec; |
| 2716 | char sign; |
| 2717 | void operator()(const char *str) const { |
| 2718 | writer.write_padded(spec, inf_or_nan_writer{sign, str}); |
| 2719 | } |
| 2720 | } write_inf_or_nan = {*this, spec, sign}; |
| 2721 | |
| 2722 | // Format NaN and ininity ourselves because sprintf's output is not consistent |
| 2723 | // across platforms. |
| 2724 | if (internal::fputil::isnotanumber(value)) |
| 2725 | return write_inf_or_nan(handler.upper ? "NAN" : "nan"); |
| 2726 | if (internal::fputil::isinfinity(value)) |
| 2727 | return write_inf_or_nan(handler.upper ? "INF" : "inf"); |
| 2728 | |
| 2729 | memory_buffer buffer; |
| 2730 | bool use_grisu = FMT_USE_GRISU && sizeof(T) <= sizeof(double) && |
| 2731 | spec.type != 'a' && spec.type != 'A' && |
| 2732 | internal::grisu2_format(static_cast<double>(value), buffer, spec); |
| 2733 | if (!use_grisu) { |
| 2734 | format_specs normalized_spec(spec); |
| 2735 | normalized_spec.type = handler.type; |
| 2736 | internal::sprintf_format(value, buffer, normalized_spec); |
| 2737 | } |
| 2738 | size_t n = buffer.size(); |
| 2739 | align_spec as = spec; |
| 2740 | if (spec.align() == ALIGN_NUMERIC) { |
| 2741 | if (sign) { |
| 2742 | auto &&it = reserve(1); |
| 2743 | *it++ = static_cast<char_type>(sign); |
| 2744 | sign = 0; |
| 2745 | if (as.width_) |
| 2746 | --as.width_; |
| 2747 | } |
| 2748 | as.align_ = ALIGN_RIGHT; |
| 2749 | } else { |
| 2750 | if (spec.align() == ALIGN_DEFAULT) |
| 2751 | as.align_ = ALIGN_RIGHT; |
| 2752 | if (sign) |
| 2753 | ++n; |
| 2754 | } |
| 2755 | write_padded(as, double_writer{n, sign, buffer}); |
no test coverage detected