blob: 60ec3eccc949d7ef53ebf101c95cac48b83e27d6 [file] [log] [blame]
Louis Dionne9bd93882021-11-17 16:25:01 -05001//===----------------------------------------------------------------------===//
Zhihao Yuan7bf19052018-08-01 02:38:30 +00002//
Chandler Carruthd2012102019-01-19 10:56:40 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Zhihao Yuan7bf19052018-08-01 02:38:30 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "charconv"
10#include <string.h>
11
Mark de Wever82dfd332021-02-09 17:52:41 +010012#include "include/ryu/digit_table.h"
13#include "include/to_chars_floating_point.h"
14
Zhihao Yuan7bf19052018-08-01 02:38:30 +000015_LIBCPP_BEGIN_NAMESPACE_STD
16
17namespace __itoa
18{
19
Zhihao Yuan7bf19052018-08-01 02:38:30 +000020template <typename T>
21inline _LIBCPP_INLINE_VISIBILITY char*
Louis Dionne4c7d4f12020-05-21 10:25:15 -040022append1(char* buffer, T i) noexcept
Zhihao Yuan7bf19052018-08-01 02:38:30 +000023{
24 *buffer = '0' + static_cast<char>(i);
25 return buffer + 1;
26}
27
28template <typename T>
29inline _LIBCPP_INLINE_VISIBILITY char*
Louis Dionne4c7d4f12020-05-21 10:25:15 -040030append2(char* buffer, T i) noexcept
Zhihao Yuan7bf19052018-08-01 02:38:30 +000031{
Mark de Wever82dfd332021-02-09 17:52:41 +010032 memcpy(buffer, &__DIGIT_TABLE[(i)*2], 2);
Zhihao Yuan7bf19052018-08-01 02:38:30 +000033 return buffer + 2;
34}
35
36template <typename T>
37inline _LIBCPP_INLINE_VISIBILITY char*
Louis Dionne4c7d4f12020-05-21 10:25:15 -040038append3(char* buffer, T i) noexcept
Zhihao Yuan7bf19052018-08-01 02:38:30 +000039{
40 return append2(append1(buffer, (i) / 100), (i) % 100);
41}
42
43template <typename T>
44inline _LIBCPP_INLINE_VISIBILITY char*
Louis Dionne4c7d4f12020-05-21 10:25:15 -040045append4(char* buffer, T i) noexcept
Zhihao Yuan7bf19052018-08-01 02:38:30 +000046{
47 return append2(append2(buffer, (i) / 100), (i) % 100);
48}
49
Zhihao Yuanf974fb72019-06-10 17:11:46 +000050template <typename T>
51inline _LIBCPP_INLINE_VISIBILITY char*
Louis Dionne4c7d4f12020-05-21 10:25:15 -040052append2_no_zeros(char* buffer, T v) noexcept
Zhihao Yuanf974fb72019-06-10 17:11:46 +000053{
54 if (v < 10)
55 return append1(buffer, v);
56 else
57 return append2(buffer, v);
58}
59
60template <typename T>
61inline _LIBCPP_INLINE_VISIBILITY char*
Louis Dionne4c7d4f12020-05-21 10:25:15 -040062append4_no_zeros(char* buffer, T v) noexcept
Zhihao Yuanf974fb72019-06-10 17:11:46 +000063{
64 if (v < 100)
65 return append2_no_zeros(buffer, v);
66 else if (v < 1000)
67 return append3(buffer, v);
68 else
69 return append4(buffer, v);
70}
71
72template <typename T>
73inline _LIBCPP_INLINE_VISIBILITY char*
Louis Dionne4c7d4f12020-05-21 10:25:15 -040074append8_no_zeros(char* buffer, T v) noexcept
Zhihao Yuanf974fb72019-06-10 17:11:46 +000075{
76 if (v < 10000)
77 {
78 buffer = append4_no_zeros(buffer, v);
79 }
80 else
81 {
82 buffer = append4_no_zeros(buffer, v / 10000);
83 buffer = append4(buffer, v % 10000);
84 }
85 return buffer;
86}
87
Zhihao Yuan7bf19052018-08-01 02:38:30 +000088char*
Louis Dionne65358e12021-03-01 12:09:45 -050089__u32toa(uint32_t value, char* buffer) noexcept
Zhihao Yuan7bf19052018-08-01 02:38:30 +000090{
Zhihao Yuanf974fb72019-06-10 17:11:46 +000091 if (value < 100000000)
Zhihao Yuan7bf19052018-08-01 02:38:30 +000092 {
Zhihao Yuanf974fb72019-06-10 17:11:46 +000093 buffer = append8_no_zeros(buffer, value);
Zhihao Yuan7bf19052018-08-01 02:38:30 +000094 }
95 else
96 {
97 // value = aabbbbcccc in decimal
98 const uint32_t a = value / 100000000; // 1 to 42
99 value %= 100000000;
100
Zhihao Yuanf974fb72019-06-10 17:11:46 +0000101 buffer = append2_no_zeros(buffer, a);
Zhihao Yuan7bf19052018-08-01 02:38:30 +0000102 buffer = append4(buffer, value / 10000);
103 buffer = append4(buffer, value % 10000);
104 }
105
106 return buffer;
107}
108
109char*
Louis Dionne65358e12021-03-01 12:09:45 -0500110__u64toa(uint64_t value, char* buffer) noexcept
Zhihao Yuan7bf19052018-08-01 02:38:30 +0000111{
112 if (value < 100000000)
113 {
114 uint32_t v = static_cast<uint32_t>(value);
Zhihao Yuanf974fb72019-06-10 17:11:46 +0000115 buffer = append8_no_zeros(buffer, v);
Zhihao Yuan7bf19052018-08-01 02:38:30 +0000116 }
117 else if (value < 10000000000000000)
118 {
119 const uint32_t v0 = static_cast<uint32_t>(value / 100000000);
120 const uint32_t v1 = static_cast<uint32_t>(value % 100000000);
121
Zhihao Yuanf974fb72019-06-10 17:11:46 +0000122 buffer = append8_no_zeros(buffer, v0);
Zhihao Yuan7bf19052018-08-01 02:38:30 +0000123 buffer = append4(buffer, v1 / 10000);
124 buffer = append4(buffer, v1 % 10000);
125 }
126 else
127 {
128 const uint32_t a =
129 static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844
130 value %= 10000000000000000;
131
Zhihao Yuanf974fb72019-06-10 17:11:46 +0000132 buffer = append4_no_zeros(buffer, a);
Zhihao Yuan7bf19052018-08-01 02:38:30 +0000133
134 const uint32_t v0 = static_cast<uint32_t>(value / 100000000);
135 const uint32_t v1 = static_cast<uint32_t>(value % 100000000);
136 buffer = append4(buffer, v0 / 10000);
137 buffer = append4(buffer, v0 % 10000);
138 buffer = append4(buffer, v1 / 10000);
139 buffer = append4(buffer, v1 % 10000);
140 }
141
142 return buffer;
143}
144
145} // namespace __itoa
146
Mark de Wever82dfd332021-02-09 17:52:41 +0100147// 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
155to_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
159to_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
163to_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
168to_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
172to_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
176to_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
181to_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
186to_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
191to_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
Zhihao Yuan7bf19052018-08-01 02:38:30 +0000196_LIBCPP_END_NAMESPACE_STD