[libcxx-commits] [libcxx] [libc++] P3391R2: `constexpr` integral overloads of `to_(w)string` (PR #205025)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jun 23 12:49:10 PDT 2026
================
@@ -3798,17 +3807,123 @@ stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI double stod(const wstring& __str, size_t* __idx = nullptr);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr);
+# if _LIBCPP_STD_VER < 26 || defined(_LIBCPP_PREFERRED_OVERLOAD)
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val);
+# endif // _LIBCPP_STD_VER < 26 || defined(_LIBCPP_PREFERRED_OVERLOAD)
+
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val);
[[__nodiscard__]] _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val);
# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+# if _LIBCPP_STD_VER >= 26
+
+// Note: _LIBCPP_ALWAYS_INLINE is used for generating direct invocations to dylib versions for Clang,
+// which avoids code size regression in C++26.
+
+template <class _String, class _Integer>
+constexpr _String __integer_to_string(_Integer __val) {
+ // numeric_limits::digits10 returns value less on 1 than desired for unsigned numbers.
+ // For example, for 1-byte unsigned value digits10 is 2 (999 can not be represented), so we need +1 here.
+ constexpr size_t __buf_size = numeric_limits<_Integer>::digits10 + 2; // +1 for minus, +1 for digits10
+ char __buf[__buf_size];
+ const auto [__ptr, __ec] = std::to_chars(__buf, __buf + __buf_size, __val);
+ _LIBCPP_ASSERT_INTERNAL(__ec == errc(), "__buf_size must be large enough to accommodate the value");
+ return _String(__buf, __ptr);
+}
+
+template <class _Integer>
+_LIBCPP_ALWAYS_INLINE constexpr string __to_string(_Integer __val) {
+# ifdef _LIBCPP_PREFERRED_OVERLOAD
+ if !consteval {
+ return std::to_string(__val);
+ } else
+# endif // _LIBCPP_PREFERRED_OVERLOAD
+ {
+ return std::__integer_to_string<string>(__val);
+ }
+}
+
+# if _LIBCPP_HAS_WIDE_CHARACTERS
+template <class _Integer>
+_LIBCPP_ALWAYS_INLINE constexpr wstring __to_wstring(_Integer __val) {
+# ifdef _LIBCPP_PREFERRED_OVERLOAD
+ if !consteval {
+ return std::to_wstring(__val);
+ } else
+# endif // _LIBCPP_PREFERRED_OVERLOAD
+ {
+ return std::__integer_to_string<wstring>(__val);
+ }
+}
+# endif // _LIBCPP_HAS_WIDE_CHARACTERS
+
+inline namespace __cpp26 {
----------------
philnik777 wrote:
Yeah, I forgot MSVC doesn't support ABI tags. If we need the namespace we should just use it everywhere - it doesn't really save us much to not have it on some platforms.
https://github.com/llvm/llvm-project/pull/205025
More information about the libcxx-commits
mailing list