Skip to content

Commit 6c4267f

Browse files
[libcxx][libc] Hand in Hand PoC with from_chars (#91651)
Implements std::from_chars for float and double. The implementation uses LLVM-libc to do the real parsing. Since this is the first time libc++ uses LLVM-libc there is a bit of additional infrastructure code. The patch is based on the [RFC] Project Hand In Hand (LLVM-libc/libc++ code sharing) https://discourse.llvm.org/t/rfc-project-hand-in-hand-llvm-libc-libc-code-sharing/77701
1 parent 9b7be3e commit 6c4267f

36 files changed

+2365
-21
lines changed

libc/shared/fp_bits.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===-- Floating point number utils -----------------------------*- C++ -*-===//
2+
//
3+
// 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
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SHARED_FP_BITS_H
10+
#define LLVM_LIBC_SHARED_FP_BITS_H
11+
12+
#include "src/__support/FPUtil/FPBits.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
namespace shared {
16+
17+
using fputil::FPBits;
18+
19+
} // namespace shared
20+
} // namespace LIBC_NAMESPACE_DECL
21+
22+
#endif // LLVM_LIBC_SHARED_FP_BITS_H

libc/shared/str_to_float.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===-- String to float conversion utils ------------------------*- C++ -*-===//
2+
//
3+
// 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
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SHARED_STR_TO_FLOAT_H
10+
#define LLVM_LIBC_SHARED_STR_TO_FLOAT_H
11+
12+
#include "src/__support/str_to_float.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
namespace shared {
16+
17+
using internal::ExpandedFloat;
18+
using internal::FloatConvertReturn;
19+
using internal::RoundDirection;
20+
21+
using internal::binary_exp_to_float;
22+
using internal::decimal_exp_to_float;
23+
24+
} // namespace shared
25+
} // namespace LIBC_NAMESPACE_DECL
26+
27+
#endif // LLVM_LIBC_SHARED_STR_TO_FLOAT_H

libc/shared/str_to_integer.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===-- String to int conversion utils --------------------------*- C++ -*-===//
2+
//
3+
// 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
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SHARED_STR_TO_INTEGER_H
10+
#define LLVM_LIBC_SHARED_STR_TO_INTEGER_H
11+
12+
#include "src/__support/str_to_integer.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
namespace shared {
16+
17+
using LIBC_NAMESPACE::StrToNumResult;
18+
19+
using internal::strtointeger;
20+
21+
} // namespace shared
22+
} // namespace LIBC_NAMESPACE_DECL
23+
24+
#endif // LLVM_LIBC_SHARED_STR_TO_INTEGER_H

libc/src/__support/FPUtil/FPBits.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// -----------------------------------------------------------------------------
10+
// **** WARNING ****
11+
// This file is shared with libc++. You should also be careful when adding
12+
// dependencies to this file, since it needs to build for all libc++ targets.
13+
// -----------------------------------------------------------------------------
14+
915
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_H
1016
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_H
1117

@@ -795,6 +801,12 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
795801
static_assert(cpp::always_false<UnqualT>, "Unsupported type");
796802
}
797803

804+
// -----------------------------------------------------------------------------
805+
// **** WARNING ****
806+
// This interface is shared with libc++, if you change this interface you need
807+
// to update it in both libc and libc++. You should also be careful when adding
808+
// dependencies to this file, since it needs to build for all libc++ targets.
809+
// -----------------------------------------------------------------------------
798810
// A generic class to manipulate C++ floating point formats.
799811
// It derives its functionality to FPRepImpl above.
800812
template <typename T>

libc/src/__support/high_precision_decimal.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// -----------------------------------------------------------------------------
10+
// **** WARNING ****
11+
// This file is shared with libc++. You should also be careful when adding
12+
// dependencies to this file, since it needs to build for all libc++ targets.
13+
// -----------------------------------------------------------------------------
14+
915
#ifndef LLVM_LIBC_SRC___SUPPORT_HIGH_PRECISION_DECIMAL_H
1016
#define LLVM_LIBC_SRC___SUPPORT_HIGH_PRECISION_DECIMAL_H
1117

@@ -23,6 +29,11 @@ struct LShiftTableEntry {
2329
char const *power_of_five;
2430
};
2531

32+
// -----------------------------------------------------------------------------
33+
// **** WARNING ****
34+
// This interface is shared with libc++, if you change this interface you need
35+
// to update it in both libc and libc++.
36+
// -----------------------------------------------------------------------------
2637
// This is used in both this file and in the main str_to_float.h.
2738
// TODO: Figure out where to put this.
2839
enum class RoundDirection { Up, Down, Nearest };

libc/src/__support/str_to_float.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// -----------------------------------------------------------------------------
10+
// **** WARNING ****
11+
// This file is shared with libc++. You should also be careful when adding
12+
// dependencies to this file, since it needs to build for all libc++ targets.
13+
// -----------------------------------------------------------------------------
14+
915
#ifndef LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H
1016
#define LLVM_LIBC_SRC___SUPPORT_STR_TO_FLOAT_H
1117

@@ -32,11 +38,21 @@
3238
namespace LIBC_NAMESPACE_DECL {
3339
namespace internal {
3440

41+
// -----------------------------------------------------------------------------
42+
// **** WARNING ****
43+
// This interface is shared with libc++, if you change this interface you need
44+
// to update it in both libc and libc++.
45+
// -----------------------------------------------------------------------------
3546
template <class T> struct ExpandedFloat {
3647
typename fputil::FPBits<T>::StorageType mantissa;
3748
int32_t exponent;
3849
};
3950

51+
// -----------------------------------------------------------------------------
52+
// **** WARNING ****
53+
// This interface is shared with libc++, if you change this interface you need
54+
// to update it in both libc and libc++.
55+
// -----------------------------------------------------------------------------
4056
template <class T> struct FloatConvertReturn {
4157
ExpandedFloat<T> num = {0, 0};
4258
int error = 0;
@@ -637,6 +653,11 @@ template <> LIBC_INLINE constexpr int32_t get_lower_bound<double>() {
637653
return -(309 + 15 + 20);
638654
}
639655

656+
// -----------------------------------------------------------------------------
657+
// **** WARNING ****
658+
// This interface is shared with libc++, if you change this interface you need
659+
// to update it in both libc and libc++.
660+
// -----------------------------------------------------------------------------
640661
// Takes a mantissa and base 10 exponent and converts it into its closest
641662
// floating point type T equivalient. First we try the Eisel-Lemire algorithm,
642663
// then if that fails then we fall back to a more accurate algorithm for
@@ -716,6 +737,11 @@ LIBC_INLINE FloatConvertReturn<T> decimal_exp_to_float(
716737
return output;
717738
}
718739

740+
// -----------------------------------------------------------------------------
741+
// **** WARNING ****
742+
// This interface is shared with libc++, if you change this interface you need
743+
// to update it in both libc and libc++.
744+
// -----------------------------------------------------------------------------
719745
// Takes a mantissa and base 2 exponent and converts it into its closest
720746
// floating point type T equivalient. Since the exponent is already in the right
721747
// form, this is mostly just shifting and rounding. This is used for hexadecimal

libc/src/__support/str_to_integer.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// -----------------------------------------------------------------------------
10+
// **** WARNING ****
11+
// This file is shared with libc++. You should also be careful when adding
12+
// dependencies to this file, since it needs to build for all libc++ targets.
13+
// -----------------------------------------------------------------------------
14+
915
#ifndef LLVM_LIBC_SRC___SUPPORT_STR_TO_INTEGER_H
1016
#define LLVM_LIBC_SRC___SUPPORT_STR_TO_INTEGER_H
1117

@@ -73,6 +79,11 @@ LIBC_INLINE int infer_base(const char *__restrict src, size_t src_len) {
7379
return 10;
7480
}
7581

82+
// -----------------------------------------------------------------------------
83+
// **** WARNING ****
84+
// This interface is shared with libc++, if you change this interface you need
85+
// to update it in both libc and libc++.
86+
// -----------------------------------------------------------------------------
7687
// Takes a pointer to a string and the base to convert to. This function is used
7788
// as the backend for all of the string to int functions.
7889
template <class T>

libc/src/__support/str_to_num_result.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// -----------------------------------------------------------------------------
10+
// **** WARNING ****
11+
// This file is shared with libc++. You should also be careful when adding
12+
// dependencies to this file, since it needs to build for all libc++ targets.
13+
// -----------------------------------------------------------------------------
14+
915
#ifndef LLVM_LIBC_SRC___SUPPORT_STR_TO_NUM_RESULT_H
1016
#define LLVM_LIBC_SRC___SUPPORT_STR_TO_NUM_RESULT_H
1117

@@ -16,6 +22,11 @@
1622

1723
namespace LIBC_NAMESPACE_DECL {
1824

25+
// -----------------------------------------------------------------------------
26+
// **** WARNING ****
27+
// This interface is shared with libc++, if you change this interface you need
28+
// to update it in both libc and libc++.
29+
// -----------------------------------------------------------------------------
1930
template <typename T> struct StrToNumResult {
2031
T value;
2132
int error;

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>`__","Hotel Parallelifornia: terminate() for Parallel Algorithms Exception Handling","2016-06 (Oulu)","|Complete|","17.0",""
7272
"","","","","",""
7373
"`P0003R5 <https://wg21.link/P0003R5>`__","Removing Deprecated Exception Specifications from C++17","2016-11 (Issaquah)","|Complete|","5.0",""
74-
"`P0067R5 <https://wg21.link/P0067R5>`__","Elementary string conversions, revision 5","2016-11 (Issaquah)","|Partial|","","``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``."
74+
"`P0067R5 <https://wg21.link/P0067R5>`__","Elementary string conversions, revision 5","2016-11 (Issaquah)","|Partial|","","``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``. ``std::from_chars`` for ``float`` and ``double`` since version 20.0."
7575
"`P0403R1 <https://wg21.link/P0403R1>`__","Literal suffixes for ``basic_string_view``\ ","2016-11 (Issaquah)","|Complete|","4.0",""
7676
"`P0414R2 <https://wg21.link/P0414R2>`__","Merging shared_ptr changes from Library Fundamentals to C++17","2016-11 (Issaquah)","|Complete|","11.0",""
7777
"`P0418R2 <https://wg21.link/P0418R2>`__","Fail or succeed: there is no atomic lattice","2016-11 (Issaquah)","","",""

libcxx/docs/Status/Cxx2cIssues.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,5 @@
7878
"","","","","",""
7979
"`LWG3343 <https://wg21.link/LWG3343>`__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Adopted Yet","|Complete|","16.0",""
8080
"`LWG4139 <https://wg21.link/LWG4139>`__","§[time.zone.leap] recursive constraint in <=>","Not Adopted Yet","|Complete|","20.0",""
81+
"`LWG3456 <https://wg21.link/LWG3456>`__","Pattern used by std::from_chars is underspecified (option B)",,"Not Yet Adopted","|Complete|","20.0",""
8182
"","","","","",""

0 commit comments

Comments
 (0)