[libcxx-commits] [libcxx] 83014d8 - [libc++] LWG 3857: allow `string_view` conversion when only traits vary

Joe Loser via libcxx-commits libcxx-commits at lists.llvm.org
Thu Feb 16 05:00:47 PST 2023


Author: Joe Loser
Date: 2023-02-16T06:00:01-07:00
New Revision: 83014d877017a796f89e4bb81347132619731bf9

URL: https://github.com/llvm/llvm-project/commit/83014d877017a796f89e4bb81347132619731bf9
DIFF: https://github.com/llvm/llvm-project/commit/83014d877017a796f89e4bb81347132619731bf9.diff

LOG: [libc++] LWG 3857: allow `string_view` conversion when only traits vary

The `basic_string_view` constructor accepting a contiguous range rejects
converting between `basic_string_view` even when only the trait types vary.
This prevents conversions for converting from `basic_string_view<C, T1>` and
`basic_string<C, T1, A>` to `basic_string_view<C, T2>`.  Recently, this
constructor was made `explicit`, so there's no reason to really forbid this
conversion anymore.

Relax the restriction that the trait types need to match in this constructor.

Differential Revision: https://reviews.llvm.org/D143972

Added: 
    

Modified: 
    libcxx/docs/Status/Cxx2bIssues.csv
    libcxx/include/string_view
    libcxx/test/std/strings/string.view/string.view.cons/from_range.pass.cpp

Removed: 
    libcxx/test/std/strings/string.view/string.view.cons/from_string1.compile.fail.cpp
    libcxx/test/std/strings/string.view/string.view.cons/from_string2.compile.fail.cpp


################################################################################
diff  --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index afd10e9f59bfc..6162e72f4867b 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -272,7 +272,7 @@
 "`3850 <https://wg21.link/LWG3850>`__","``views::as_const`` on ``empty_view<T>`` should return ``empty_view<const T>``","February 2023","","","|ranges|"
 "`3851 <https://wg21.link/LWG3851>`__","``chunk_view::inner-iterator`` missing custom ``iter_move`` and ``iter_swap``","February 2023","","","|ranges|"
 "`3853 <https://wg21.link/LWG3853>`__","``basic_const_iterator<volatile int*>::operator->`` is ill-formed","February 2023","","",""
-"`3857 <https://wg21.link/LWG3857>`__","``basic_string_view`` should allow explicit conversion when only traits vary","February 2023","","",""
+"`3857 <https://wg21.link/LWG3857>`__","``basic_string_view`` should allow explicit conversion when only traits vary","February 2023","|Complete|","17.0",""
 "`3860 <https://wg21.link/LWG3860>`__","``range_common_reference_t`` is missing","February 2023","","","|ranges|"
 "`3866 <https://wg21.link/LWG3866>`__","Bad Mandates for ``expected::transform_error`` overloads","February 2023","","",""
 "`3867 <https://wg21.link/LWG3867>`__","Should ``std::basic_osyncstream``'s move assignment operator be ``noexcept``?","February 2023","","",""

diff  --git a/libcxx/include/string_view b/libcxx/include/string_view
index 41b70a2dbb017..052e0981618b8 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -323,10 +323,7 @@ public:
         !is_convertible_v<_Range, const _CharT*> &&
         (!requires(remove_cvref_t<_Range>& __d) {
           __d.operator _VSTD::basic_string_view<_CharT, _Traits>();
-        }) &&
-        (!requires {
-         typename remove_reference_t<_Range>::traits_type;
-        } || is_same_v<typename remove_reference_t<_Range>::traits_type, _Traits>)
+        })
       )
     constexpr explicit _LIBCPP_HIDE_FROM_ABI
     basic_string_view(_Range&& __r) : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}

diff  --git a/libcxx/test/std/strings/string.view/string.view.cons/from_range.pass.cpp b/libcxx/test/std/strings/string.view/string.view.cons/from_range.pass.cpp
index a645827c59359..4ea963d925495 100644
--- a/libcxx/test/std/strings/string.view/string.view.cons/from_range.pass.cpp
+++ b/libcxx/test/std/strings/string.view/string.view.cons/from_range.pass.cpp
@@ -20,7 +20,6 @@
 #include <type_traits>
 #include <vector>
 
-#include "constexpr_char_traits.h"
 #include "make_string.h"
 #include "test_iterators.h"
 #include "test_range.h"
@@ -107,6 +106,15 @@ constexpr bool test() {
     assert(sv == "test");
   }
 
+  // Different trait types
+  {
+    struct OtherTraits : std::char_traits<char> {};
+    std::basic_string_view<char> sv1{"hello"};
+    std::basic_string_view<char, OtherTraits> sv2(sv1);
+    assert(sv1.size() == sv2.size());
+    assert(sv1.data() == sv2.data());
+  }
+
   return true;
 }
 
@@ -135,25 +143,7 @@ struct WithStringViewConversionOperator {
 
 static_assert(std::is_constructible_v<std::string_view, WithStringViewConversionOperator>); // lvalue
 static_assert(std::is_constructible_v<std::string_view, const WithStringViewConversionOperator&>); // const lvalue
-static_assert(std::is_constructible_v<std::string_view, WithStringViewConversionOperator&&>); // rvalue
-
-template <class CharTraits>
-struct WithTraitsType {
-  typename CharTraits::char_type* begin() const;
-  typename CharTraits::char_type* end() const;
-  using traits_type = CharTraits;
-};
-
-using CCT = constexpr_char_traits<char>;
-static_assert(std::is_constructible_v<std::string_view, WithTraitsType<std::char_traits<char>>>);
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(std::is_constructible_v<std::wstring_view, WithTraitsType<std::char_traits<wchar_t>>>);
-#endif
-static_assert(std::is_constructible_v<std::basic_string_view<char, CCT>, WithTraitsType<CCT>>);
-static_assert(!std::is_constructible_v<std::string_view, WithTraitsType<CCT>>);  // wrong traits type
-#ifndef TEST_HAS_NO_WIDE_CHARACTERS
-static_assert(!std::is_constructible_v<std::wstring_view, WithTraitsType<std::char_traits<char>>>);  // wrong traits type
-#endif
+static_assert(std::is_constructible_v<std::string_view, WithStringViewConversionOperator&&>);      // rvalue
 
 #ifndef TEST_HAS_NO_EXCEPTIONS
 void test_throwing() {

diff  --git a/libcxx/test/std/strings/string.view/string.view.cons/from_string1.compile.fail.cpp b/libcxx/test/std/strings/string.view/string.view.cons/from_string1.compile.fail.cpp
deleted file mode 100644
index e4cf136f54ab9..0000000000000
--- a/libcxx/test/std/strings/string.view/string.view.cons/from_string1.compile.fail.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: !stdlib=libc++ && (c++03 || c++11 || c++14)
-
-// <string_view>
-
-// template<class Allocator>
-// basic_string_view(const basic_string<_CharT, _Traits, Allocator>& _str) noexcept
-
-#include <string_view>
-#include <string>
-#include <cassert>
-
-struct dummy_char_traits : public std::char_traits<char> {};
-
-int main(int, char**) {
-    using string_view = std::basic_string_view<char>;
-    using string      = std::              basic_string     <char, dummy_char_traits>;
-
-    {
-    string s{"QBCDE"};
-    string_view sv1 ( s );
-    assert ( sv1.size() == s.size());
-    assert ( sv1.data() == s.data());
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/strings/string.view/string.view.cons/from_string2.compile.fail.cpp b/libcxx/test/std/strings/string.view/string.view.cons/from_string2.compile.fail.cpp
deleted file mode 100644
index 30540eebe0fa4..0000000000000
--- a/libcxx/test/std/strings/string.view/string.view.cons/from_string2.compile.fail.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: !stdlib=libc++ && (c++03 || c++11 || c++14)
-
-// <string_view>
-
-// template<class Allocator>
-// basic_string_view(const basic_string<_CharT, _Traits, Allocator>& _str) noexcept
-
-#include <string_view>
-#include <string>
-#include <cassert>
-
-struct dummy_char_traits : public std::char_traits<char> {};
-
-int main(int, char**) {
-    using string_view = std::basic_string_view<char, dummy_char_traits>;
-    using string      = std::              basic_string     <char>;
-
-    {
-    string s{"QBCDE"};
-    string_view sv1 ( s );
-    assert ( sv1.size() == s.size());
-    assert ( sv1.data() == s.data());
-    }
-
-  return 0;
-}


        


More information about the libcxx-commits mailing list