[libcxx-commits] [libcxx] [libc++] Remove _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS (PR #111964)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Nov 17 03:16:58 PST 2024


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/111964

>From e7e57a9e17a503a149e03f5eb3d0d8ee6a463c19 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Fri, 11 Oct 2024 10:21:54 +0200
Subject: [PATCH] [libc++] Remove
 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS

---
 libcxx/.clang-format                          |   1 -
 libcxx/docs/DesignDocs/VisibilityMacros.rst   |  29 -
 .../__condition_variable/condition_variable.h | 184 +++---
 libcxx/include/__config                       |   8 -
 libcxx/include/__locale                       |  32 +-
 libcxx/include/__thread/thread.h              | 127 ++---
 libcxx/include/condition_variable             |  66 +--
 libcxx/include/future                         |  48 +-
 libcxx/include/locale                         | 527 +++++++++---------
 libcxx/include/mutex                          |  76 ++-
 libcxx/include/shared_mutex                   | 100 ++--
 libcxx/include/string                         | 404 +++++---------
 12 files changed, 695 insertions(+), 907 deletions(-)

diff --git a/libcxx/.clang-format b/libcxx/.clang-format
index f548119652c19a..0d9b2806987d94 100644
--- a/libcxx/.clang-format
+++ b/libcxx/.clang-format
@@ -38,7 +38,6 @@ AttributeMacros: [
                   '_LIBCPP_HIDDEN',
                   '_LIBCPP_HIDE_FROM_ABI_AFTER_V1',
                   '_LIBCPP_HIDE_FROM_ABI',
-                  '_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS',
                   '_LIBCPP_NO_SANITIZE',
                   '_LIBCPP_NO_UNIQUE_ADDRESS',
                   '_LIBCPP_NOALIAS',
diff --git a/libcxx/docs/DesignDocs/VisibilityMacros.rst b/libcxx/docs/DesignDocs/VisibilityMacros.rst
index 83a9a62942bc97..e37e712014c080 100644
--- a/libcxx/docs/DesignDocs/VisibilityMacros.rst
+++ b/libcxx/docs/DesignDocs/VisibilityMacros.rst
@@ -105,35 +105,6 @@ Visibility Macros
   the extern template declaration) as exported on Windows, as discussed above.
   On all other platforms, this macro has an empty definition.
 
-**_LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS**
-  Mark a symbol as hidden so it will not be exported from shared libraries. This
-  is intended specifically for method templates of either classes marked with
-  `_LIBCPP_TYPE_VIS` or classes with an extern template instantiation
-  declaration marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS`.
-
-  When building libc++ with hidden visibility, we want explicit template
-  instantiations to export members, which is consistent with existing Windows
-  behavior. We also want classes annotated with `_LIBCPP_TYPE_VIS` to export
-  their members, which is again consistent with existing Windows behavior.
-  Both these changes are necessary for clients to be able to link against a
-  libc++ DSO built with hidden visibility without encountering missing symbols.
-
-  An unfortunate side effect, however, is that method templates of classes
-  either marked `_LIBCPP_TYPE_VIS` or with extern template instantiation
-  declarations marked with `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` also get default
-  visibility when instantiated. These methods are often implicitly instantiated
-  inside other libraries which use the libc++ headers, and will therefore end up
-  being exported from those libraries, since those implicit instantiations will
-  receive default visibility. This is not acceptable for libraries that wish to
-  control their visibility, and led to PR30642.
-
-  Consequently, all such problematic method templates are explicitly marked
-  either hidden (via this macro) or inline, so that they don't leak into client
-  libraries. The problematic methods were found by running
-  `bad-visibility-finder <https://github.com/smeenai/bad-visibility-finder>`_
-  against the libc++ headers after making `_LIBCPP_TYPE_VIS` and
-  `_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS` expand to default visibility.
-
 Links
 =====
 
diff --git a/libcxx/include/__condition_variable/condition_variable.h b/libcxx/include/__condition_variable/condition_variable.h
index 4521fe274614ef..5215bdc2b879c5 100644
--- a/libcxx/include/__condition_variable/condition_variable.h
+++ b/libcxx/include/__condition_variable/condition_variable.h
@@ -39,60 +39,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 _LIBCPP_DECLARE_STRONG_ENUM(cv_status){no_timeout, timeout};
 _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
 
-class _LIBCPP_EXPORTED_FROM_ABI condition_variable {
-  __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
-
-public:
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
-
-#  if _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
-  ~condition_variable() = default;
-#  else
-  ~condition_variable();
-#  endif
-
-  condition_variable(const condition_variable&)            = delete;
-  condition_variable& operator=(const condition_variable&) = delete;
-
-  void notify_one() _NOEXCEPT;
-  void notify_all() _NOEXCEPT;
-
-  void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
-  template <class _Predicate>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS void wait(unique_lock<mutex>& __lk, _Predicate __pred);
-
-  template <class _Clock, class _Duration>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
-  wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t);
-
-  template <class _Clock, class _Duration, class _Predicate>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
-  wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred);
-
-  template <class _Rep, class _Period>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
-  wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d);
-
-  template <class _Rep, class _Period, class _Predicate>
-  bool _LIBCPP_HIDE_FROM_ABI
-  wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
-
-  typedef __libcpp_condvar_t* native_handle_type;
-  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
-
-private:
-  void
-  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
-#  if _LIBCPP_HAS_COND_CLOCKWAIT
-  _LIBCPP_HIDE_FROM_ABI void
-  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
-#  endif
-  template <class _Clock>
-  _LIBCPP_HIDE_FROM_ABI void
-  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
-};
-#endif // _LIBCPP_HAS_THREADS
-
 template <class _Rep, class _Period, __enable_if_t<is_floating_point<_Rep>::value, int> = 0>
 inline _LIBCPP_HIDE_FROM_ABI chrono::nanoseconds __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) {
   using namespace chrono;
@@ -140,64 +86,106 @@ inline _LIBCPP_HIDE_FROM_ABI chrono::nanoseconds __safe_nanosecond_cast(chrono::
   return nanoseconds(__result);
 }
 
-#if _LIBCPP_HAS_THREADS
-template <class _Predicate>
-void condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred) {
-  while (!__pred())
-    wait(__lk);
-}
+class _LIBCPP_EXPORTED_FROM_ABI condition_variable {
+  __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER;
 
-template <class _Clock, class _Duration>
-cv_status condition_variable::wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t) {
-  using namespace chrono;
-  using __clock_tp_ns = time_point<_Clock, nanoseconds>;
+public:
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default;
 
-  typename _Clock::time_point __now = _Clock::now();
-  if (__t <= __now)
-    return cv_status::timeout;
+#  if _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION
+  ~condition_variable() = default;
+#  else
+  ~condition_variable();
+#  endif
 
-  __clock_tp_ns __t_ns = __clock_tp_ns(std::__safe_nanosecond_cast(__t.time_since_epoch()));
+  condition_variable(const condition_variable&)            = delete;
+  condition_variable& operator=(const condition_variable&) = delete;
 
-  __do_timed_wait(__lk, __t_ns);
-  return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
-}
+  void notify_one() _NOEXCEPT;
+  void notify_all() _NOEXCEPT;
+
+  void wait(unique_lock<mutex>& __lk) _NOEXCEPT;
 
-template <class _Clock, class _Duration, class _Predicate>
-bool condition_variable::wait_until(
-    unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred) {
-  while (!__pred()) {
-    if (wait_until(__lk, __t) == cv_status::timeout)
-      return __pred();
+  template <class _Predicate>
+  _LIBCPP_HIDE_FROM_ABI void wait(unique_lock<mutex>& __lk, _Predicate __pred) {
+    while (!__pred())
+      wait(__lk);
   }
-  return true;
-}
 
-template <class _Rep, class _Period>
-cv_status condition_variable::wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d) {
-  using namespace chrono;
-  if (__d <= __d.zero())
-    return cv_status::timeout;
-  using __ns_rep                   = nanoseconds::rep;
-  steady_clock::time_point __c_now = steady_clock::now();
+  template <class _Clock, class _Duration>
+  _LIBCPP_HIDE_FROM_ABI cv_status
+  wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t) {
+    using namespace chrono;
+    using __clock_tp_ns = time_point<_Clock, nanoseconds>;
 
-#  if _LIBCPP_HAS_COND_CLOCKWAIT
-  using __clock_tp_ns     = time_point<steady_clock, nanoseconds>;
-  __ns_rep __now_count_ns = std::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
+    typename _Clock::time_point __now = _Clock::now();
+    if (__t <= __now)
+      return cv_status::timeout;
+
+    __clock_tp_ns __t_ns = __clock_tp_ns(std::__safe_nanosecond_cast(__t.time_since_epoch()));
+
+    __do_timed_wait(__lk, __t_ns);
+    return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
+  }
+
+  template <class _Clock, class _Duration, class _Predicate>
+  _LIBCPP_HIDE_FROM_ABI bool
+  wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred) {
+    while (!__pred()) {
+      if (wait_until(__lk, __t) == cv_status::timeout)
+        return __pred();
+    }
+    return true;
+  }
+
+  template <class _Rep, class _Period>
+  _LIBCPP_HIDE_FROM_ABI cv_status wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d) {
+    using namespace chrono;
+    if (__d <= __d.zero())
+      return cv_status::timeout;
+    using __ns_rep                   = nanoseconds::rep;
+    steady_clock::time_point __c_now = steady_clock::now();
+
+#  if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
+    using __clock_tp_ns     = time_point<steady_clock, nanoseconds>;
+    __ns_rep __now_count_ns = std::__safe_nanosecond_cast(__c_now.time_since_epoch()).count();
 #  else
-  using __clock_tp_ns     = time_point<system_clock, nanoseconds>;
-  __ns_rep __now_count_ns = std::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
+    using __clock_tp_ns     = time_point<system_clock, nanoseconds>;
+    __ns_rep __now_count_ns = std::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count();
 #  endif
 
-  __ns_rep __d_ns_count = std::__safe_nanosecond_cast(__d).count();
+    __ns_rep __d_ns_count = std::__safe_nanosecond_cast(__d).count();
 
-  if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
-    __do_timed_wait(__lk, __clock_tp_ns::max());
-  } else {
-    __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
+    if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) {
+      __do_timed_wait(__lk, __clock_tp_ns::max());
+    } else {
+      __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count)));
+    }
+
+    return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : cv_status::timeout;
   }
 
-  return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : cv_status::timeout;
-}
+  template <class _Rep, class _Period, class _Predicate>
+  bool _LIBCPP_HIDE_FROM_ABI
+  wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred);
+
+  typedef __libcpp_condvar_t* native_handle_type;
+  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; }
+
+private:
+  void
+  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
+#  if defined(_LIBCPP_HAS_COND_CLOCKWAIT)
+  _LIBCPP_HIDE_FROM_ABI void
+  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT;
+#  endif
+  template <class _Clock>
+  _LIBCPP_HIDE_FROM_ABI void
+  __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT;
+};
+#endif // !_LIBCPP_HAS_NO_THREADS
+
+#ifndef _LIBCPP_HAS_NO_THREADS
 
 template <class _Rep, class _Period, class _Predicate>
 inline bool
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 9db00cd0c9fb93..408a4695723f77 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -384,7 +384,6 @@ typedef __char32_t char32_t;
 #    endif
 
 #    define _LIBCPP_HIDDEN
-#    define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
 #    define _LIBCPP_TEMPLATE_VIS
 #    define _LIBCPP_TEMPLATE_DATA_VIS
 #    define _LIBCPP_TYPE_VISIBILITY_DEFAULT
@@ -404,13 +403,6 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS
 #    define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_VISIBILITY("default")
 
-#    if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
-// The inline should be removed once PR32114 is resolved
-#      define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN
-#    else
-#      define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-#    endif
-
 // GCC doesn't support the type_visibility attribute, so we have to keep the visibility attribute on templates
 #    if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && !__has_attribute(__type_visibility__)
 #      define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default")))
diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index b675e01bac81e5..fb5df4ab610a0e 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -41,6 +41,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 class _LIBCPP_EXPORTED_FROM_ABI locale;
 
+template <class _CharT>
+class collate;
+
 template <class _Facet>
 _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale&) _NOEXCEPT;
 
@@ -79,7 +82,12 @@ public:
   const locale& operator=(const locale&) _NOEXCEPT;
 
   template <class _Facet>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS locale combine(const locale&) const;
+  _LIBCPP_HIDE_FROM_ABI locale combine(const locale& __other) const {
+    if (!std::has_facet<_Facet>(__other))
+      __throw_runtime_error("locale::combine: locale missing facet");
+
+    return locale(*this, &const_cast<_Facet&>(std::use_facet<_Facet>(__other)));
+  }
 
   // locale operations:
   string name() const;
@@ -88,8 +96,11 @@ public:
   _LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const { return !(*this == __y); }
 #endif
   template <class _CharT, class _Traits, class _Allocator>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
-  operator()(const basic_string<_CharT, _Traits, _Allocator>&, const basic_string<_CharT, _Traits, _Allocator>&) const;
+  _LIBCPP_HIDE_FROM_ABI bool operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
+                                        const basic_string<_CharT, _Traits, _Allocator>& __y) const {
+    return std::use_facet<std::collate<_CharT> >(*this).compare(
+               __x.data(), __x.data() + __x.size(), __y.data(), __y.data() + __y.size()) < 0;
+  }
 
   // global locale objects:
   static locale global(const locale&);
@@ -150,14 +161,6 @@ inline _LIBCPP_HIDE_FROM_ABI locale::locale(const locale& __other, _Facet* __f)
   __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
 }
 
-template <class _Facet>
-locale locale::combine(const locale& __other) const {
-  if (!std::has_facet<_Facet>(__other))
-    __throw_runtime_error("locale::combine: locale missing facet");
-
-  return locale(*this, &const_cast<_Facet&>(std::use_facet<_Facet>(__other)));
-}
-
 template <class _Facet>
 inline _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale& __l) _NOEXCEPT {
   return __l.has_facet(_Facet::id);
@@ -284,13 +287,6 @@ protected:
 };
 #endif
 
-template <class _CharT, class _Traits, class _Allocator>
-bool locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
-                        const basic_string<_CharT, _Traits, _Allocator>& __y) const {
-  return std::use_facet<std::collate<_CharT> >(*this).compare(
-             __x.data(), __x.data() + __x.size(), __y.data(), __y.data() + __y.size()) < 0;
-}
-
 // template <class charT> class ctype
 
 class _LIBCPP_EXPORTED_FROM_ABI ctype_base {
diff --git a/libcxx/include/__thread/thread.h b/libcxx/include/__thread/thread.h
index c40ffd25b903c2..86c0e8b4ff9da3 100644
--- a/libcxx/include/__thread/thread.h
+++ b/libcxx/include/__thread/thread.h
@@ -151,47 +151,6 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) {
 }
 #  endif // _LIBCPP_HAS_LOCALIZATION
 
-class _LIBCPP_EXPORTED_FROM_ABI thread {
-  __libcpp_thread_t __t_;
-
-  thread(const thread&);
-  thread& operator=(const thread&);
-
-public:
-  typedef __thread_id id;
-  typedef __libcpp_thread_t native_handle_type;
-
-  _LIBCPP_HIDE_FROM_ABI thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
-#  ifndef _LIBCPP_CXX03_LANG
-  template <class _Fp, class... _Args, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit thread(_Fp&& __f, _Args&&... __args);
-#  else // _LIBCPP_CXX03_LANG
-  template <class _Fp>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS explicit thread(_Fp __f);
-#  endif
-  ~thread();
-
-  _LIBCPP_HIDE_FROM_ABI thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { __t.__t_ = _LIBCPP_NULL_THREAD; }
-
-  _LIBCPP_HIDE_FROM_ABI thread& operator=(thread&& __t) _NOEXCEPT {
-    if (!__libcpp_thread_isnull(&__t_))
-      terminate();
-    __t_     = __t.__t_;
-    __t.__t_ = _LIBCPP_NULL_THREAD;
-    return *this;
-  }
-
-  _LIBCPP_HIDE_FROM_ABI void swap(thread& __t) _NOEXCEPT { std::swap(__t_, __t.__t_); }
-
-  _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
-  void join();
-  void detach();
-  _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
-  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
-
-  static unsigned hardware_concurrency() _NOEXCEPT;
-};
-
 #  ifndef _LIBCPP_CXX03_LANG
 
 template <class _TSp, class _Fp, class... _Args, size_t... _Indices>
@@ -209,19 +168,6 @@ _LIBCPP_HIDE_FROM_ABI void* __thread_proxy(void* __vp) {
   return nullptr;
 }
 
-template <class _Fp, class... _Args, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value, int> >
-thread::thread(_Fp&& __f, _Args&&... __args) {
-  typedef unique_ptr<__thread_struct> _TSPtr;
-  _TSPtr __tsp(new __thread_struct);
-  typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp;
-  unique_ptr<_Gp> __p(new _Gp(std::move(__tsp), std::forward<_Fp>(__f), std::forward<_Args>(__args)...));
-  int __ec = std::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
-  if (__ec == 0)
-    __p.release();
-  else
-    __throw_system_error(__ec, "thread constructor failed");
-}
-
 #  else // _LIBCPP_CXX03_LANG
 
 template <class _Fp>
@@ -242,20 +188,69 @@ _LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp) {
   return nullptr;
 }
 
-template <class _Fp>
-thread::thread(_Fp __f) {
-  typedef __thread_invoke_pair<_Fp> _InvokePair;
-  typedef unique_ptr<_InvokePair> _PairPtr;
-  _PairPtr __pp(new _InvokePair(__f));
-  int __ec = std::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
-  if (__ec == 0)
-    __pp.release();
-  else
-    __throw_system_error(__ec, "thread constructor failed");
-}
-
 #  endif // _LIBCPP_CXX03_LANG
 
+class _LIBCPP_EXPORTED_FROM_ABI thread {
+  __libcpp_thread_t __t_;
+
+  thread(const thread&);
+  thread& operator=(const thread&);
+
+public:
+  typedef __thread_id id;
+  typedef __libcpp_thread_t native_handle_type;
+
+  _LIBCPP_HIDE_FROM_ABI thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
+
+#  ifndef _LIBCPP_CXX03_LANG
+  template <class _Fp, class... _Args, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value, int> = 0>
+  _LIBCPP_HIDE_FROM_ABI explicit thread(_Fp&& __f, _Args&&... __args) {
+    typedef unique_ptr<__thread_struct> _TSPtr;
+    _TSPtr __tsp(new __thread_struct);
+    typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp;
+    unique_ptr<_Gp> __p(new _Gp(std::move(__tsp), std::forward<_Fp>(__f), std::forward<_Args>(__args)...));
+    int __ec = std::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
+    if (__ec == 0)
+      __p.release();
+    else
+      __throw_system_error(__ec, "thread constructor failed");
+  }
+#  else // _LIBCPP_CXX03_LANG
+  template <class _Fp>
+  _LIBCPP_HIDE_FROM_ABI explicit thread(_Fp __f) {
+    typedef __thread_invoke_pair<_Fp> _InvokePair;
+    typedef unique_ptr<_InvokePair> _PairPtr;
+    _PairPtr __pp(new _InvokePair(__f));
+    int __ec = std::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
+    if (__ec == 0)
+      __pp.release();
+    else
+      __throw_system_error(__ec, "thread constructor failed");
+  }
+#  endif
+  ~thread();
+
+  _LIBCPP_HIDE_FROM_ABI thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { __t.__t_ = _LIBCPP_NULL_THREAD; }
+
+  _LIBCPP_HIDE_FROM_ABI thread& operator=(thread&& __t) _NOEXCEPT {
+    if (!__libcpp_thread_isnull(&__t_))
+      terminate();
+    __t_     = __t.__t_;
+    __t.__t_ = _LIBCPP_NULL_THREAD;
+    return *this;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI void swap(thread& __t) _NOEXCEPT { std::swap(__t_, __t.__t_); }
+
+  _LIBCPP_HIDE_FROM_ABI bool joinable() const _NOEXCEPT { return !__libcpp_thread_isnull(&__t_); }
+  void join();
+  void detach();
+  _LIBCPP_HIDE_FROM_ABI id get_id() const _NOEXCEPT { return __libcpp_thread_get_id(&__t_); }
+  _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() _NOEXCEPT { return __t_; }
+
+  static unsigned hardware_concurrency() _NOEXCEPT;
+};
+
 inline _LIBCPP_HIDE_FROM_ABI void swap(thread& __x, thread& __y) _NOEXCEPT { __x.swap(__y); }
 
 #endif // _LIBCPP_HAS_THREADS
diff --git a/libcxx/include/condition_variable b/libcxx/include/condition_variable
index f894407d9321b3..4e4c025ea351da 100644
--- a/libcxx/include/condition_variable
+++ b/libcxx/include/condition_variable
@@ -144,6 +144,21 @@ _LIBCPP_PUSH_MACROS
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+template <class _Lock>
+struct __unlock_guard {
+  _Lock& __lock_;
+
+  _LIBCPP_HIDE_FROM_ABI __unlock_guard(_Lock& __lock) : __lock_(__lock) { __lock_.unlock(); }
+
+  _LIBCPP_HIDE_FROM_ABI ~__unlock_guard() _NOEXCEPT // turns exception to std::terminate
+  {
+    __lock_.lock();
+  }
+
+  __unlock_guard(const __unlock_guard&)            = delete;
+  __unlock_guard& operator=(const __unlock_guard&) = delete;
+};
+
 class _LIBCPP_EXPORTED_FROM_ABI condition_variable_any {
   condition_variable __cv_;
   shared_ptr<mutex> __mut_;
@@ -155,13 +170,25 @@ public:
   _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT;
 
   template <class _Lock>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS void wait(_Lock& __lock);
+  _LIBCPP_HIDE_FROM_ABI void wait(_Lock& __lock) {
+    shared_ptr<mutex> __mut = __mut_;
+    unique_lock<mutex> __lk(*__mut);
+    __unlock_guard<_Lock> __unlock(__lock);
+    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
+    __cv_.wait(__lk);
+  } // __mut_.unlock(), __lock.lock()
+
   template <class _Lock, class _Predicate>
   _LIBCPP_HIDE_FROM_ABI void wait(_Lock& __lock, _Predicate __pred);
 
   template <class _Lock, class _Clock, class _Duration>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status
-  wait_until(_Lock& __lock, const chrono::time_point<_Clock, _Duration>& __t);
+  _LIBCPP_HIDE_FROM_ABI cv_status wait_until(_Lock& __lock, const chrono::time_point<_Clock, _Duration>& __t) {
+    shared_ptr<mutex> __mut = __mut_;
+    unique_lock<mutex> __lk(*__mut);
+    __unlock_guard<_Lock> __unlock(__lock);
+    lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
+    return __cv_.wait_until(__lk, __t);
+  } // __mut_.unlock(), __lock.lock()
 
   template <class _Lock, class _Clock, class _Duration, class _Predicate>
   bool _LIBCPP_HIDE_FROM_ABI
@@ -201,45 +228,12 @@ inline void condition_variable_any::notify_all() _NOEXCEPT {
   __cv_.notify_all();
 }
 
-template <class _Lock>
-struct __unlock_guard {
-  _Lock& __lock_;
-
-  _LIBCPP_HIDE_FROM_ABI __unlock_guard(_Lock& __lock) : __lock_(__lock) { __lock_.unlock(); }
-
-  _LIBCPP_HIDE_FROM_ABI ~__unlock_guard() _NOEXCEPT // turns exception to std::terminate
-  {
-    __lock_.lock();
-  }
-
-  __unlock_guard(const __unlock_guard&)            = delete;
-  __unlock_guard& operator=(const __unlock_guard&) = delete;
-};
-
-template <class _Lock>
-void condition_variable_any::wait(_Lock& __lock) {
-  shared_ptr<mutex> __mut = __mut_;
-  unique_lock<mutex> __lk(*__mut);
-  __unlock_guard<_Lock> __unlock(__lock);
-  lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
-  __cv_.wait(__lk);
-} // __mut_.unlock(), __lock.lock()
-
 template <class _Lock, class _Predicate>
 inline void condition_variable_any::wait(_Lock& __lock, _Predicate __pred) {
   while (!__pred())
     wait(__lock);
 }
 
-template <class _Lock, class _Clock, class _Duration>
-cv_status condition_variable_any::wait_until(_Lock& __lock, const chrono::time_point<_Clock, _Duration>& __t) {
-  shared_ptr<mutex> __mut = __mut_;
-  unique_lock<mutex> __lk(*__mut);
-  __unlock_guard<_Lock> __unlock(__lock);
-  lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t());
-  return __cv_.wait_until(__lk, __t);
-} // __mut_.unlock(), __lock.lock()
-
 template <class _Lock, class _Clock, class _Duration, class _Predicate>
 inline bool
 condition_variable_any::wait_until(_Lock& __lock, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred) {
diff --git a/libcxx/include/future b/libcxx/include/future
index 9f7c95e542fd60..0e160584c3c18b 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -551,24 +551,20 @@ public:
   template <class _Rep, class _Period>
   future_status _LIBCPP_HIDE_FROM_ABI wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const;
   template <class _Clock, class _Duration>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS future_status
-  wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const;
+  _LIBCPP_HIDE_FROM_ABI future_status wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
+    unique_lock<mutex> __lk(__mut_);
+    if (__state_ & deferred)
+      return future_status::deferred;
+    while (!(__state_ & ready) && _Clock::now() < __abs_time)
+      __cv_.wait_until(__lk, __abs_time);
+    if (__state_ & ready)
+      return future_status::ready;
+    return future_status::timeout;
+  }
 
   virtual void __execute();
 };
 
-template <class _Clock, class _Duration>
-future_status __assoc_sub_state::wait_until(const chrono::time_point<_Clock, _Duration>& __abs_time) const {
-  unique_lock<mutex> __lk(__mut_);
-  if (__state_ & deferred)
-    return future_status::deferred;
-  while (!(__state_ & ready) && _Clock::now() < __abs_time)
-    __cv_.wait_until(__lk, __abs_time);
-  if (__state_ & ready)
-    return future_status::ready;
-  return future_status::timeout;
-}
-
 template <class _Rep, class _Period>
 inline future_status __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) const {
   return wait_until(chrono::steady_clock::now() + __rel_time);
@@ -1335,8 +1331,17 @@ class _LIBCPP_EXPORTED_FROM_ABI promise<void> {
 
 public:
   promise();
-  template <class _Allocator>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS promise(allocator_arg_t, const _Allocator& __a);
+  template <class _Alloc>
+  _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a0) {
+    typedef __assoc_sub_state_alloc<_Alloc> _State;
+    typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
+    typedef __allocator_destructor<_A2> _D2;
+    _A2 __a(__a0);
+    unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
+    ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
+    __state_ = std::addressof(*__hold.release());
+  }
+
   _LIBCPP_HIDE_FROM_ABI promise(promise&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) { __rhs.__state_ = nullptr; }
   promise(const promise& __rhs) = delete;
   ~promise();
@@ -1362,17 +1367,6 @@ public:
   void set_exception_at_thread_exit(exception_ptr __p);
 };
 
-template <class _Alloc>
-promise<void>::promise(allocator_arg_t, const _Alloc& __a0) {
-  typedef __assoc_sub_state_alloc<_Alloc> _State;
-  typedef typename __allocator_traits_rebind<_Alloc, _State>::type _A2;
-  typedef __allocator_destructor<_A2> _D2;
-  _A2 __a(__a0);
-  unique_ptr<_State, _D2> __hold(__a.allocate(1), _D2(__a, 1));
-  ::new ((void*)std::addressof(*__hold.get())) _State(__a0);
-  __state_ = std::addressof(*__hold.release());
-}
-
 template <class _Rp>
 inline _LIBCPP_HIDE_FROM_ABI void swap(promise<_Rp>& __x, promise<_Rp>& __y) _NOEXCEPT {
   __x.swap(__y);
diff --git a/libcxx/include/locale b/libcxx/include/locale
index 65f5c6ba52f736..caa7312c116c92 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -585,6 +585,104 @@ 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 strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
+}
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI double __do_strtod<double>(const char* __a, char** __p2) {
+  return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
+}
+
+template <>
+inline _LIBCPP_HIDE_FROM_ABI long double __do_strtod<long double>(const char* __a, char** __p2) {
+  return strtold_l(__a, __p2, _LIBCPP_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);
+    __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
+    if (__current_errno == 0)
+      errno = __save_errno;
+    if (__p2 != __a_end) {
+      __err = ios_base::failbit;
+      return 0;
+    } else if (__current_errno == ERANGE)
+      __err = ios_base::failbit;
+    return __ld;
+  }
+  __err = ios_base::failbit;
+  return 0;
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__num_get_signed_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
+  if (__a != __a_end) {
+    __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
+    errno                                                     = 0;
+    char* __p2;
+    long long __ll                                               = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
+    __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
+    if (__current_errno == 0)
+      errno = __save_errno;
+    if (__p2 != __a_end) {
+      __err = ios_base::failbit;
+      return 0;
+    } else if (__current_errno == ERANGE || __ll < numeric_limits<_Tp>::min() || numeric_limits<_Tp>::max() < __ll) {
+      __err = ios_base::failbit;
+      if (__ll > 0)
+        return numeric_limits<_Tp>::max();
+      else
+        return numeric_limits<_Tp>::min();
+    }
+    return static_cast<_Tp>(__ll);
+  }
+  __err = ios_base::failbit;
+  return 0;
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _Tp
+__num_get_unsigned_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
+  if (__a != __a_end) {
+    const bool __negate = *__a == '-';
+    if (__negate && ++__a == __a_end) {
+      __err = ios_base::failbit;
+      return 0;
+    }
+    __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
+    errno                                                     = 0;
+    char* __p2;
+    unsigned long long __ll                                      = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
+    __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
+    if (__current_errno == 0)
+      errno = __save_errno;
+    if (__p2 != __a_end) {
+      __err = ios_base::failbit;
+      return 0;
+    } else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) {
+      __err = ios_base::failbit;
+      return numeric_limits<_Tp>::max();
+    }
+    _Tp __res = static_cast<_Tp>(__ll);
+    if (__negate)
+      __res = -__res;
+    return __res;
+  }
+  __err = ios_base::failbit;
+  return 0;
+}
+
 template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
 class _LIBCPP_TEMPLATE_VIS num_get : public locale::facet, private __num_get<_CharT> {
 public:
@@ -654,16 +752,165 @@ protected:
   _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~num_get() override {}
 
   template <class _Fp>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iter_type
-  __do_get_floating_point(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Fp& __v) const;
+  _LIBCPP_HIDE_FROM_ABI iter_type
+  __do_get_floating_point(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Fp& __v) const {
+    // Stage 1, nothing to do
+    // Stage 2
+    char_type __atoms[__num_get_base::__fp_chr_cnt];
+    char_type __decimal_point;
+    char_type __thousands_sep;
+    string __grouping = this->__stage2_float_prep(__iob, __atoms, __decimal_point, __thousands_sep);
+    string __buf;
+    __buf.resize(__buf.capacity());
+    char* __a     = &__buf[0];
+    char* __a_end = __a;
+    unsigned __g[__num_get_base::__num_get_buf_sz];
+    unsigned* __g_end        = __g;
+    unsigned __dc            = 0;
+    bool __in_units          = true;
+    char __exp               = 'E';
+    bool __is_leading_parsed = false;
+    for (; __b != __e; ++__b) {
+      if (__a_end == __a + __buf.size()) {
+        size_t __tmp = __buf.size();
+        __buf.resize(2 * __buf.size());
+        __buf.resize(__buf.capacity());
+        __a     = &__buf[0];
+        __a_end = __a + __tmp;
+      }
+      if (this->__stage2_float_loop(
+              *__b,
+              __in_units,
+              __exp,
+              __a,
+              __a_end,
+              __decimal_point,
+              __thousands_sep,
+              __grouping,
+              __g,
+              __g_end,
+              __dc,
+              __atoms))
+        break;
+
+      // the leading character excluding the sign must be a decimal digit
+      if (!__is_leading_parsed) {
+        if (__a_end - __a >= 1 && __a[0] != '-' && __a[0] != '+') {
+          if (('0' <= __a[0] && __a[0] <= '9') || __a[0] == '.')
+            __is_leading_parsed = true;
+          else
+            break;
+        } else if (__a_end - __a >= 2 && (__a[0] == '-' || __a[0] == '+')) {
+          if (('0' <= __a[1] && __a[1] <= '9') || __a[1] == '.')
+            __is_leading_parsed = true;
+          else
+            break;
+        }
+      }
+    }
+    if (__grouping.size() != 0 && __in_units && __g_end - __g < __num_get_base::__num_get_buf_sz)
+      *__g_end++ = __dc;
+    // Stage 3
+    __v = std::__num_get_float<_Fp>(__a, __a_end, __err);
+    // Digit grouping checked
+    __check_grouping(__grouping, __g, __g_end, __err);
+    // EOF checked
+    if (__b == __e)
+      __err |= ios_base::eofbit;
+    return __b;
+  }
 
   template <class _Signed>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iter_type
-  __do_get_signed(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const;
+  _LIBCPP_HIDE_FROM_ABI iter_type
+  __do_get_signed(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const {
+    // Stage 1
+    int __base = this->__get_base(__iob);
+    // Stage 2
+    char_type __thousands_sep;
+    const int __atoms_size = __num_get_base::__int_chr_cnt;
+#  ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
+    char_type __atoms1[__atoms_size];
+    const char_type* __atoms = this->__do_widen(__iob, __atoms1);
+    string __grouping        = this->__stage2_int_prep(__iob, __thousands_sep);
+#  else
+    char_type __atoms[__atoms_size];
+    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
+#  endif
+    string __buf;
+    __buf.resize(__buf.capacity());
+    char* __a     = &__buf[0];
+    char* __a_end = __a;
+    unsigned __g[__num_get_base::__num_get_buf_sz];
+    unsigned* __g_end = __g;
+    unsigned __dc     = 0;
+    for (; __b != __e; ++__b) {
+      if (__a_end == __a + __buf.size()) {
+        size_t __tmp = __buf.size();
+        __buf.resize(2 * __buf.size());
+        __buf.resize(__buf.capacity());
+        __a     = &__buf[0];
+        __a_end = __a + __tmp;
+      }
+      if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms))
+        break;
+    }
+    if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
+      *__g_end++ = __dc;
+    // Stage 3
+    __v = std::__num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
+    // Digit grouping checked
+    __check_grouping(__grouping, __g, __g_end, __err);
+    // EOF checked
+    if (__b == __e)
+      __err |= ios_base::eofbit;
+    return __b;
+  }
 
   template <class _Unsigned>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS iter_type
-  __do_get_unsigned(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const;
+  _LIBCPP_HIDE_FROM_ABI iter_type
+  __do_get_unsigned(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const {
+    // Stage 1
+    int __base = this->__get_base(__iob);
+    // Stage 2
+    char_type __thousands_sep;
+    const int __atoms_size = __num_get_base::__int_chr_cnt;
+#  ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
+    char_type __atoms1[__atoms_size];
+    const char_type* __atoms = this->__do_widen(__iob, __atoms1);
+    string __grouping        = this->__stage2_int_prep(__iob, __thousands_sep);
+#  else
+    char_type __atoms[__atoms_size];
+    string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
+#  endif
+    string __buf;
+    __buf.resize(__buf.capacity());
+    char* __a     = &__buf[0];
+    char* __a_end = __a;
+    unsigned __g[__num_get_base::__num_get_buf_sz];
+    unsigned* __g_end = __g;
+    unsigned __dc     = 0;
+    for (; __b != __e; ++__b) {
+      if (__a_end == __a + __buf.size()) {
+        size_t __tmp = __buf.size();
+        __buf.resize(2 * __buf.size());
+        __buf.resize(__buf.capacity());
+        __a     = &__buf[0];
+        __a_end = __a + __tmp;
+      }
+      if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms))
+        break;
+    }
+    if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
+      *__g_end++ = __dc;
+    // Stage 3
+    __v = std::__num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
+    // Digit grouping checked
+    __check_grouping(__grouping, __g, __g_end, __err);
+    // EOF checked
+    if (__b == __e)
+      __err |= ios_base::eofbit;
+    return __b;
+  }
 
   virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const;
 
@@ -715,104 +962,6 @@ protected:
 template <class _CharT, class _InputIterator>
 locale::id num_get<_CharT, _InputIterator>::id;
 
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _Tp
-__num_get_signed_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
-  if (__a != __a_end) {
-    __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
-    errno                                                     = 0;
-    char* __p2;
-    long long __ll                                               = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
-    __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
-    if (__current_errno == 0)
-      errno = __save_errno;
-    if (__p2 != __a_end) {
-      __err = ios_base::failbit;
-      return 0;
-    } else if (__current_errno == ERANGE || __ll < numeric_limits<_Tp>::min() || numeric_limits<_Tp>::max() < __ll) {
-      __err = ios_base::failbit;
-      if (__ll > 0)
-        return numeric_limits<_Tp>::max();
-      else
-        return numeric_limits<_Tp>::min();
-    }
-    return static_cast<_Tp>(__ll);
-  }
-  __err = ios_base::failbit;
-  return 0;
-}
-
-template <class _Tp>
-_LIBCPP_HIDE_FROM_ABI _Tp
-__num_get_unsigned_integral(const char* __a, const char* __a_end, ios_base::iostate& __err, int __base) {
-  if (__a != __a_end) {
-    const bool __negate = *__a == '-';
-    if (__negate && ++__a == __a_end) {
-      __err = ios_base::failbit;
-      return 0;
-    }
-    __libcpp_remove_reference_t<decltype(errno)> __save_errno = errno;
-    errno                                                     = 0;
-    char* __p2;
-    unsigned long long __ll                                      = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
-    __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
-    if (__current_errno == 0)
-      errno = __save_errno;
-    if (__p2 != __a_end) {
-      __err = ios_base::failbit;
-      return 0;
-    } else if (__current_errno == ERANGE || numeric_limits<_Tp>::max() < __ll) {
-      __err = ios_base::failbit;
-      return numeric_limits<_Tp>::max();
-    }
-    _Tp __res = static_cast<_Tp>(__ll);
-    if (__negate)
-      __res = -__res;
-    return __res;
-  }
-  __err = ios_base::failbit;
-  return 0;
-}
-
-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 strtof_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
-}
-
-template <>
-inline _LIBCPP_HIDE_FROM_ABI double __do_strtod<double>(const char* __a, char** __p2) {
-  return strtod_l(__a, __p2, _LIBCPP_GET_C_LOCALE);
-}
-
-template <>
-inline _LIBCPP_HIDE_FROM_ABI long double __do_strtod<long double>(const char* __a, char** __p2) {
-  return strtold_l(__a, __p2, _LIBCPP_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);
-    __libcpp_remove_reference_t<decltype(errno)> __current_errno = errno;
-    if (__current_errno == 0)
-      errno = __save_errno;
-    if (__p2 != __a_end) {
-      __err = ios_base::failbit;
-      return 0;
-    } else if (__current_errno == ERANGE)
-      __err = ios_base::failbit;
-    return __ld;
-  }
-  __err = ios_base::failbit;
-  return 0;
-}
-
 template <class _CharT, class _InputIterator>
 _InputIterator num_get<_CharT, _InputIterator>::do_get(
     iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, bool& __v) const {
@@ -842,176 +991,6 @@ _InputIterator num_get<_CharT, _InputIterator>::do_get(
   return __b;
 }
 
-// signed
-
-template <class _CharT, class _InputIterator>
-template <class _Signed>
-_InputIterator num_get<_CharT, _InputIterator>::__do_get_signed(
-    iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Signed& __v) const {
-  // Stage 1
-  int __base = this->__get_base(__iob);
-  // Stage 2
-  char_type __thousands_sep;
-  const int __atoms_size = __num_get_base::__int_chr_cnt;
-#  ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
-  char_type __atoms1[__atoms_size];
-  const char_type* __atoms = this->__do_widen(__iob, __atoms1);
-  string __grouping        = this->__stage2_int_prep(__iob, __thousands_sep);
-#  else
-  char_type __atoms[__atoms_size];
-  string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
-#  endif
-  string __buf;
-  __buf.resize(__buf.capacity());
-  char* __a     = &__buf[0];
-  char* __a_end = __a;
-  unsigned __g[__num_get_base::__num_get_buf_sz];
-  unsigned* __g_end = __g;
-  unsigned __dc     = 0;
-  for (; __b != __e; ++__b) {
-    if (__a_end == __a + __buf.size()) {
-      size_t __tmp = __buf.size();
-      __buf.resize(2 * __buf.size());
-      __buf.resize(__buf.capacity());
-      __a     = &__buf[0];
-      __a_end = __a + __tmp;
-    }
-    if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms))
-      break;
-  }
-  if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
-    *__g_end++ = __dc;
-  // Stage 3
-  __v = std::__num_get_signed_integral<_Signed>(__a, __a_end, __err, __base);
-  // Digit grouping checked
-  __check_grouping(__grouping, __g, __g_end, __err);
-  // EOF checked
-  if (__b == __e)
-    __err |= ios_base::eofbit;
-  return __b;
-}
-
-// unsigned
-
-template <class _CharT, class _InputIterator>
-template <class _Unsigned>
-_InputIterator num_get<_CharT, _InputIterator>::__do_get_unsigned(
-    iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Unsigned& __v) const {
-  // Stage 1
-  int __base = this->__get_base(__iob);
-  // Stage 2
-  char_type __thousands_sep;
-  const int __atoms_size = __num_get_base::__int_chr_cnt;
-#  ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
-  char_type __atoms1[__atoms_size];
-  const char_type* __atoms = this->__do_widen(__iob, __atoms1);
-  string __grouping        = this->__stage2_int_prep(__iob, __thousands_sep);
-#  else
-  char_type __atoms[__atoms_size];
-  string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
-#  endif
-  string __buf;
-  __buf.resize(__buf.capacity());
-  char* __a     = &__buf[0];
-  char* __a_end = __a;
-  unsigned __g[__num_get_base::__num_get_buf_sz];
-  unsigned* __g_end = __g;
-  unsigned __dc     = 0;
-  for (; __b != __e; ++__b) {
-    if (__a_end == __a + __buf.size()) {
-      size_t __tmp = __buf.size();
-      __buf.resize(2 * __buf.size());
-      __buf.resize(__buf.capacity());
-      __a     = &__buf[0];
-      __a_end = __a + __tmp;
-    }
-    if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, __thousands_sep, __grouping, __g, __g_end, __atoms))
-      break;
-  }
-  if (__grouping.size() != 0 && __g_end - __g < __num_get_base::__num_get_buf_sz)
-    *__g_end++ = __dc;
-  // Stage 3
-  __v = std::__num_get_unsigned_integral<_Unsigned>(__a, __a_end, __err, __base);
-  // Digit grouping checked
-  __check_grouping(__grouping, __g, __g_end, __err);
-  // EOF checked
-  if (__b == __e)
-    __err |= ios_base::eofbit;
-  return __b;
-}
-
-// floating point
-
-template <class _CharT, class _InputIterator>
-template <class _Fp>
-_InputIterator num_get<_CharT, _InputIterator>::__do_get_floating_point(
-    iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, _Fp& __v) const {
-  // Stage 1, nothing to do
-  // Stage 2
-  char_type __atoms[__num_get_base::__fp_chr_cnt];
-  char_type __decimal_point;
-  char_type __thousands_sep;
-  string __grouping = this->__stage2_float_prep(__iob, __atoms, __decimal_point, __thousands_sep);
-  string __buf;
-  __buf.resize(__buf.capacity());
-  char* __a     = &__buf[0];
-  char* __a_end = __a;
-  unsigned __g[__num_get_base::__num_get_buf_sz];
-  unsigned* __g_end        = __g;
-  unsigned __dc            = 0;
-  bool __in_units          = true;
-  char __exp               = 'E';
-  bool __is_leading_parsed = false;
-  for (; __b != __e; ++__b) {
-    if (__a_end == __a + __buf.size()) {
-      size_t __tmp = __buf.size();
-      __buf.resize(2 * __buf.size());
-      __buf.resize(__buf.capacity());
-      __a     = &__buf[0];
-      __a_end = __a + __tmp;
-    }
-    if (this->__stage2_float_loop(
-            *__b,
-            __in_units,
-            __exp,
-            __a,
-            __a_end,
-            __decimal_point,
-            __thousands_sep,
-            __grouping,
-            __g,
-            __g_end,
-            __dc,
-            __atoms))
-      break;
-
-    // the leading character excluding the sign must be a decimal digit
-    if (!__is_leading_parsed) {
-      if (__a_end - __a >= 1 && __a[0] != '-' && __a[0] != '+') {
-        if (('0' <= __a[0] && __a[0] <= '9') || __a[0] == '.')
-          __is_leading_parsed = true;
-        else
-          break;
-      } else if (__a_end - __a >= 2 && (__a[0] == '-' || __a[0] == '+')) {
-        if (('0' <= __a[1] && __a[1] <= '9') || __a[1] == '.')
-          __is_leading_parsed = true;
-        else
-          break;
-      }
-    }
-  }
-  if (__grouping.size() != 0 && __in_units && __g_end - __g < __num_get_base::__num_get_buf_sz)
-    *__g_end++ = __dc;
-  // Stage 3
-  __v = std::__num_get_float<_Fp>(__a, __a_end, __err);
-  // Digit grouping checked
-  __check_grouping(__grouping, __g, __g_end, __err);
-  // EOF checked
-  if (__b == __e)
-    __err |= ios_base::eofbit;
-  return __b;
-}
-
 template <class _CharT, class _InputIterator>
 _InputIterator num_get<_CharT, _InputIterator>::do_get(
     iter_type __b, iter_type __e, ios_base& __iob, ios_base::iostate& __err, void*& __v) const {
diff --git a/libcxx/include/mutex b/libcxx/include/mutex
index ecbfc5607dcc78..e9ddefdd719edd 100644
--- a/libcxx/include/mutex
+++ b/libcxx/include/mutex
@@ -253,26 +253,24 @@ public:
   _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
     return try_lock_until(chrono::steady_clock::now() + __d);
   }
+
   template <class _Clock, class _Duration>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
-  try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
+    using namespace chrono;
+    unique_lock<mutex> __lk(__m_);
+    bool __no_timeout = _Clock::now() < __t;
+    while (__no_timeout && __locked_)
+      __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
+    if (!__locked_) {
+      __locked_ = true;
+      return true;
+    }
+    return false;
+  }
+
   void unlock() _NOEXCEPT;
 };
 
-template <class _Clock, class _Duration>
-bool timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
-  using namespace chrono;
-  unique_lock<mutex> __lk(__m_);
-  bool __no_timeout = _Clock::now() < __t;
-  while (__no_timeout && __locked_)
-    __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
-  if (!__locked_) {
-    __locked_ = true;
-    return true;
-  }
-  return false;
-}
-
 class _LIBCPP_EXPORTED_FROM_ABI recursive_timed_mutex {
   mutex __m_;
   condition_variable __cv_;
@@ -292,34 +290,32 @@ public:
   _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) {
     return try_lock_until(chrono::steady_clock::now() + __d);
   }
+
   template <class _Clock, class _Duration>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
-  try_lock_until(const chrono::time_point<_Clock, _Duration>& __t);
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
+    using namespace chrono;
+    __thread_id __id = this_thread::get_id();
+    unique_lock<mutex> __lk(__m_);
+    if (__id == __id_) {
+      if (__count_ == numeric_limits<size_t>::max())
+        return false;
+      ++__count_;
+      return true;
+    }
+    bool __no_timeout = _Clock::now() < __t;
+    while (__no_timeout && __count_ != 0)
+      __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
+    if (__count_ == 0) {
+      __count_ = 1;
+      __id_    = __id;
+      return true;
+    }
+    return false;
+  }
+
   void unlock() _NOEXCEPT;
 };
 
-template <class _Clock, class _Duration>
-bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) {
-  using namespace chrono;
-  __thread_id __id = this_thread::get_id();
-  unique_lock<mutex> __lk(__m_);
-  if (__id == __id_) {
-    if (__count_ == numeric_limits<size_t>::max())
-      return false;
-    ++__count_;
-    return true;
-  }
-  bool __no_timeout = _Clock::now() < __t;
-  while (__no_timeout && __count_ != 0)
-    __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout;
-  if (__count_ == 0) {
-    __count_ = 1;
-    __id_    = __id;
-    return true;
-  }
-  return false;
-}
-
 template <class _L0, class _L1>
 _LIBCPP_HIDE_FROM_ABI int try_lock(_L0& __l0, _L1& __l1) {
   unique_lock<_L0> __u0(__l0, try_to_lock_t());
diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex
index 2552119405419c..fd35940862c343 100644
--- a/libcxx/include/shared_mutex
+++ b/libcxx/include/shared_mutex
@@ -237,10 +237,36 @@ public:
       _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
     return try_lock_until(chrono::steady_clock::now() + __rel_time);
   }
+
   template <class _Clock, class _Duration>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
-  try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true));
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) {
+    unique_lock<mutex> __lk(__base_.__mut_);
+    if (__base_.__state_ & __base_.__write_entered_) {
+      while (true) {
+        cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
+        if ((__base_.__state_ & __base_.__write_entered_) == 0)
+          break;
+        if (__status == cv_status::timeout)
+          return false;
+      }
+    }
+    __base_.__state_ |= __base_.__write_entered_;
+    if (__base_.__state_ & __base_.__n_readers_) {
+      while (true) {
+        cv_status __status = __base_.__gate2_.wait_until(__lk, __abs_time);
+        if ((__base_.__state_ & __base_.__n_readers_) == 0)
+          break;
+        if (__status == cv_status::timeout) {
+          __base_.__state_ &= ~__base_.__write_entered_;
+          __base_.__gate1_.notify_all();
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
   void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__());
 
   // Shared ownership
@@ -251,60 +277,30 @@ public:
       _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
     return try_lock_shared_until(chrono::steady_clock::now() + __rel_time);
   }
-  template <class _Clock, class _Duration>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
-  try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
-      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true));
-  void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__());
-};
 
-template <class _Clock, class _Duration>
-bool shared_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) {
-  unique_lock<mutex> __lk(__base_.__mut_);
-  if (__base_.__state_ & __base_.__write_entered_) {
-    while (true) {
-      cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
-      if ((__base_.__state_ & __base_.__write_entered_) == 0)
-        break;
-      if (__status == cv_status::timeout)
-        return false;
-    }
-  }
-  __base_.__state_ |= __base_.__write_entered_;
-  if (__base_.__state_ & __base_.__n_readers_) {
-    while (true) {
-      cv_status __status = __base_.__gate2_.wait_until(__lk, __abs_time);
-      if ((__base_.__state_ & __base_.__n_readers_) == 0)
-        break;
-      if (__status == cv_status::timeout) {
-        __base_.__state_ &= ~__base_.__write_entered_;
-        __base_.__gate1_.notify_all();
-        return false;
+  template <class _Clock, class _Duration>
+  _LIBCPP_HIDE_FROM_ABI bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
+      _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) {
+    unique_lock<mutex> __lk(__base_.__mut_);
+    if ((__base_.__state_ & __base_.__write_entered_) ||
+        (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_) {
+      while (true) {
+        cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
+        if ((__base_.__state_ & __base_.__write_entered_) == 0 &&
+            (__base_.__state_ & __base_.__n_readers_) < __base_.__n_readers_)
+          break;
+        if (__status == cv_status::timeout)
+          return false;
       }
     }
+    unsigned __num_readers = (__base_.__state_ & __base_.__n_readers_) + 1;
+    __base_.__state_ &= ~__base_.__n_readers_;
+    __base_.__state_ |= __num_readers;
+    return true;
   }
-  return true;
-}
 
-template <class _Clock, class _Duration>
-bool shared_timed_mutex::try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) {
-  unique_lock<mutex> __lk(__base_.__mut_);
-  if ((__base_.__state_ & __base_.__write_entered_) ||
-      (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_) {
-    while (true) {
-      cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time);
-      if ((__base_.__state_ & __base_.__write_entered_) == 0 &&
-          (__base_.__state_ & __base_.__n_readers_) < __base_.__n_readers_)
-        break;
-      if (__status == cv_status::timeout)
-        return false;
-    }
-  }
-  unsigned __num_readers = (__base_.__state_ & __base_.__n_readers_) + 1;
-  __base_.__state_ &= ~__base_.__n_readers_;
-  __base_.__state_ |= __num_readers;
-  return true;
-}
+  void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__());
+};
 
 template <class _Mutex>
 class shared_lock {
diff --git a/libcxx/include/string b/libcxx/include/string
index a994f65a9a6e4f..a9de5abaef5707 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1155,7 +1155,7 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string>::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
   basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type())
       : __alloc_(__a) {
     __self_view __sv0 = __t;
@@ -1167,8 +1167,7 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string>::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t) {
     __self_view __sv = __t;
     __init(__sv.data(), __sv.size());
   }
@@ -1177,8 +1176,7 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string>::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t, const allocator_type& __a)
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t, const allocator_type& __a)
       : __alloc_(__a) {
     __self_view __sv = __t;
     __init(__sv.data(), __sv.size());
@@ -1365,8 +1363,7 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string >::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  operator+=(const _Tp& __t) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator+=(const _Tp& __t) {
     __self_view __sv = __t;
     return append(__sv);
   }
@@ -1394,8 +1391,7 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string>::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  append(const _Tp& __t) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const _Tp& __t) {
     __self_view __sv = __t;
     return append(__sv.data(), __sv.size());
   }
@@ -1406,10 +1402,14 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string>::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20
-
-  basic_string&
-  append(const _Tp& __t, size_type __pos, size_type __n = npos);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  append(const _Tp& __t, size_type __pos, size_type __n = npos) {
+    __self_view __sv = __t;
+    size_type __sz   = __sv.size();
+    if (__pos > __sz)
+      __throw_out_of_range();
+    return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s);
@@ -1418,7 +1418,7 @@ public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append_default_init(size_type __n);
 
   template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   append(_InputIterator __first, _InputIterator __last) {
     const basic_string __temp(__first, __last, __alloc_);
     append(__temp.data(), __temp.size());
@@ -1426,8 +1426,26 @@ public:
   }
 
   template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  append(_ForwardIterator __first, _ForwardIterator __last);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  append(_ForwardIterator __first, _ForwardIterator __last) {
+    size_type __sz  = size();
+    size_type __cap = capacity();
+    size_type __n   = static_cast<size_type>(std::distance(__first, __last));
+    if (__n) {
+      if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) {
+        if (__cap - __sz < __n)
+          __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
+        __annotate_increase(__n);
+        auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz));
+        traits_type::assign(*__end, value_type());
+        __set_size(__sz + __n);
+      } else {
+        const basic_string __temp(__first, __last, __alloc_);
+        append(__temp.data(), __temp.size());
+      }
+    }
+    return *this;
+  }
 
 #if _LIBCPP_STD_VER >= 23
   template <_ContainerCompatibleRange<_CharT> _Range>
@@ -1467,8 +1485,7 @@ public:
   }
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  assign(const _Tp& __t) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const _Tp& __t) {
     __self_view __sv = __t;
     return assign(__sv.data(), __sv.size());
   }
@@ -1512,19 +1529,38 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string>::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  assign(const _Tp& __t, size_type __pos, size_type __n = npos);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  assign(const _Tp& __t, size_type __pos, size_type __n = npos) {
+    __self_view __sv = __t;
+    size_type __sz   = __sv.size();
+    if (__pos > __sz)
+      __throw_out_of_range();
+    return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s);
   _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c);
+
   template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  assign(_InputIterator __first, _InputIterator __last);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  assign(_InputIterator __first, _InputIterator __last) {
+    __assign_with_sentinel(__first, __last);
+    return *this;
+  }
 
   template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  assign(_ForwardIterator __first, _ForwardIterator __last);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  assign(_ForwardIterator __first, _ForwardIterator __last) {
+    if (__string_is_trivial_iterator<_ForwardIterator>::value) {
+      size_type __n = static_cast<size_type>(std::distance(__first, __last));
+      __assign_trivial(__first, __last, __n);
+    } else {
+      __assign_with_sentinel(__first, __last);
+    }
+
+    return *this;
+  }
 
 #if _LIBCPP_STD_VER >= 23
   template <_ContainerCompatibleRange<_CharT> _Range>
@@ -1554,8 +1590,7 @@ public:
   }
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  insert(size_type __pos1, const _Tp& __t) {
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos1, const _Tp& __t) {
     __self_view __sv = __t;
     return insert(__pos1, __sv.data(), __sv.size());
   }
@@ -1564,8 +1599,14 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string>::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos) {
+    __self_view __sv   = __t;
+    size_type __str_sz = __sv.size();
+    if (__pos2 > __str_sz)
+      __throw_out_of_range();
+    return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos);
@@ -1596,12 +1637,18 @@ public:
   }
 
   template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
-  insert(const_iterator __pos, _InputIterator __first, _InputIterator __last);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
+  insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) {
+    const basic_string __temp(__first, __last, __alloc_);
+    return insert(__pos, __temp.data(), __temp.data() + __temp.size());
+  }
 
   template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
-  insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
+  insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) {
+    auto __n = static_cast<size_type>(std::distance(__first, __last));
+    return __insert_with_size(__pos, __first, __last, __n);
+  }
 
 #ifndef _LIBCPP_CXX03_LANG
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator
@@ -1620,7 +1667,7 @@ public:
   }
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   replace(size_type __pos1, size_type __n1, const _Tp& __t) {
     __self_view __sv = __t;
     return replace(__pos1, __n1, __sv.data(), __sv.size());
@@ -1633,8 +1680,14 @@ public:
             __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
                               !__is_same_uncvref<_Tp, basic_string>::value,
                           int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) {
+    __self_view __sv   = __t;
+    size_type __str_sz = __sv.size();
+    if (__pos2 > __str_sz)
+      __throw_out_of_range();
+    return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2);
@@ -1648,7 +1701,7 @@ public:
   }
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
   replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) {
     __self_view __sv = __t;
     return replace(__i1 - begin(), __i2 - __i1, __sv);
@@ -1670,8 +1723,11 @@ public:
   }
 
   template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
-  replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2);
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string&
+  replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) {
+    const basic_string __temp(__j1, __j2, __alloc_);
+    return replace(__i1, __i2, __temp);
+  }
 
 #if _LIBCPP_STD_VER >= 23
   template <_ContainerCompatibleRange<_CharT> _Range>
@@ -1731,8 +1787,11 @@ public:
   find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
-  find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+  find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
+    __self_view __sv = __t;
+    return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
@@ -1743,8 +1802,11 @@ public:
   rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
-  rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+  rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
+    __self_view __sv = __t;
+    return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
@@ -1755,8 +1817,12 @@ public:
   find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
-  find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+  find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
+    __self_view __sv = __t;
+    return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
+        data(), size(), __sv.data(), __pos, __sv.size());
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
   find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
@@ -1769,8 +1835,12 @@ public:
   find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
-  find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+  find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
+    __self_view __sv = __t;
+    return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
+        data(), size(), __sv.data(), __pos, __sv.size());
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
   find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
@@ -1783,8 +1853,12 @@ public:
   find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT;
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
-  find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+  find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT {
+    __self_view __sv = __t;
+    return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
+        data(), size(), __sv.data(), __pos, __sv.size());
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
   find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
@@ -1797,8 +1871,12 @@ public:
   find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT;
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
-  find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
+  find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT {
+    __self_view __sv = __t;
+    return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
+        data(), size(), __sv.data(), __pos, __sv.size());
+  }
 
   _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type
   find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT;
@@ -1810,12 +1888,26 @@ public:
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const basic_string& __str) const _NOEXCEPT;
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int
-  compare(const _Tp& __t) const _NOEXCEPT;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const _Tp& __t) const _NOEXCEPT {
+    __self_view __sv = __t;
+    size_t __lhs_sz  = size();
+    size_t __rhs_sz  = __sv.size();
+    int __result     = traits_type::compare(data(), __sv.data(), std::min(__lhs_sz, __rhs_sz));
+    if (__result != 0)
+      return __result;
+    if (__lhs_sz < __rhs_sz)
+      return -1;
+    if (__lhs_sz > __rhs_sz)
+      return 1;
+    return 0;
+  }
 
   template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0>
-  _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int
-  compare(size_type __pos1, size_type __n1, const _Tp& __t) const;
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
+  compare(size_type __pos1, size_type __n1, const _Tp& __t) const {
+    __self_view __sv = __t;
+    return compare(__pos1, __n1, __sv.data(), __sv.size());
+  }
 
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int
   compare(size_type __pos1, size_type __n1, const basic_string& __str) const;
@@ -2761,14 +2853,6 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr
 
 #endif
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) {
-  __assign_with_sentinel(__first, __last);
-  return *this;
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 template <class _InputIterator, class _Sentinel>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
@@ -2777,20 +2861,6 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator
   assign(__temp.data(), __temp.size());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) {
-  if (__string_is_trivial_iterator<_ForwardIterator>::value) {
-    size_type __n = static_cast<size_type>(std::distance(__first, __last));
-    __assign_trivial(__first, __last, __n);
-  } else {
-    __assign_with_sentinel(__first, __last);
-  }
-
-  return *this;
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Iterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
@@ -2830,20 +2900,6 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz
   return assign(__str.data() + __pos, std::min(__n, __sz - __pos));
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp,
-          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
-                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-                        int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) {
-  __self_view __sv = __t;
-  size_type __sz   = __sv.size();
-  if (__pos > __sz)
-    __throw_out_of_range();
-  return assign(__sv.data() + __pos, std::min(__n, __sz - __pos));
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::__assign_external(const value_type* __s) {
@@ -2945,29 +3001,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void basic_string<_CharT, _Traits, _Allocator>::pu
   traits_type::assign(*++__p, value_type());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::append(_ForwardIterator __first, _ForwardIterator __last) {
-  size_type __sz  = size();
-  size_type __cap = capacity();
-  size_type __n   = static_cast<size_type>(std::distance(__first, __last));
-  if (__n) {
-    if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) {
-      if (__cap - __sz < __n)
-        __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0);
-      __annotate_increase(__n);
-      auto __end = __copy_non_overlapping_range(__first, __last, std::__to_address(__get_pointer() + __sz));
-      traits_type::assign(*__end, value_type());
-      __set_size(__sz + __n);
-    } else {
-      const basic_string __temp(__first, __last, __alloc_);
-      append(__temp.data(), __temp.size());
-    }
-  }
-  return *this;
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, size_type __pos, size_type __n) {
@@ -2977,20 +3010,6 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz
   return append(__str.data() + __pos, std::min(__n, __sz - __pos));
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp,
-          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
-                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-                        int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) {
-  __self_view __sv = __t;
-  size_type __sz   = __sv.size();
-  if (__pos > __sz)
-    __throw_out_of_range();
-  return append(__sv.data() + __pos, std::min(__n, __sz - __pos));
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) {
@@ -3055,23 +3074,6 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n
   return *this;
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
-basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) {
-  const basic_string __temp(__first, __last, __alloc_);
-  return insert(__pos, __temp.data(), __temp.data() + __temp.size());
-}
-
-template <class _CharT, class _Traits, class _Allocator>
-template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
-basic_string<_CharT, _Traits, _Allocator>::insert(
-    const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) {
-  auto __n = static_cast<size_type>(std::distance(__first, __last));
-  return __insert_with_size(__pos, __first, __last, __n);
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 template <class _Iterator, class _Sentinel>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
@@ -3099,20 +3101,6 @@ basic_string<_CharT, _Traits, _Allocator>::insert(
   return insert(__pos1, __str.data() + __pos2, std::min(__n, __str_sz - __pos2));
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp,
-          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
-                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-                        int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) {
-  __self_view __sv   = __t;
-  size_type __str_sz = __sv.size();
-  if (__pos2 > __str_sz)
-    __throw_out_of_range();
-  return insert(__pos1, __sv.data() + __pos2, std::min(__n, __str_sz - __pos2));
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) {
@@ -3216,15 +3204,6 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __
   return __null_terminate_at(__p, __sz - (__n1 - __n2));
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::replace(
-    const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2) {
-  const basic_string __temp(__j1, __j2, __alloc_);
-  return replace(__i1, __i2, __temp);
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(
@@ -3235,21 +3214,6 @@ basic_string<_CharT, _Traits, _Allocator>::replace(
   return replace(__pos1, __n1, __str.data() + __pos2, std::min(__n2, __str_sz - __pos2));
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp,
-          __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value &&
-                            !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value,
-                        int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
-basic_string<_CharT, _Traits, _Allocator>::replace(
-    size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) {
-  __self_view __sv   = __t;
-  size_type __str_sz = __sv.size();
-  if (__pos2 > __str_sz)
-    __throw_out_of_range();
-  return replace(__pos1, __n1, __sv.data() + __pos2, std::min(__n2, __str_sz - __pos2));
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>&
 basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) {
@@ -3498,14 +3462,6 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, size_
   return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find(const _Tp& __t, size_type __pos) const _NOEXCEPT {
-  __self_view __sv = __t;
-  return std::__str_find<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, size_type __pos) const _NOEXCEPT {
@@ -3536,14 +3492,6 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, size
   return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __str.data(), __pos, __str.size());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, size_type __pos) const _NOEXCEPT {
-  __self_view __sv = __t;
-  return std::__str_rfind<value_type, size_type, traits_type, npos>(data(), size(), __sv.data(), __pos, __sv.size());
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, size_type __pos) const _NOEXCEPT {
@@ -3575,15 +3523,6 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s
       data(), size(), __str.data(), __pos, __str.size());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {
-  __self_view __sv = __t;
-  return std::__str_find_first_of<value_type, size_type, traits_type, npos>(
-      data(), size(), __sv.data(), __pos, __sv.size());
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, size_type __pos) const _NOEXCEPT {
@@ -3615,15 +3554,6 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st
       data(), size(), __str.data(), __pos, __str.size());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {
-  __self_view __sv = __t;
-  return std::__str_find_last_of<value_type, size_type, traits_type, npos>(
-      data(), size(), __sv.data(), __pos, __sv.size());
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, size_type __pos) const _NOEXCEPT {
@@ -3656,15 +3586,6 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(
       data(), size(), __str.data(), __pos, __str.size());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {
-  __self_view __sv = __t;
-  return std::__str_find_first_not_of<value_type, size_type, traits_type, npos>(
-      data(), size(), __sv.data(), __pos, __sv.size());
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT {
@@ -3697,15 +3618,6 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(
       data(), size(), __str.data(), __pos, __str.size());
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
-basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, size_type __pos) const _NOEXCEPT {
-  __self_view __sv = __t;
-  return std::__str_find_last_not_of<value_type, size_type, traits_type, npos>(
-      data(), size(), __sv.data(), __pos, __sv.size());
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type
 basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, size_type __pos) const _NOEXCEPT {
@@ -3722,22 +3634,6 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, size
 
 // compare
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT {
-  __self_view __sv = __t;
-  size_t __lhs_sz  = size();
-  size_t __rhs_sz  = __sv.size();
-  int __result     = traits_type::compare(data(), __sv.data(), std::min(__lhs_sz, __rhs_sz));
-  if (__result != 0)
-    return __result;
-  if (__lhs_sz < __rhs_sz)
-    return -1;
-  if (__lhs_sz > __rhs_sz)
-    return 1;
-  return 0;
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 int
 basic_string<_CharT, _Traits, _Allocator>::compare(const basic_string& __str) const _NOEXCEPT {
@@ -3762,14 +3658,6 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocato
   return __r;
 }
 
-template <class _CharT, class _Traits, class _Allocator>
-template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> >
-_LIBCPP_CONSTEXPR_SINCE_CXX20 int
-basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const _Tp& __t) const {
-  __self_view __sv = __t;
-  return compare(__pos1, __n1, __sv.data(), __sv.size());
-}
-
 template <class _CharT, class _Traits, class _Allocator>
 inline _LIBCPP_CONSTEXPR_SINCE_CXX20 int
 basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, size_type __n1, const basic_string& __str) const {



More information about the libcxx-commits mailing list