| 1833 | template <typename Char> |
| 1834 | template <typename T> |
| 1835 | void BasicWriter<Char>::write_double( |
| 1836 | T value, const FormatSpec &spec) { |
| 1837 | // Check type. |
| 1838 | char type = spec.type(); |
| 1839 | bool upper = false; |
| 1840 | switch (type) { |
| 1841 | case 0: |
| 1842 | type = 'g'; |
| 1843 | break; |
| 1844 | case 'e': case 'f': case 'g': case 'a': |
| 1845 | break; |
| 1846 | case 'F': |
| 1847 | #ifdef _MSC_VER |
| 1848 | // MSVC's printf doesn't support 'F'. |
| 1849 | type = 'f'; |
| 1850 | #endif |
| 1851 | // Fall through. |
| 1852 | case 'E': case 'G': case 'A': |
| 1853 | upper = true; |
| 1854 | break; |
| 1855 | default: |
| 1856 | internal::report_unknown_type(type, "double"); |
| 1857 | break; |
| 1858 | } |
| 1859 | |
| 1860 | char sign = 0; |
| 1861 | // Use getsign instead of value < 0 because the latter is always |
| 1862 | // false for NaN. |
| 1863 | if (internal::getsign(static_cast<double>(value))) { |
| 1864 | sign = '-'; |
| 1865 | value = -value; |
| 1866 | } else if (spec.flag(SIGN_FLAG)) { |
| 1867 | sign = spec.flag(PLUS_FLAG) ? '+' : ' '; |
| 1868 | } |
| 1869 | |
| 1870 | if (value != value) { |
| 1871 | // Format NaN ourselves because sprintf's output is not consistent |
| 1872 | // across platforms. |
| 1873 | std::size_t size = 4; |
| 1874 | const char *nan = upper ? " NAN" : " nan"; |
| 1875 | if (!sign) { |
| 1876 | --size; |
| 1877 | ++nan; |
| 1878 | } |
| 1879 | CharPtr out = write_str(nan, size, spec); |
| 1880 | if (sign) |
| 1881 | *out = sign; |
| 1882 | return; |
| 1883 | } |
| 1884 | |
| 1885 | if (internal::isinfinity(value)) { |
| 1886 | // Format infinity ourselves because sprintf's output is not consistent |
| 1887 | // across platforms. |
| 1888 | std::size_t size = 4; |
| 1889 | const char *inf = upper ? " INF" : " inf"; |
| 1890 | if (!sign) { |
| 1891 | --size; |
| 1892 | ++inf; |
nothing calls this directly
no test coverage detected