Skip to content

Commit fbe296e

Browse files
michaelrj-googlemordante
authored andcommitted
[libcxx][libc] Hand in Hand PoC with from_chars
DO NOT MERGE, PROOF OF CONCEPT ONLY. This patch aims to demonstrate the utility of sharing code between libc and libc++ by using the libc float conversion code in the libc++ function from_chars. This patch adds from_chars for float and double (long double is possible but was causing errors so was skipped here), as well as a test to demonstrate that it works. This is very much just a proof of concept, not intended to be committed as-is. The from_chars code written is copied from the libc parsing code and is not functionally complete, nor does it follow the correct coding style.
1 parent 7f65377 commit fbe296e

31 files changed

+2270
-20
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

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/LWG3343>`__","Pattern used by std::from_chars is underspecified (option B)",,"Not Yet Adopted","|Complete|","20.0",""
8182
"","","","","",""

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ set(files
235235
__bit/rotate.h
236236
__bit_reference
237237
__charconv/chars_format.h
238+
__charconv/from_chars_floating_point.h
238239
__charconv/from_chars_integral.h
239240
__charconv/from_chars_result.h
240241
__charconv/tables.h
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// -*- C++ -*-
2+
//===----------------------------------------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef _LIBCPP___CHARCONV_FROM_CHARS_FLOATING_POINT_H
11+
#define _LIBCPP___CHARCONV_FROM_CHARS_FLOATING_POINT_H
12+
13+
#include <__assert>
14+
#include <__charconv/chars_format.h>
15+
#include <__charconv/from_chars_result.h>
16+
#include <__config>
17+
18+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19+
# pragma GCC system_header
20+
#endif
21+
22+
_LIBCPP_PUSH_MACROS
23+
#include <__undef_macros>
24+
25+
_LIBCPP_BEGIN_NAMESPACE_STD
26+
27+
#if _LIBCPP_STD_VER >= 17
28+
29+
_LIBCPP_EXPORTED_FROM_ABI from_chars_result
30+
__from_chars_floating_point(const char* __first, const char* __last, float& __value, chars_format __fmt);
31+
32+
_LIBCPP_EXPORTED_FROM_ABI from_chars_result
33+
__from_chars_floating_point(const char* __first, const char* __last, double& __value, chars_format __fmt);
34+
35+
_LIBCPP_AVAILABILITY_FROM_CHARS_FLOATING_POINT _LIBCPP_HIDE_FROM_ABI inline from_chars_result
36+
from_chars(const char* __first, const char* __last, float& __value, chars_format __fmt = chars_format::general) {
37+
return std::__from_chars_floating_point(__first, __last, __value, __fmt);
38+
}
39+
40+
_LIBCPP_AVAILABILITY_FROM_CHARS_FLOATING_POINT _LIBCPP_HIDE_FROM_ABI inline from_chars_result
41+
from_chars(const char* __first, const char* __last, double& __value, chars_format __fmt = chars_format::general) {
42+
return std::__from_chars_floating_point(__first, __last, __value, __fmt);
43+
}
44+
45+
#endif // _LIBCPP_STD_VER >= 17
46+
47+
_LIBCPP_END_NAMESPACE_STD
48+
49+
_LIBCPP_POP_MACROS
50+
51+
#endif // _LIBCPP___CHARCONV_FROM_CHARS_FLOATING_POINT_H

libcxx/include/__configuration/availability.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@
8787
// in all versions of the library are available.
8888
#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)
8989

90+
# define _LIBCPP_INTRODUCED_IN_LLVM_20 1
91+
# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE /* nothing */
92+
9093
# define _LIBCPP_INTRODUCED_IN_LLVM_19 1
9194
# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE /* nothing */
9295

@@ -132,6 +135,11 @@
132135

133136
// clang-format off
134137

138+
// LLVM 20
139+
// TODO: Fill this in
140+
# define _LIBCPP_INTRODUCED_IN_LLVM_20 0
141+
# define _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE __attribute__((unavailable))
142+
135143
// LLVM 19
136144
// TODO: Fill this in
137145
# define _LIBCPP_INTRODUCED_IN_LLVM_19 0
@@ -409,6 +417,11 @@
409417
#define _LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION _LIBCPP_INTRODUCED_IN_LLVM_19
410418
#define _LIBCPP_AVAILABILITY_BAD_EXPECTED_ACCESS_KEY_FUNCTION _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE
411419

420+
// This controls the availability of floating-point std::from_chars functions.
421+
// These overloads were added later than the integer overloads.
422+
#define _LIBCPP_AVAILABILITY_HAS_FROM_CHARS_FLOATING_POINT _LIBCPP_INTRODUCED_IN_LLVM_20
423+
#define _LIBCPP_AVAILABILITY_FROM_CHARS_FLOATING_POINT _LIBCPP_INTRODUCED_IN_LLVM_20_ATTRIBUTE
424+
412425
// Define availability attributes that depend on _LIBCPP_HAS_NO_EXCEPTIONS.
413426
// Those are defined in terms of the availability attributes above, and
414427
// should not be vendor-specific.

libcxx/include/charconv

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ namespace std {
6565
constexpr from_chars_result from_chars(const char* first, const char* last,
6666
see below& value, int base = 10); // constexpr since C++23
6767
68+
from_chars_result from_chars(const char* first, const char* last,
69+
float& value, chars_format fmt);
70+
71+
from_chars_result from_chars(const char* first, const char* last,
72+
double& value, chars_format fmt);
73+
6874
} // namespace std
6975
7076
*/
@@ -73,6 +79,7 @@ namespace std {
7379

7480
#if _LIBCPP_STD_VER >= 17
7581
# include <__charconv/chars_format.h>
82+
# include <__charconv/from_chars_floating_point.h>
7683
# include <__charconv/from_chars_integral.h>
7784
# include <__charconv/from_chars_result.h>
7885
# include <__charconv/tables.h>

libcxx/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,7 @@ module std [system] {
893893

894894
module charconv {
895895
module chars_format { header "__charconv/chars_format.h" }
896+
module from_chars_floating_point { header "__charconv/from_chars_floating_point.h" }
896897
module from_chars_integral { header "__charconv/from_chars_integral.h" }
897898
module from_chars_result { header "__charconv/from_chars_result.h" }
898899
module tables { header "__charconv/tables.h" }

0 commit comments

Comments
 (0)