[libcxx-commits] [libcxx] 3489ea3 - [libcxx][locale] Refactor strtonum functions using __str_to_float_c_locale<FloatT> (#222081)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Sep 24 21:21:22 PDT 2026


Author: Himadhith
Date: 2026-09-25T09:51:14+05:30
New Revision: 3489ea3b567c719f497bfcf83348e27cfd79cdb7

URL: https://github.com/llvm/llvm-project/commit/3489ea3b567c719f497bfcf83348e27cfd79cdb7
DIFF: https://github.com/llvm/llvm-project/commit/3489ea3b567c719f497bfcf83348e27cfd79cdb7.diff

LOG: [libcxx][locale] Refactor strtonum functions using __str_to_float_c_locale<FloatT> (#222081)

Replace the 3 separate functions `__strtof`, `__strtod` and `__strtold`
with a single template `__str_to_float_c_locale<FloatT>` across
locale_base_api and all platform support headers. Since
`__str_to_float_c_locale<FloatT>` now does not need `__get_c_locale`
argument we can directly call it instead of `__do_strtod`.

This removes `__setAndRestore` from `aix.h` entirely as `__locale_guard`
is now used directly in the template specialisations to switch locales.
`num.h` is updated to call `__locale::__str_to_float_c_locale<T>`
uniformly across the 3 separate `__do_strtod` specialisation calls.

Additionally,
- linux.h, bsd_like.h, newlib.h delegate to the platform's native
`strtof_l`/`strtod_l`/`strtold_l`.
- openbsd.h, no_locale/strtonum.h call bare `strtof`, `strtod` and
`strtold` (no locale needed).
- windows.h, locale_win32.cpp's MSVCRT path inlines the 3 functions and
the non-MSVCRT path exports explicit specialisations from the library.
- Changes `__locale_guard` to take `__locale_t` by value now by removing
`&`.
- Forward declared the `__get_c_locale()` function as it's being used
well before the include.

---------

Co-authored-by: himadhith <himadhith.v at ibm.com>

Added: 
    

Modified: 
    libcxx/include/__locale_dir/locale_base_api.h
    libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
    libcxx/include/__locale_dir/num.h
    libcxx/include/__locale_dir/support/aix.h
    libcxx/include/__locale_dir/support/bsd_like.h
    libcxx/include/__locale_dir/support/fuchsia.h
    libcxx/include/__locale_dir/support/linux.h
    libcxx/include/__locale_dir/support/newlib.h
    libcxx/include/__locale_dir/support/no_locale/strtonum.h
    libcxx/include/__locale_dir/support/openbsd.h
    libcxx/include/__locale_dir/support/windows.h
    libcxx/src/support/win32/locale_win32.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h
index 14ff9d8a45b565..91bd9cfd6d0b75 100644
--- a/libcxx/include/__locale_dir/locale_base_api.h
+++ b/libcxx/include/__locale_dir/locale_base_api.h
@@ -54,9 +54,8 @@
 // ------------------
 // namespace __locale {
 //  // required by the headers
-//  float               __strtof(const char*, char**, __locale_t);
-//  double              __strtod(const char*, char**, __locale_t);
-//  long double         __strtold(const char*, char**, __locale_t);
+//  template <class FloatT>
+//  FloatT __str_to_float_c_locale(const char*, char**);
 // }
 //
 // Character manipulation functions
@@ -166,6 +165,9 @@ namespace __locale {
 
 using __locale_t _LIBCPP_NODEBUG = locale_t;
 
+// Forward declared for use below.
+inline __locale_t __get_c_locale();
+
 #    if defined(_LIBCPP_BUILDING_LIBRARY)
 using __lconv_t _LIBCPP_NODEBUG = lconv;
 
@@ -185,16 +187,22 @@ inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) { return
 //
 // Strtonum functions
 //
-inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return strtof_l(__nptr, __endptr, __loc);
+template <class _FloatT>
+_LIBCPP_HIDE_FROM_ABI _FloatT __str_to_float_c_locale(const char* __nptr, char** __endptr);
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI float __str_to_float_c_locale<float>(const char* __nptr, char** __endptr) {
+  return strtof_l(__nptr, __endptr, __get_c_locale());
 }
 
-inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return strtod_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __str_to_float_c_locale<double>(const char* __nptr, char** __endptr) {
+  return strtod_l(__nptr, __endptr, __get_c_locale());
 }
 
-inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return strtold_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __str_to_float_c_locale<long double>(const char* __nptr, char** __endptr) {
+  return strtold_l(__nptr, __endptr, __get_c_locale());
 }
 
 //
@@ -306,6 +314,8 @@ _LIBCPP_DIAGNOSTIC_POP
 } // namespace __locale
 _LIBCPP_END_NAMESPACE_STD
 
+#    include <__locale_dir/support/default/get_c_locale.h>
+
 #  endif // Compatibility definition of locale base APIs
 
 #endif // _LIBCPP_HAS_LOCALIZATION

diff  --git a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
index 8cdbe0cd15051c..973bbfd0f6cebd 100644
--- a/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
+++ b/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h
@@ -29,7 +29,7 @@
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 struct __locale_guard {
-  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
+  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t __loc) : __old_loc_(::uselocale(__loc)) {}
 
   _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
     if (__old_loc_)

diff  --git a/libcxx/include/__locale_dir/num.h b/libcxx/include/__locale_dir/num.h
index e924c88d0955c9..6774903aa00693 100644
--- a/libcxx/include/__locale_dir/num.h
+++ b/libcxx/include/__locale_dir/num.h
@@ -301,31 +301,13 @@ extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<char>;
 extern template struct _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS __num_get<wchar_t>;
 #  endif
 
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _Tp __do_strtod(const char* __a, char** __p2);
-
-template <>
-inline _LIBCPP_HIDE_FROM_ABI float __do_strtod<float>(const char* __a, char** __p2) {
-  return __locale::__strtof(__a, __p2, __locale::__get_c_locale());
-}
-
-template <>
-inline _LIBCPP_HIDE_FROM_ABI double __do_strtod<double>(const char* __a, char** __p2) {
-  return __locale::__strtod(__a, __p2, __locale::__get_c_locale());
-}
-
-template <>
-inline _LIBCPP_HIDE_FROM_ABI long double __do_strtod<long double>(const char* __a, char** __p2) {
-  return __locale::__strtold(__a, __p2, __locale::__get_c_locale());
-}
-
 template <class _Tp>
 _LIBCPP_HIDE_FROM_ABI _Tp __num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) {
   if (__a != __a_end) {
     __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
     errno                                                     = 0;
     char* __p2;
-    _Tp __ld                                                     = std::__do_strtod<_Tp>(__a, &__p2);
+    _Tp __ld                                                     = __locale::__str_to_float_c_locale<_Tp>(__a, &__p2);
     __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
     if (__current_errno == 0)
       errno = __save_errno;

diff  --git a/libcxx/include/__locale_dir/support/aix.h b/libcxx/include/__locale_dir/support/aix.h
index d5c2b395b1a37e..17f095ac6ce424 100644
--- a/libcxx/include/__locale_dir/support/aix.h
+++ b/libcxx/include/__locale_dir/support/aix.h
@@ -33,7 +33,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __locale {
 
 struct __locale_guard {
-  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
+  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t __loc) : __old_loc_(::uselocale(__loc)) {}
 
   _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
     if (__old_loc_)
@@ -63,6 +63,9 @@ inline _LIBCPP_HIDE_FROM_ABI decltype(MB_CUR_MAX) __mb_cur_max() { return MB_CUR
 
 using __locale_t _LIBCPP_NODEBUG = ::locale_t;
 
+// Forward declared for use below.
+inline __locale_t __get_c_locale();
+
 #if defined(_LIBCPP_BUILDING_LIBRARY)
 using __lconv_t _LIBCPP_NODEBUG = std::lconv;
 
@@ -86,44 +89,27 @@ inline _LIBCPP_HIDE_FROM_ABI const char* __get_locale_encoding(__locale_t __loc)
 }
 #endif // _LIBCPP_BUILDING_LIBRARY
 
-// The following structure is a quick-and-dirty workaround for routines that AIX
-// does not provide in the "_l" (locale-aware) variants.
-struct __setAndRestore {
-  explicit __setAndRestore(locale_t locale) {
-    if (locale == (locale_t)0) {
-      __cloc   = newlocale(LC_ALL_MASK, "C", /* base */ (locale_t)0);
-      __stored = uselocale(__cloc);
-    } else {
-      __stored = uselocale(locale);
-    }
-  }
-
-  ~__setAndRestore() {
-    uselocale(__stored);
-    if (__cloc)
-      freelocale(__cloc);
-  }
-
-private:
-  locale_t __stored = (locale_t)0;
-  locale_t __cloc   = (locale_t)0;
-};
-
 //
 // Strtonum functions
 //
-inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
-  __setAndRestore __newloc(__loc);
+template <class _FloatT>
+_LIBCPP_HIDE_FROM_ABI _FloatT __str_to_float_c_locale(const char* __nptr, char** __endptr);
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI float __str_to_float_c_locale<float>(const char* __nptr, char** __endptr) {
+  __locale_guard __current(__get_c_locale());
   return ::strtof(__nptr, __endptr);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
-  __setAndRestore __newloc(__loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __str_to_float_c_locale<double>(const char* __nptr, char** __endptr) {
+  __locale_guard __current(__get_c_locale());
   return ::strtod(__nptr, __endptr);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
-  __setAndRestore __newloc(__loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __str_to_float_c_locale<long double>(const char* __nptr, char** __endptr) {
+  __locale_guard __current(__get_c_locale());
   return ::strtold(__nptr, __endptr);
 }
 

diff  --git a/libcxx/include/__locale_dir/support/bsd_like.h b/libcxx/include/__locale_dir/support/bsd_like.h
index ebe3f726e34ffc..63a385dfdc008e 100644
--- a/libcxx/include/__locale_dir/support/bsd_like.h
+++ b/libcxx/include/__locale_dir/support/bsd_like.h
@@ -78,16 +78,22 @@ inline __locale_t __get_c_locale() {
 //
 // Strtonum functions
 //
-inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtof_l(__nptr, __endptr, __loc);
+template <class _FloatT>
+_LIBCPP_HIDE_FROM_ABI _FloatT __str_to_float_c_locale(const char* __nptr, char** __endptr);
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI float __str_to_float_c_locale<float>(const char* __nptr, char** __endptr) {
+  return ::strtof_l(__nptr, __endptr, __get_c_locale());
 }
 
-inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtod_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __str_to_float_c_locale<double>(const char* __nptr, char** __endptr) {
+  return ::strtod_l(__nptr, __endptr, __get_c_locale());
 }
 
-inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtold_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __str_to_float_c_locale<long double>(const char* __nptr, char** __endptr) {
+  return ::strtold_l(__nptr, __endptr, __get_c_locale());
 }
 
 //

diff  --git a/libcxx/include/__locale_dir/support/fuchsia.h b/libcxx/include/__locale_dir/support/fuchsia.h
index 0b4c2681080327..f95ecbbb2e8303 100644
--- a/libcxx/include/__locale_dir/support/fuchsia.h
+++ b/libcxx/include/__locale_dir/support/fuchsia.h
@@ -25,7 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __locale {
 
 struct __locale_guard {
-  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
+  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t __loc) : __old_loc_(::uselocale(__loc)) {}
 
   _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
     if (__old_loc_)

diff  --git a/libcxx/include/__locale_dir/support/linux.h b/libcxx/include/__locale_dir/support/linux.h
index 8d20bbe9180c4f..01f184c56ebe55 100644
--- a/libcxx/include/__locale_dir/support/linux.h
+++ b/libcxx/include/__locale_dir/support/linux.h
@@ -36,7 +36,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __locale {
 
 struct __locale_guard {
-  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
+  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t __loc) : __old_loc_(::uselocale(__loc)) {}
 
   _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
     if (__old_loc_)
@@ -63,6 +63,9 @@ struct __locale_guard {
 
 using __locale_t _LIBCPP_NODEBUG = ::locale_t;
 
+// Forward declared for use below.
+inline __locale_t __get_c_locale();
+
 #if defined(_LIBCPP_BUILDING_LIBRARY)
 using __lconv_t _LIBCPP_NODEBUG = std::lconv;
 
@@ -85,16 +88,22 @@ inline _LIBCPP_HIDE_FROM_ABI __lconv_t* __localeconv(__locale_t& __loc) {
 //
 // Strtonum functions
 //
-inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtof_l(__nptr, __endptr, __loc);
+template <class _FloatT>
+_LIBCPP_HIDE_FROM_ABI _FloatT __str_to_float_c_locale(const char* __nptr, char** __endptr);
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI float __str_to_float_c_locale<float>(const char* __nptr, char** __endptr) {
+  return ::strtof_l(__nptr, __endptr, __get_c_locale());
 }
 
-inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtod_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __str_to_float_c_locale<double>(const char* __nptr, char** __endptr) {
+  return ::strtod_l(__nptr, __endptr, __get_c_locale());
 }
 
-inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtold_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __str_to_float_c_locale<long double>(const char* __nptr, char** __endptr) {
+  return ::strtold_l(__nptr, __endptr, __get_c_locale());
 }
 
 //

diff  --git a/libcxx/include/__locale_dir/support/newlib.h b/libcxx/include/__locale_dir/support/newlib.h
index daf60e8a48ea26..6b72454e79a54d 100644
--- a/libcxx/include/__locale_dir/support/newlib.h
+++ b/libcxx/include/__locale_dir/support/newlib.h
@@ -33,7 +33,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __locale {
 
 struct __locale_guard {
-  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
+  _LIBCPP_HIDE_FROM_ABI __locale_guard(locale_t __loc) : __old_loc_(::uselocale(__loc)) {}
 
   _LIBCPP_HIDE_FROM_ABI ~__locale_guard() {
     if (__old_loc_)
@@ -60,6 +60,9 @@ struct __locale_guard {
 
 using __locale_t _LIBCPP_NODEBUG = ::locale_t;
 
+// Forward declared for use below.
+inline __locale_t __get_c_locale();
+
 #if defined(_LIBCPP_BUILDING_LIBRARY)
 using __lconv_t _LIBCPP_NODEBUG = std::lconv;
 
@@ -86,16 +89,22 @@ inline _LIBCPP_HIDE_FROM_ABI const char* __get_locale_encoding(__locale_t __loc)
 //
 // Strtonum functions
 //
-inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtof_l(__nptr, __endptr, __loc);
+template <class _FloatT>
+_LIBCPP_HIDE_FROM_ABI _FloatT __str_to_float_c_locale(const char* __nptr, char** __endptr);
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI float __str_to_float_c_locale<float>(const char* __nptr, char** __endptr) {
+  return ::strtof_l(__nptr, __endptr, __get_c_locale());
 }
 
-inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtod_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __str_to_float_c_locale<double>(const char* __nptr, char** __endptr) {
+  return ::strtod_l(__nptr, __endptr, __get_c_locale());
 }
 
-inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::strtold_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __str_to_float_c_locale<long double>(const char* __nptr, char** __endptr) {
+  return ::strtold_l(__nptr, __endptr, __get_c_locale());
 }
 
 //

diff  --git a/libcxx/include/__locale_dir/support/no_locale/strtonum.h b/libcxx/include/__locale_dir/support/no_locale/strtonum.h
index 59544e10e4a4c0..9b8e1b3b105566 100644
--- a/libcxx/include/__locale_dir/support/no_locale/strtonum.h
+++ b/libcxx/include/__locale_dir/support/no_locale/strtonum.h
@@ -22,15 +22,21 @@ namespace __locale {
 //
 // Strtonum functions
 //
-inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t) {
+template <class _FloatT>
+_LIBCPP_HIDE_FROM_ABI _FloatT __str_to_float_c_locale(const char* __nptr, char** __endptr);
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI float __str_to_float_c_locale<float>(const char* __nptr, char** __endptr) {
   return std::strtof(__nptr, __endptr);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t) {
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __str_to_float_c_locale<double>(const char* __nptr, char** __endptr) {
   return std::strtod(__nptr, __endptr);
 }
 
-inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t) {
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __str_to_float_c_locale<long double>(const char* __nptr, char** __endptr) {
   return std::strtold(__nptr, __endptr);
 }
 

diff  --git a/libcxx/include/__locale_dir/support/openbsd.h b/libcxx/include/__locale_dir/support/openbsd.h
index 85f008f8a17f07..369b8e652689be 100644
--- a/libcxx/include/__locale_dir/support/openbsd.h
+++ b/libcxx/include/__locale_dir/support/openbsd.h
@@ -33,7 +33,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace __locale {
 
 struct __locale_guard {
-  __locale_guard(locale_t& __loc) : __old_loc_(::uselocale(__loc)) {}
+  __locale_guard(locale_t __loc) : __old_loc_(::uselocale(__loc)) {}
 
   ~__locale_guard() {
     if (__old_loc_)
@@ -79,11 +79,23 @@ inline __lconv_t* __localeconv(__locale_t& __loc) {
 //
 // Strtonum functions
 //
-inline float __strtof(const char* __nptr, char** __endptr, __locale_t) { return ::strtof(__nptr, __endptr); }
+template <class _FloatT>
+_LIBCPP_HIDE_FROM_ABI _FloatT __str_to_float_c_locale(const char* __nptr, char** __endptr);
 
-inline double __strtod(const char* __nptr, char** __endptr, __locale_t) { return ::strtod(__nptr, __endptr); }
+template <>
+inline _LIBCPP_HIDE_FROM_ABI float __str_to_float_c_locale<float>(const char* __nptr, char** __endptr) {
+  return ::strtof(__nptr, __endptr);
+}
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __str_to_float_c_locale<double>(const char* __nptr, char** __endptr) {
+  return ::strtod(__nptr, __endptr);
+}
 
-inline long double __strtold(const char* __nptr, char** __endptr, __locale_t) { return ::strtold(__nptr, __endptr); }
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __str_to_float_c_locale<long double>(const char* __nptr, char** __endptr) {
+  return ::strtold(__nptr, __endptr);
+}
 
 //
 // Character manipulation functions

diff  --git a/libcxx/include/__locale_dir/support/windows.h b/libcxx/include/__locale_dir/support/windows.h
index 5f35d089ac1fcf..e4a030c72e701b 100644
--- a/libcxx/include/__locale_dir/support/windows.h
+++ b/libcxx/include/__locale_dir/support/windows.h
@@ -154,6 +154,9 @@ class __locale_t {
   __lconv_storage* __lc_ = nullptr;
 };
 
+// Forward declared for use below.
+inline _LIBCPP_HIDE_FROM_ABI __locale_t __get_c_locale();
+
 #if defined(_LIBCPP_BUILDING_LIBRARY)
 _LIBCPP_EXPORTED_FROM_ABI __locale_t __newlocale(int __mask, const char* __locale, __locale_t __base);
 inline _LIBCPP_HIDE_FROM_ABI void __freelocale(__locale_t __loc) { ::_free_locale(__loc); }
@@ -172,20 +175,30 @@ _LIBCPP_EXPORTED_FROM_ABI const char* __get_locale_encoding(__locale_t __loc);
 //
 
 // the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+
+template <class _FloatT>
+_LIBCPP_HIDE_FROM_ABI _FloatT __str_to_float_c_locale(const char* __nptr, char** __endptr);
 #if defined(_LIBCPP_MSVCRT)
-inline _LIBCPP_HIDE_FROM_ABI float __strtof(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::_strtof_l(__nptr, __endptr, __loc);
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI float __str_to_float_c_locale<float>(const char* __nptr, char** __endptr) {
+  return ::_strtof_l(__nptr, __endptr, __get_c_locale());
 }
-inline _LIBCPP_HIDE_FROM_ABI long double __strtold(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::_strtold_l(__nptr, __endptr, __loc);
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __str_to_float_c_locale<long double>(const char* __nptr, char** __endptr) {
+  return ::_strtold_l(__nptr, __endptr, __get_c_locale());
 }
 #else
-_LIBCPP_EXPORTED_FROM_ABI float __strtof(const char*, char**, __locale_t);
-_LIBCPP_EXPORTED_FROM_ABI long double __strtold(const char*, char**, __locale_t);
+template <>
+_LIBCPP_EXPORTED_FROM_ABI float __str_to_float_c_locale<float>(const char*, char**);
+
+template <>
+_LIBCPP_EXPORTED_FROM_ABI long double __str_to_float_c_locale<long double>(const char*, char**);
 #endif
 
-inline _LIBCPP_HIDE_FROM_ABI double __strtod(const char* __nptr, char** __endptr, __locale_t __loc) {
-  return ::_strtod_l(__nptr, __endptr, __loc);
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __str_to_float_c_locale<double>(const char* __nptr, char** __endptr) {
+  return ::_strtod_l(__nptr, __endptr, __get_c_locale());
 }
 
 //

diff  --git a/libcxx/src/support/win32/locale_win32.cpp b/libcxx/src/support/win32/locale_win32.cpp
index c5117564438a5c..a09f219e7f1bd4 100644
--- a/libcxx/src/support/win32/locale_win32.cpp
+++ b/libcxx/src/support/win32/locale_win32.cpp
@@ -299,13 +299,15 @@ const char* __get_locale_encoding(__locale_t loc) {
 // Strtonum functions
 //
 #if !defined(_LIBCPP_MSVCRT)
-float __strtof(const char* nptr, char** endptr, __locale_t loc) {
-  __locale_guard __current(loc);
+template <>
+float __str_to_float_c_locale<float>(const char* nptr, char** endptr) {
+  __locale_guard __current(__get_c_locale());
   return std::strtof(nptr, endptr);
 }
 
-long double __strtold(const char* nptr, char** endptr, __locale_t loc) {
-  __locale_guard __current(loc);
+template <>
+long double __str_to_float_c_locale<long double>(const char* nptr, char** endptr) {
+  __locale_guard __current(__get_c_locale());
   return std::strtold(nptr, endptr);
 }
 #endif


        


More information about the libcxx-commits mailing list