Skip to content

Commit a8025e0

Browse files
committed
Microsoft's floating-point to_chars powered by Ryu and Ryu Printf
Microsoft would like to contribute its implementation of floating-point to_chars to libc++. This uses the impossibly fast Ryu and Ryu Printf algorithms invented by Ulf Adams at Google. Upstream repos: https://github.com/microsoft/STL and https://github.com/ulfjack/ryu . Licensing notes: MSVC's STL is available under the Apache License v2.0 with LLVM Exception, intentionally chosen to match libc++. We've used Ryu under the Boost Software License. This patch contains minor changes from Jorg Brown at Google, to adapt the code to libc++. He verified that it works in Google's Linux-based environment, but then I applied more changes on top of his, so any compiler errors are my fault. (I haven't tried to build and test libc++ yet.) Please tell me if we need to do anything else in order to follow https://llvm.org/docs/DeveloperPolicy.html#attribution-of-changes . Notes: * libc++'s integer charconv is unchanged (except for a small refactoring). MSVC's integer charconv hasn't been tuned for performance yet, so you're not missing anything. * Floating-point from_chars isn't part of this patch because Jorg found that MSVC's implementation (derived from our CRT's strtod) was slower than Abseil's. If you're unable to use Abseil or another implementation due to licensing or technical considerations, Microsoft would be delighted if you used MSVC's from_chars (and you can just take it, or ask us to provide a patch like this). Ulf is also working on a novel algorithm for from_chars. * This assumes that float is IEEE 32-bit, double is IEEE 64-bit, and long double is also IEEE 64-bit. * I have added MSVC's charconv tests (the whole thing: integer/floating from_chars/to_chars), but haven't adapted them to libcxx's harness at all. (These tests will be available in the microsoft/STL repo soon.) * Jorg added int128 codepaths. These were originally present in upstream Ryu, and I removed them from microsoft/STL purely for performance reasons (MSVC doesn't support int128; Clang on Windows does, but I found that x64 intrinsics were slightly faster). * The implementation is split into 3 headers. In MSVC's STL, charconv contains only Microsoft-written code. xcharconv_ryu.h contains code derived from Ryu (with significant modifications and additions). xcharconv_ryu_tables.h contains Ryu's large lookup tables (they were sufficiently large to make editing inconvenient, hence the separate file). The xmeow.h convention is MSVC's for internal headers; you may wish to rename them. * You should consider separately compiling the lookup tables (see microsoft/STL#172 ) for compiler throughput and reduced object file size. * See https://github.com/StephanTLavavej/llvm-project/commits/charconv for fine-grained history. (If necessary, I can perform some rebase surgery to show you what Jorg changed relative to the microsoft/STL repo; currently that's all fused into the first commit.) Differential Revision: https://reviews.llvm.org/D70631
1 parent 15495be commit a8025e0

File tree

48 files changed

+73318
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+73318
-18
lines changed

libcxx/CREDITS.TXT

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ N: Saleem Abdulrasool
1212
1313
D: Minor patches and Linux fixes.
1414

15+
N: Ulf Adams
16+
D: Invented the Ryu and Ryu Printf algorithms used in floating-point to_chars, and wrote the initial code.
17+
1518
N: Muiez Ahmed
1619
1720
D: z/OS port.
@@ -28,6 +31,9 @@ N: Holger Arnold
2831
2932
D: Minor fix.
3033

34+
N: Jorg Brown
35+
D: Ported floating-point to_chars from MSVC to libc++.
36+
3137
N: David Chisnall
3238
E: theraven at theravensnest dot org
3339
D: FreeBSD and Solaris ports, libcxxrt support, some atomics work.
@@ -81,6 +87,14 @@ N: Argyrios Kyrtzidis
8187
8288
D: Bug fixes.
8389

90+
N: Stephan T. Lavavej
91+
92+
93+
D: Implemented floating-point to_chars.
94+
95+
N: Microsoft Corporation
96+
D: Contributed floating-point to_chars.
97+
8498
N: Bruce Mitchener, Jr.
8599
86100
D: Emscripten-related changes.
@@ -152,6 +166,7 @@ D: Minor bug fix.
152166
N: Mark de Wever
153167
E: koraq at xs4all dot nl
154168
D: Format library support.
169+
D: Finalized the porting of MSVC's to_chars to libc++.
155170

156171
N: Zhang Xiongpang
157172

libcxx/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ New Features
5555
behavior of standard algorithms (e.g. equal elements in ``std::sort`` or
5656
randomization of both sides of partition for ``std::nth_element``)
5757

58+
- Floating-point support for ``std::to_chars`` support has been added.
59+
Thanks to Stephan T. Lavavej and Microsoft for providing their implemention
60+
to libc++.
61+
5862
API Changes
5963
-----------
6064

libcxx/docs/Status/Cxx17.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Paper Status
4040

4141
.. note::
4242

43+
.. [#note-P0067] P0067: ``std::(to|from)_chars`` for integrals has been available since version 7.0. ``std::to_chars`` for ``float`` and ``double`` since version 14.0 ``std::to_chars`` for ``long double`` uses the implementation for ``double``.
4344
.. [#note-P0607] P0607: The parts of P0607 that are not done are the ``<regex>`` bits.
4445
4546

libcxx/docs/Status/Cxx17Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"`P0394r4 <https://wg21.link/P0394r4>`__","LWG","Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling","Oulu","",""
7272
"","","","","",""
7373
"`P0003R5 <https://wg21.link/P0003R5>`__","LWG","Removing Deprecated Exception Specifications from C++17","Issaquah","|Complete|","5.0"
74-
"`P0067R5 <https://wg21.link/P0067R5>`__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial|",""
74+
"`P0067R5 <https://wg21.link/P0067R5>`__","LWG","Elementary string conversions, revision 5","Issaquah","|Partial| [#note-P0067]",""
7575
"`P0403R1 <https://wg21.link/P0403R1>`__","LWG","Literal suffixes for ``basic_string_view``\ ","Issaquah","|Complete|","4.0"
7676
"`P0414R2 <https://wg21.link/P0414R2>`__","LWG","Merging shared_ptr changes from Library Fundamentals to C++17","Issaquah","|Complete|","11.0"
7777
"`P0418R2 <https://wg21.link/P0418R2>`__","LWG","Fail or succeed: there is no atomic lattice","Issaquah","",""

libcxx/include/__availability

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@
129129
// This controls the availability of std::to_chars.
130130
# define _LIBCPP_AVAILABILITY_TO_CHARS
131131

132+
// This controls the availability of floating-point std::to_chars functions.
133+
// These overloads were added later than the integer overloads.
134+
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT
135+
132136
// This controls the availability of the C++20 synchronization library,
133137
// which requires shared library support for various operations
134138
// (see libcxx/src/atomic.cpp).
@@ -222,6 +226,9 @@
222226
# define _LIBCPP_AVAILABILITY_TO_CHARS \
223227
_LIBCPP_AVAILABILITY_FILESYSTEM
224228

229+
# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \
230+
__attribute__((unavailable))
231+
225232
# define _LIBCPP_AVAILABILITY_SYNC \
226233
__attribute__((availability(macosx,strict,introduced=11.0))) \
227234
__attribute__((availability(ios,strict,introduced=14.0))) \

libcxx/include/charconv

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,38 @@ from_chars(const char* __first, const char* __last, _Tp& __value, int __base)
598598
return __from_chars_integral(__first, __last, __value, __base);
599599
}
600600

601+
// Floating-point implementation starts here.
602+
// Unlike the other parts of charconv this is only available in C++17 and newer.
603+
#if _LIBCPP_STD_VER > 14
604+
605+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
606+
to_chars_result to_chars(char* __first, char* __last, float __value);
607+
608+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
609+
to_chars_result to_chars(char* __first, char* __last, double __value);
610+
611+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
612+
to_chars_result to_chars(char* __first, char* __last, long double __value);
613+
614+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
615+
to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt);
616+
617+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
618+
to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt);
619+
620+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
621+
to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt);
622+
623+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
624+
to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision);
625+
626+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
627+
to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision);
628+
629+
_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS
630+
to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision);
631+
632+
# endif // _LIBCPP_STD_VER > 14
601633
#endif // _LIBCPP_CXX03_LANG
602634

603635
_LIBCPP_END_NAMESPACE_STD

libcxx/lib/abi/CHANGELOG.TXT

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,48 @@ New entries should be added directly below the "Version" header.
1616
Version 14.0
1717
------------
1818

19+
* [libc++] `to_chars` for floating point.
20+
21+
This commit added the `to_chars` implementation for floating point values.
22+
The entire implementation resides in the dylib and the functions specified
23+
in the Standard are now part of the ABI.
24+
25+
arm64-apple-darwin
26+
------------------
27+
Symbol added: _ZNSt3__18to_charsEPcS0_d
28+
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatE
29+
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi
30+
Symbol added: _ZNSt3__18to_charsEPcS0_e
31+
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatE
32+
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi
33+
Symbol added: _ZNSt3__18to_charsEPcS0_f
34+
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatE
35+
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi
36+
37+
x86_64-apple-darwin
38+
-------------------
39+
Symbol added: _ZNSt3__18to_charsEPcS0_d
40+
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatE
41+
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi
42+
Symbol added: _ZNSt3__18to_charsEPcS0_e
43+
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatE
44+
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi
45+
Symbol added: _ZNSt3__18to_charsEPcS0_f
46+
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatE
47+
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi
48+
49+
x86_64-unknown-linux-gnu
50+
------------------------
51+
Symbol added: _ZNSt3__18to_charsEPcS0_d
52+
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatE
53+
Symbol added: _ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi
54+
Symbol added: _ZNSt3__18to_charsEPcS0_e
55+
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatE
56+
Symbol added: _ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi
57+
Symbol added: _ZNSt3__18to_charsEPcS0_f
58+
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatE
59+
Symbol added: _ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi
60+
1961
* [libc++] Resolve missing table_size symbol
2062

2163
This commit added an out-of-line definition for `table_size` in the library.

libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,15 @@
18791879
{'is_defined': True, 'name': '__ZNSt3__18time_getIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
18801880
{'is_defined': True, 'name': '__ZNSt3__18time_putIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
18811881
{'is_defined': True, 'name': '__ZNSt3__18time_putIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
1882+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_d', 'type': 'FUNC'}
1883+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_dNS_12chars_formatE', 'type': 'FUNC'}
1884+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi', 'type': 'FUNC'}
1885+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_e', 'type': 'FUNC'}
1886+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_eNS_12chars_formatE', 'type': 'FUNC'}
1887+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi', 'type': 'FUNC'}
1888+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_f', 'type': 'FUNC'}
1889+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_fNS_12chars_formatE', 'type': 'FUNC'}
1890+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi', 'type': 'FUNC'}
18821891
{'is_defined': True, 'name': '__ZNSt3__18valarrayImE6resizeEmm', 'type': 'FUNC'}
18831892
{'is_defined': True, 'name': '__ZNSt3__18valarrayImEC1Em', 'type': 'FUNC'}
18841893
{'is_defined': True, 'name': '__ZNSt3__18valarrayImEC2Em', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,15 @@
18791879
{'is_defined': True, 'name': '__ZNSt3__18time_getIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
18801880
{'is_defined': True, 'name': '__ZNSt3__18time_putIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
18811881
{'is_defined': True, 'name': '__ZNSt3__18time_putIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 0, 'type': 'OBJECT'}
1882+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_d', 'type': 'FUNC'}
1883+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_dNS_12chars_formatE', 'type': 'FUNC'}
1884+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi', 'type': 'FUNC'}
1885+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_e', 'type': 'FUNC'}
1886+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_eNS_12chars_formatE', 'type': 'FUNC'}
1887+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi', 'type': 'FUNC'}
1888+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_f', 'type': 'FUNC'}
1889+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_fNS_12chars_formatE', 'type': 'FUNC'}
1890+
{'is_defined': True, 'name': '__ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi', 'type': 'FUNC'}
18821891
{'is_defined': True, 'name': '__ZNSt3__18valarrayImE6resizeEmm', 'type': 'FUNC'}
18831892
{'is_defined': True, 'name': '__ZNSt3__18valarrayImEC1Em', 'type': 'FUNC'}
18841893
{'is_defined': True, 'name': '__ZNSt3__18valarrayImEC2Em', 'type': 'FUNC'}

libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,15 @@
15731573
{'is_defined': True, 'name': '_ZNSt3__18time_getIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 16, 'type': 'OBJECT'}
15741574
{'is_defined': True, 'name': '_ZNSt3__18time_putIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEE2idE', 'size': 16, 'type': 'OBJECT'}
15751575
{'is_defined': True, 'name': '_ZNSt3__18time_putIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEE2idE', 'size': 16, 'type': 'OBJECT'}
1576+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_d', 'type': 'FUNC'}
1577+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_dNS_12chars_formatE', 'type': 'FUNC'}
1578+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_dNS_12chars_formatEi', 'type': 'FUNC'}
1579+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_e', 'type': 'FUNC'}
1580+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_eNS_12chars_formatE', 'type': 'FUNC'}
1581+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_eNS_12chars_formatEi', 'type': 'FUNC'}
1582+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_f', 'type': 'FUNC'}
1583+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_fNS_12chars_formatE', 'type': 'FUNC'}
1584+
{'is_defined': True, 'name': '_ZNSt3__18to_charsEPcS0_fNS_12chars_formatEi', 'type': 'FUNC'}
15761585
{'is_defined': True, 'name': '_ZNSt3__18valarrayImE6resizeEmm', 'type': 'FUNC'}
15771586
{'is_defined': True, 'name': '_ZNSt3__18valarrayImEC1Em', 'type': 'FUNC'}
15781587
{'is_defined': True, 'name': '_ZNSt3__18valarrayImEC2Em', 'type': 'FUNC'}

libcxx/src/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,26 @@ set(LIBCXX_SOURCES
1919
include/atomic_support.h
2020
include/config_elast.h
2121
include/refstring.h
22+
include/ryu/common.h
23+
include/ryu/d2fixed.h
24+
include/ryu/d2fixed_full_table.h
25+
include/ryu/d2s.h
26+
include/ryu/d2s_full_table.h
27+
include/ryu/d2s_intrinsics.h
28+
include/ryu/digit_table.h
29+
include/ryu/f2s.h
30+
include/ryu/ryu.h
31+
include/to_chars_floating_point.h
2232
legacy_pointer_safety.cpp
2333
memory.cpp
2434
mutex.cpp
2535
mutex_destructor.cpp
2636
new.cpp
2737
optional.cpp
2838
random_shuffle.cpp
39+
ryu/d2fixed.cpp
40+
ryu/d2s.cpp
41+
ryu/f2s.cpp
2942
shared_mutex.cpp
3043
stdexcept.cpp
3144
string.cpp

libcxx/src/charconv.cpp

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,14 @@
99
#include "charconv"
1010
#include <string.h>
1111

12+
#include "include/ryu/digit_table.h"
13+
#include "include/to_chars_floating_point.h"
14+
1215
_LIBCPP_BEGIN_NAMESPACE_STD
1316

1417
namespace __itoa
1518
{
1619

17-
static constexpr char cDigitsLut[200] = {
18-
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0',
19-
'7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4',
20-
'1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0', '2', '1', '2',
21-
'2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
22-
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3',
23-
'7', '3', '8', '3', '9', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4',
24-
'4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '5', '0', '5', '1', '5',
25-
'2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
26-
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6',
27-
'7', '6', '8', '6', '9', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4',
28-
'7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '8', '0', '8', '1', '8',
29-
'2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
30-
'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9',
31-
'7', '9', '8', '9', '9'};
32-
3320
template <typename T>
3421
inline _LIBCPP_INLINE_VISIBILITY char*
3522
append1(char* buffer, T i) noexcept
@@ -42,7 +29,7 @@ template <typename T>
4229
inline _LIBCPP_INLINE_VISIBILITY char*
4330
append2(char* buffer, T i) noexcept
4431
{
45-
memcpy(buffer, &cDigitsLut[(i)*2], 2);
32+
memcpy(buffer, &__DIGIT_TABLE[(i)*2], 2);
4633
return buffer + 2;
4734
}
4835

@@ -157,4 +144,53 @@ __u64toa(uint64_t value, char* buffer) noexcept
157144

158145
} // namespace __itoa
159146

147+
// The original version of floating-point to_chars was written by Microsoft and
148+
// contributed with the following license.
149+
150+
// Copyright (c) Microsoft Corporation.
151+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
152+
153+
// This implementation is dedicated to the memory of Mary and Thavatchai.
154+
155+
to_chars_result to_chars(char* __first, char* __last, float __value) {
156+
return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, __value, chars_format{}, 0);
157+
}
158+
159+
to_chars_result to_chars(char* __first, char* __last, double __value) {
160+
return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, __value, chars_format{}, 0);
161+
}
162+
163+
to_chars_result to_chars(char* __first, char* __last, long double __value) {
164+
return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, static_cast<double>(__value),
165+
chars_format{}, 0);
166+
}
167+
168+
to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt) {
169+
return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, __value, __fmt, 0);
170+
}
171+
172+
to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt) {
173+
return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, __value, __fmt, 0);
174+
}
175+
176+
to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt) {
177+
return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, static_cast<double>(__value),
178+
__fmt, 0);
179+
}
180+
181+
to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision) {
182+
return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(__first, __last, __value, __fmt,
183+
__precision);
184+
}
185+
186+
to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision) {
187+
return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(__first, __last, __value, __fmt,
188+
__precision);
189+
}
190+
191+
to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision) {
192+
return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(
193+
__first, __last, static_cast<double>(__value), __fmt, __precision);
194+
}
195+
160196
_LIBCPP_END_NAMESPACE_STD

0 commit comments

Comments
 (0)