[libcxx-commits] [PATCH] D117941: [libc++] [ranges] Fix LWG3470 "convertible-to-non-slicing seems to reject valid case"

Arthur O'Dwyer via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jan 22 09:05:16 PST 2022


Quuxplusone updated this revision to Diff 402224.
Quuxplusone added a comment.

Added constexpr test, and a couple more (arguably //too// tangential) things I thought to test.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117941/new/

https://reviews.llvm.org/D117941

Files:
  libcxx/docs/Status/Cxx2bIssues.csv
  libcxx/include/__ranges/subrange.h
  libcxx/test/std/ranges/range.utility/range.subrange/lwg3470.pass.cpp


Index: libcxx/test/std/ranges/range.utility/range.subrange/lwg3470.pass.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/ranges/range.utility/range.subrange/lwg3470.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: libcpp-has-no-incomplete-ranges
+
+// class std::ranges::subrange;
+//   Test the example from LWG 3470,
+//   qualification conversions in __convertible_to_non_slicing
+
+#include <ranges>
+
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool test()
+{
+  // The example from LWG3470, using implicit conversion.
+  int a[3] = { 1, 2, 3 };
+  int* b[3] = { &a[2], &a[0], &a[1] };
+  std::ranges::subrange<const int* const*> c = b;
+  assert(c.begin() == b + 0);
+  assert(c.end() == b + 3);
+
+  // Also test CTAD and a subrange-to-subrange conversion.
+  std::same_as<std::ranges::subrange<int**>> auto d = std::ranges::subrange(b);
+  assert(d.begin() == b + 0);
+  assert(d.end() == b + 3);
+
+  std::ranges::subrange<const int* const*> e = d;
+  assert(e.begin() == b + 0);
+  assert(e.end() == b + 3);
+
+  return true;
+}
+
+int main(int, char**)
+{
+  test();
+  static_assert(test());
+
+  return 0;
+}
Index: libcxx/include/__ranges/subrange.h
===================================================================
--- libcxx/include/__ranges/subrange.h
+++ libcxx/include/__ranges/subrange.h
@@ -39,13 +39,15 @@
 #if !defined(_LIBCPP_HAS_NO_RANGES)
 
 namespace ranges {
+  template<class _From, class _To>
+  concept __uses_nonqualification_pointer_conversion =
+    is_pointer_v<_From> && is_pointer_v<_To> &&
+    !convertible_to<remove_pointer_t<_From>(*)[], remove_pointer_t<_To>(*)[]>;
+
   template<class _From, class _To>
   concept __convertible_to_non_slicing =
     convertible_to<_From, _To> &&
-    // If they're both pointers, they must have the same element type.
-    !(is_pointer_v<decay_t<_From>> &&
-      is_pointer_v<decay_t<_To>> &&
-      __different_from<remove_pointer_t<decay_t<_From>>, remove_pointer_t<decay_t<_To>>>);
+    !__uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>;
 
   template<class _Tp>
   concept __pair_like =
Index: libcxx/docs/Status/Cxx2bIssues.csv
===================================================================
--- libcxx/docs/Status/Cxx2bIssues.csv
+++ libcxx/docs/Status/Cxx2bIssues.csv
@@ -109,7 +109,7 @@
 `3392 <https://wg21.link/LWG3392>`__,"``ranges::distance()`` cannot be used on a move-only iterator with a sized sentinel","October 2021","","","|ranges|"
 `3407 <https://wg21.link/LWG3407>`__,"Some problems with the wording changes of P1739R4","October 2021","","","|ranges|"
 `3422 <https://wg21.link/LWG3422>`__,"Issues of ``seed_seq``'s constructors","October 2021","",""
-`3470 <https://wg21.link/LWG3470>`__,"``convertible-to-non-slicing`` seems to reject valid case","October 2021","","","|ranges|"
+`3470 <https://wg21.link/LWG3470>`__,"``convertible-to-non-slicing`` seems to reject valid case","October 2021","|Complete|","14.0","|ranges|"
 `3480 <https://wg21.link/LWG3480>`__,"``directory_iterator`` and ``recursive_directory_iterator`` are not C++20 ranges","October 2021","|Complete|","14.0","|ranges|"
 `3498 <https://wg21.link/LWG3498>`__,"Inconsistent ``noexcept``-specifiers for ``basic_syncbuf``","October 2021","",""
 `3535 <https://wg21.link/LWG3535>`__,"``join_view::iterator::iterator_category`` and ``::iterator_concept`` lie","October 2021","","","|ranges|"
@@ -138,4 +138,4 @@
 `3595 <https://wg21.link/LWG3595>`__,"Exposition-only classes proxy and postfix-proxy for ``common_iterator`` should be fully ``constexpr``","October 2021","","","|ranges|"
 "","","","",""
 `3645 <https://wg21.link/LWG3645>`__,"``resize_and_overwrite`` is overspecified to call its callback with lvalues", "Not voted in","|Complete|","14.0",""
-"","","","",""
\ No newline at end of file
+"","","","",""


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117941.402224.patch
Type: text/x-patch
Size: 4338 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220122/f74fda42/attachment.bin>


More information about the libcxx-commits mailing list