[libcxx-commits] [libcxx] [DRAFT] [libc++] Add `__is_transparently_comparable_v` specializations for `basic_string_view` (PR #195871)

Michael Levine via libcxx-commits libcxx-commits at lists.llvm.org
Tue May 5 08:34:52 PDT 2026


https://github.com/levinem updated https://github.com/llvm/llvm-project/pull/195871

>From a25cc50d919a949e3403f91b499f2db76a0f463b Mon Sep 17 00:00:00 2001
From: mlevine55 <mlevine55 at bloomberg.net>
Date: Tue, 5 May 2026 11:15:47 -0400
Subject: [PATCH 1/2] Added the optimizations

Signed-off-by: mlevine55 <mlevine55 at bloomberg.net>
---
 libcxx/include/string                         | 23 +++++++++++++++
 libcxx/include/string_view                    | 27 ++++++++++++++++++
 ..._transparently_comparable.compile.pass.cpp | 28 +++++++++++++++++++
 3 files changed, 78 insertions(+)

diff --git a/libcxx/include/string b/libcxx/include/string
index a00b824e5150a..82deee9085027 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -2599,6 +2599,29 @@ template <class _Comparator, class _CharT, class _Traits, class _Alloc, size_t _
 inline const bool __is_transparently_comparable_v<_Comparator, _CharT[_Np], basic_string<_CharT, _Traits, _Alloc> > =
     __is_transparently_comparable_v<_Comparator, basic_string<_CharT, _Traits, _Alloc>, const _CharT*>;
 
+template <class _Comparator, class _CharT, class _Traits, class _Alloc>
+inline const bool
+    __is_transparently_comparable_v<_Comparator,
+                                   basic_string<_CharT, _Traits, _Alloc>,
+                                   basic_string_view<_CharT, _Traits> > =
+        __desugars_to_v<__less_tag,
+                        _Comparator,
+                        basic_string<_CharT, _Traits, _Alloc>,
+                        basic_string<_CharT, _Traits, _Alloc> > ||
+        __desugars_to_v<__greater_tag,
+                        _Comparator,
+                        basic_string<_CharT, _Traits, _Alloc>,
+                        basic_string<_CharT, _Traits, _Alloc> >;
+
+template <class _Comparator, class _CharT, class _Traits, class _Alloc>
+inline const bool
+    __is_transparently_comparable_v<_Comparator,
+                                   basic_string_view<_CharT, _Traits>,
+                                   basic_string<_CharT, _Traits, _Alloc> > =
+        __is_transparently_comparable_v<_Comparator,
+                                       basic_string<_CharT, _Traits, _Alloc>,
+                                       basic_string_view<_CharT, _Traits> >;
+
 #  if _LIBCPP_STD_VER >= 17
 template <class _InputIterator,
           class _CharT     = __iterator_value_type<_InputIterator>,
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 5dd04a9ba8479..0ea8b5f3965f5 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -217,6 +217,7 @@ namespace std {
 #  include <__cstddef/ptrdiff_t.h>
 #  include <__cstddef/size_t.h>
 #  include <__functional/hash.h>
+#  include <__functional/is_transparent.h>
 #  include <__functional/unary_function.h>
 #  include <__fwd/ostream.h>
 #  include <__fwd/string.h>
@@ -234,11 +235,13 @@ namespace std {
 #  include <__ranges/size.h>
 #  include <__string/char_traits.h>
 #  include <__type_traits/is_array.h>
+#  include <__type_traits/desugars_to.h>
 #  include <__type_traits/is_convertible.h>
 #  include <__type_traits/is_same.h>
 #  include <__type_traits/is_standard_layout.h>
 #  include <__type_traits/is_trivially_constructible.h>
 #  include <__type_traits/is_trivially_copyable.h>
+#  include <__type_traits/remove_cv.h>
 #  include <__type_traits/remove_cvref.h>
 #  include <__type_traits/remove_reference.h>
 #  include <__type_traits/type_identity.h>
@@ -933,6 +936,30 @@ template <>
 struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {};
 #  endif
 
+template <class _Comparator, class _CharT2, class _CharT, class _Traits>
+inline const bool __is_transparently_comparable_v<_Comparator, basic_string_view<_CharT, _Traits>, _CharT2*> =
+    is_same<_CharT, __remove_cv_t<_CharT2> >::value &&
+    (__desugars_to_v<__less_tag,
+                     _Comparator,
+                     basic_string_view<_CharT, _Traits>,
+                     basic_string_view<_CharT, _Traits> > ||
+     __desugars_to_v<__greater_tag,
+                     _Comparator,
+                     basic_string_view<_CharT, _Traits>,
+                     basic_string_view<_CharT, _Traits> >);
+
+template <class _Comparator, class _CharT2, class _CharT, class _Traits>
+inline const bool __is_transparently_comparable_v<_Comparator, _CharT2*, basic_string_view<_CharT, _Traits> > =
+    __is_transparently_comparable_v<_Comparator, basic_string_view<_CharT, _Traits>, _CharT2*>;
+
+template <class _Comparator, class _CharT, class _Traits, size_t _Np>
+inline const bool __is_transparently_comparable_v<_Comparator, basic_string_view<_CharT, _Traits>, _CharT[_Np]> =
+    __is_transparently_comparable_v<_Comparator, basic_string_view<_CharT, _Traits>, const _CharT*>;
+
+template <class _Comparator, class _CharT, class _Traits, size_t _Np>
+inline const bool __is_transparently_comparable_v<_Comparator, _CharT[_Np], basic_string_view<_CharT, _Traits> > =
+    __is_transparently_comparable_v<_Comparator, basic_string_view<_CharT, _Traits>, const _CharT*>;
+
 #  if _LIBCPP_STD_VER >= 14
 inline namespace literals {
 inline namespace string_view_literals {
diff --git a/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp b/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp
index 8ab8cb0be8418..870a77cf33abc 100644
--- a/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp
+++ b/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp
@@ -10,8 +10,10 @@
 
 #include <functional>
 #include <string>
+#include <string_view>
 #include <__type_traits/desugars_to.h>
 
+// basic_string with char pointers/arrays
 static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string, const char*>, "");
 static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string, char*>, "");
 static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string, char[5]>, "");
@@ -30,3 +32,29 @@ static_assert(
 static_assert(
     !std::__is_transparently_comparable_v<std::less<std::reference_wrapper<std::string> >, char const*, std::string>,
     "");
+
+// basic_string_view with char pointers/arrays
+static_assert(
+    std::__is_transparently_comparable_v<std::less<std::string_view>, std::string_view, const char*>, "");
+static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, std::string_view, char*>, "");
+static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, std::string_view, char[5]>, "");
+
+static_assert(
+    std::__is_transparently_comparable_v<std::less<std::string_view>, const char*, std::string_view>, "");
+static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, char*, std::string_view>, "");
+static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, char[5], std::string_view>, "");
+
+static_assert(
+    !std::__is_transparently_comparable_v<std::less<std::reference_wrapper<std::string_view> >,
+                                          std::string_view,
+                                          const char*>,
+    "");
+static_assert(
+    !std::__is_transparently_comparable_v<std::less<std::reference_wrapper<std::string_view> >,
+                                          const char*,
+                                          std::string_view>,
+    "");
+
+// Cross-type: basic_string key with basic_string_view argument
+static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string, std::string_view>, "");
+static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string_view, std::string>, "");

>From 5346d22c9a0b48debfa51a701acad833858f2d6d Mon Sep 17 00:00:00 2001
From: mlevine55 <mlevine55 at bloomberg.net>
Date: Tue, 5 May 2026 11:34:11 -0400
Subject: [PATCH 2/2] clang-format

Signed-off-by: mlevine55 <mlevine55 at bloomberg.net>
---
 libcxx/include/string                         | 54 +++++++++----------
 libcxx/include/string_view                    |  2 +-
 ..._transparently_comparable.compile.pass.cpp | 24 ++++-----
 3 files changed, 37 insertions(+), 43 deletions(-)

diff --git a/libcxx/include/string b/libcxx/include/string
index 82deee9085027..c9bc3336e8be4 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -1735,8 +1735,8 @@ public:
   _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type copy(value_type* __s, size_type __n, size_type __pos = 0) const;
 
 #  if _LIBCPP_STD_VER <= 20
-  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI
-  _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string substr(size_type __pos = 0, size_type __n = npos) const {
+  [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string
+  substr(size_type __pos = 0, size_type __n = npos) const {
     return basic_string(*this, __pos, __n);
   }
 #  else
@@ -2600,27 +2600,25 @@ inline const bool __is_transparently_comparable_v<_Comparator, _CharT[_Np], basi
     __is_transparently_comparable_v<_Comparator, basic_string<_CharT, _Traits, _Alloc>, const _CharT*>;
 
 template <class _Comparator, class _CharT, class _Traits, class _Alloc>
-inline const bool
-    __is_transparently_comparable_v<_Comparator,
-                                   basic_string<_CharT, _Traits, _Alloc>,
-                                   basic_string_view<_CharT, _Traits> > =
-        __desugars_to_v<__less_tag,
-                        _Comparator,
-                        basic_string<_CharT, _Traits, _Alloc>,
-                        basic_string<_CharT, _Traits, _Alloc> > ||
-        __desugars_to_v<__greater_tag,
-                        _Comparator,
-                        basic_string<_CharT, _Traits, _Alloc>,
-                        basic_string<_CharT, _Traits, _Alloc> >;
+inline const bool __is_transparently_comparable_v<_Comparator,
+                                                  basic_string<_CharT, _Traits, _Alloc>,
+                                                  basic_string_view<_CharT, _Traits> > =
+    __desugars_to_v<__less_tag,
+                    _Comparator,
+                    basic_string<_CharT, _Traits, _Alloc>,
+                    basic_string<_CharT, _Traits, _Alloc> > ||
+    __desugars_to_v<__greater_tag,
+                    _Comparator,
+                    basic_string<_CharT, _Traits, _Alloc>,
+                    basic_string<_CharT, _Traits, _Alloc> >;
 
 template <class _Comparator, class _CharT, class _Traits, class _Alloc>
-inline const bool
+inline const bool __is_transparently_comparable_v<_Comparator,
+                                                  basic_string_view<_CharT, _Traits>,
+                                                  basic_string<_CharT, _Traits, _Alloc> > =
     __is_transparently_comparable_v<_Comparator,
-                                   basic_string_view<_CharT, _Traits>,
-                                   basic_string<_CharT, _Traits, _Alloc> > =
-        __is_transparently_comparable_v<_Comparator,
-                                       basic_string<_CharT, _Traits, _Alloc>,
-                                       basic_string_view<_CharT, _Traits> >;
+                                    basic_string<_CharT, _Traits, _Alloc>,
+                                    basic_string_view<_CharT, _Traits> >;
 
 #  if _LIBCPP_STD_VER >= 17
 template <class _InputIterator,
@@ -2635,8 +2633,8 @@ template <class _CharT,
           class _Traits,
           class _Allocator = allocator<_CharT>,
           class            = enable_if_t<__is_allocator_v<_Allocator>>>
-explicit basic_string(basic_string_view<_CharT, _Traits>, const _Allocator& = _Allocator())
-    -> basic_string<_CharT, _Traits, _Allocator>;
+explicit basic_string(basic_string_view<_CharT, _Traits>,
+                      const _Allocator& = _Allocator()) -> basic_string<_CharT, _Traits, _Allocator>;
 
 template <class _CharT,
           class _Traits,
@@ -3977,21 +3975,21 @@ operator""s(const char* __str, size_t __len) {
 }
 
 #    if _LIBCPP_HAS_WIDE_CHARACTERS
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t> operator""s(const wchar_t* __str, size_t __len) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<wchar_t>
+operator""s(const wchar_t* __str, size_t __len) {
   return basic_string<wchar_t>(__str, __len);
 }
 #    endif
 
 #    if _LIBCPP_HAS_CHAR8_T
-[[__nodiscard__]] inline
-    _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t> operator""s(const char8_t* __str, size_t __len) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI constexpr basic_string<char8_t>
+operator""s(const char8_t* __str, size_t __len) {
   return basic_string<char8_t>(__str, __len);
 }
 #    endif
 
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI
-_LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t> operator""s(const char16_t* __str, size_t __len) {
+[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<char16_t>
+operator""s(const char16_t* __str, size_t __len) {
   return basic_string<char16_t>(__str, __len);
 }
 
diff --git a/libcxx/include/string_view b/libcxx/include/string_view
index 0ea8b5f3965f5..6dc3af94bb99f 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -234,8 +234,8 @@ namespace std {
 #  include <__ranges/enable_view.h>
 #  include <__ranges/size.h>
 #  include <__string/char_traits.h>
-#  include <__type_traits/is_array.h>
 #  include <__type_traits/desugars_to.h>
+#  include <__type_traits/is_array.h>
 #  include <__type_traits/is_convertible.h>
 #  include <__type_traits/is_same.h>
 #  include <__type_traits/is_standard_layout.h>
diff --git a/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp b/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp
index 870a77cf33abc..d02f5713ce777 100644
--- a/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp
+++ b/libcxx/test/libcxx/type_traits/is_transparently_comparable.compile.pass.cpp
@@ -34,26 +34,22 @@ static_assert(
     "");
 
 // basic_string_view with char pointers/arrays
-static_assert(
-    std::__is_transparently_comparable_v<std::less<std::string_view>, std::string_view, const char*>, "");
+static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, std::string_view, const char*>, "");
 static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, std::string_view, char*>, "");
 static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, std::string_view, char[5]>, "");
 
-static_assert(
-    std::__is_transparently_comparable_v<std::less<std::string_view>, const char*, std::string_view>, "");
+static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, const char*, std::string_view>, "");
 static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, char*, std::string_view>, "");
 static_assert(std::__is_transparently_comparable_v<std::less<std::string_view>, char[5], std::string_view>, "");
 
-static_assert(
-    !std::__is_transparently_comparable_v<std::less<std::reference_wrapper<std::string_view> >,
-                                          std::string_view,
-                                          const char*>,
-    "");
-static_assert(
-    !std::__is_transparently_comparable_v<std::less<std::reference_wrapper<std::string_view> >,
-                                          const char*,
-                                          std::string_view>,
-    "");
+static_assert(!std::__is_transparently_comparable_v<std::less<std::reference_wrapper<std::string_view> >,
+                                                    std::string_view,
+                                                    const char*>,
+              "");
+static_assert(!std::__is_transparently_comparable_v<std::less<std::reference_wrapper<std::string_view> >,
+                                                    const char*,
+                                                    std::string_view>,
+              "");
 
 // Cross-type: basic_string key with basic_string_view argument
 static_assert(std::__is_transparently_comparable_v<std::less<std::string>, std::string, std::string_view>, "");



More information about the libcxx-commits mailing list