[libcxx-commits] [libcxx] 4a47ac7 - [libc++] Remove incorrect default constructor in cpp17_input_iterator

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jan 4 11:34:11 PST 2022


Author: Louis Dionne
Date: 2022-01-04T14:33:51-05:00
New Revision: 4a47ac7d514c151883a0b9a98f7c3071229c13a5

URL: https://github.com/llvm/llvm-project/commit/4a47ac7d514c151883a0b9a98f7c3071229c13a5
DIFF: https://github.com/llvm/llvm-project/commit/4a47ac7d514c151883a0b9a98f7c3071229c13a5.diff

LOG: [libc++] Remove incorrect default constructor in cpp17_input_iterator

AFAICT, Cpp17InputIterators are not required to be default constructible,
since that requirement is added in Cpp17ForwardIterator. Hence, our
archetype for Cpp17InputIterator should not be default constructible.
Removing that constructor has a ripple effect on a couple of tests that
were making incorrect assumptions. Notably:

- Some tests were using cpp17_input_iterator as a sentinel for itself.
  That is not valid, because a cpp17_input_iterator is not semiregular
  anymore after the change (and hence it doesn't satisfy sentinel_for).

- Some tests were using a stride-counted cpp17_input_iterator as the
  sentinel for a range. This doesn't work anymore because of the problem
  above, so these tests were changed not to check stride counts for
  input iterators.

- Some tests were default constructing cpp17_input_iterator when a simple
  alternative was available -- those have been changed to use that alternative.

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

Added: 
    

Modified: 
    libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.addressof.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
    libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_sentinel.pass.cpp
    libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_count_sentinel.pass.cpp
    libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_sentinel.pass.cpp
    libcxx/test/std/iterators/predef.iterators/counted.iterator/ctor.default.pass.cpp
    libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp
    libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp
    libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/ctor.default.pass.cpp
    libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/member_types.compile.pass.cpp
    libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp
    libcxx/test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp
    libcxx/test/std/ranges/range.req/range.refinements/input_range.compile.pass.cpp
    libcxx/test/std/ranges/range.utility/range.subrange/advance.pass.cpp
    libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
    libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
    libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
    libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
    libcxx/test/support/test_iterators.h

Removed: 
    


################################################################################
diff  --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.addressof.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.addressof.compile.pass.cpp
index a8eb860e6487..f8311090b37e 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.addressof.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.addressof.compile.pass.cpp
@@ -19,10 +19,9 @@
 #include "operator_hijacker.h"
 #include "test_iterators.h"
 
-void test() {
+void test(cpp17_input_iterator<operator_hijacker*> i) {
   {
     std::vector<operator_hijacker> v;
-    cpp17_input_iterator<std::vector<operator_hijacker>::iterator> i;
     v.insert(v.end(), i, i);
   }
   {

diff  --git a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
index 19475c3d07e8..ca8dcb8474c6 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.modifiers/insert_iter_iter_iter.pass.cpp
@@ -179,7 +179,7 @@ int main(int, char**)
 
     {
         std::vector<adl::S> s;
-        s.insert(s.end(), cpp17_input_iterator<adl::S*>(), cpp17_input_iterator<adl::S*>());
+        s.insert(s.end(), cpp17_input_iterator<adl::S*>(nullptr), cpp17_input_iterator<adl::S*>(nullptr));
     }
 
   return 0;

diff  --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_sentinel.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_sentinel.pass.cpp
index 165b0b063e98..90f9aba1b7ff 100644
--- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_sentinel.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.advance/iterator_sentinel.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <array>
 #include <cassert>
+#include <cstddef>
 
 #include "test_iterators.h"
 
@@ -44,61 +45,103 @@ class distance_apriori_sentinel {
   std::ptr
diff _t count_ = 0;
 };
 
-template <std::input_or_output_iterator It, std::sentinel_for<It> Sent = It>
-constexpr void check_assignable_case(std::ptr
diff _t const n) {
+template <class It, class Sent = It>
+constexpr void check_assignable_case() {
   auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
-  auto first = stride_counting_iterator(It(range.begin()));
-  std::ranges::advance(first, stride_counting_iterator(Sent(It(range.begin() + n))));
-  assert(first.base().base() == range.begin() + n);
-  assert(first.stride_count() == 0); // because we got here by assigning from last, not by incrementing
+
+  for (std::ptr
diff _t n = 0; n != 9; ++n) {
+    {
+      It first(range.begin());
+      Sent last(It(range.begin() + n));
+      std::ranges::advance(first, last);
+      assert(base(first) == range.begin() + n);
+    }
+
+    // Count operations
+    if constexpr (std::is_same_v<It, Sent>) {
+      stride_counting_iterator<It> first(It(range.begin()));
+      stride_counting_iterator<It> last(It(range.begin() + n));
+      std::ranges::advance(first, last);
+      assert(first.base().base() == range.begin() + n);
+      assert(first.stride_count() == 0); // because we got here by assigning from last, not by incrementing
+    }
+  }
 }
 
-template <std::input_or_output_iterator It>
-constexpr void check_sized_sentinel_case(std::ptr
diff _t const n) {
+template <class It>
+constexpr void check_sized_sentinel_case() {
   auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
-  auto first = stride_counting_iterator(It(range.begin()));
-  std::ranges::advance(first, distance_apriori_sentinel(n));
-
-  assert(first.base().base() == range.begin() + n);
-  if constexpr (std::random_access_iterator<It>) {
-    assert(first.stride_count() == 1);
-    assert(first.stride_displacement() == 1);
-  } else {
-    assert(first.stride_count() == n);
-    assert(first.stride_displacement() == n);
+
+  for (std::ptr
diff _t n = 0; n != 9; ++n) {
+    {
+      It first(range.begin());
+      distance_apriori_sentinel last(n);
+      std::ranges::advance(first, last);
+      assert(base(first) == range.begin() + n);
+    }
+
+    // Count operations
+    {
+      stride_counting_iterator<It> first(It(range.begin()));
+      distance_apriori_sentinel last(n);
+      std::ranges::advance(first, last);
+
+      assert(first.base().base() == range.begin() + n);
+      if constexpr (std::random_access_iterator<It>) {
+        assert(first.stride_count() == 1);
+        assert(first.stride_displacement() == 1);
+      } else {
+        assert(first.stride_count() == n);
+        assert(first.stride_displacement() == n);
+      }
+    }
   }
 }
 
-template <std::input_or_output_iterator It>
-constexpr void check_sentinel_case(std::ptr
diff _t const n) {
+template <class It>
+constexpr void check_sentinel_case() {
   auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
-  auto first = stride_counting_iterator(It(range.begin()));
-  auto const last = It(range.begin() + n);
-  std::ranges::advance(first, sentinel_wrapper(last));
-  assert(first.base() == last);
-  assert(first.stride_count() == n);
+
+  for (std::ptr
diff _t n = 0; n != 9; ++n) {
+    {
+      It first(range.begin());
+      sentinel_wrapper<It> last(It(range.begin() + n));
+      std::ranges::advance(first, last);
+      assert(base(first) == range.begin() + n);
+    }
+
+    // Count operations
+    {
+      stride_counting_iterator<It> first(It(range.begin()));
+      sentinel_wrapper<It> last(It(range.begin() + n));
+      std::ranges::advance(first, last);
+      assert(first.base() == last);
+      assert(first.stride_count() == n);
+    }
+  }
 }
 
 constexpr bool test() {
-  check_assignable_case<cpp17_input_iterator<range_t::const_iterator> >(1);
-  check_assignable_case<forward_iterator<range_t::const_iterator> >(3);
-  check_assignable_case<bidirectional_iterator<range_t::const_iterator> >(4);
-  check_assignable_case<random_access_iterator<range_t::const_iterator> >(5);
-  check_assignable_case<contiguous_iterator<range_t::const_iterator> >(6);
-
-  check_sized_sentinel_case<cpp17_input_iterator<range_t::const_iterator> >(7);
-  check_sized_sentinel_case<cpp20_input_iterator<range_t::const_iterator> >(6);
-  check_sized_sentinel_case<forward_iterator<range_t::const_iterator> >(5);
-  check_sized_sentinel_case<bidirectional_iterator<range_t::const_iterator> >(4);
-  check_sized_sentinel_case<random_access_iterator<range_t::const_iterator> >(3);
-  check_sized_sentinel_case<contiguous_iterator<range_t::const_iterator> >(2);
-
-  check_sentinel_case<cpp17_input_iterator<range_t::const_iterator> >(1);
+  using It = range_t::const_iterator;
+  check_assignable_case<cpp17_input_iterator<It>, sentinel_wrapper<cpp17_input_iterator<It>>>();
+  check_assignable_case<forward_iterator<It>>();
+  check_assignable_case<bidirectional_iterator<It>>();
+  check_assignable_case<random_access_iterator<It>>();
+  check_assignable_case<contiguous_iterator<It>>();
+
+  check_sized_sentinel_case<cpp17_input_iterator<It>>();
+  check_sized_sentinel_case<cpp20_input_iterator<It>>();
+  check_sized_sentinel_case<forward_iterator<It>>();
+  check_sized_sentinel_case<bidirectional_iterator<It>>();
+  check_sized_sentinel_case<random_access_iterator<It>>();
+  check_sized_sentinel_case<contiguous_iterator<It>>();
+
+  check_sentinel_case<cpp17_input_iterator<It>>();
   // cpp20_input_iterator not copyable, so is omitted
-  check_sentinel_case<forward_iterator<range_t::const_iterator> >(3);
-  check_sentinel_case<bidirectional_iterator<range_t::const_iterator> >(4);
-  check_sentinel_case<random_access_iterator<range_t::const_iterator> >(5);
-  check_sentinel_case<contiguous_iterator<range_t::const_iterator> >(6);
+  check_sentinel_case<forward_iterator<It>>();
+  check_sentinel_case<bidirectional_iterator<It>>();
+  check_sentinel_case<random_access_iterator<It>>();
+  check_sentinel_case<contiguous_iterator<It>>();
   return true;
 }
 

diff  --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_count_sentinel.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_count_sentinel.pass.cpp
index 3554a34011d2..3c0e9d89ea64 100644
--- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_count_sentinel.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_count_sentinel.pass.cpp
@@ -13,18 +13,19 @@
 
 #include <iterator>
 #include <cassert>
+#include <type_traits>
 
 #include "test_iterators.h"
 
-template <std::input_or_output_iterator It>
-constexpr void check(It it, std::ptr
diff _t n, It last) {
+template <class It, class Sent = It>
+constexpr void check(It it, std::ptr
diff _t n, Sent last) {
   {
     It result = std::ranges::next(it, n, last);
     assert(result == last);
   }
 
   // Count the number of operations
-  {
+  if constexpr (std::is_same_v<It, Sent>) {
     stride_counting_iterator<It> strided_it(it);
     stride_counting_iterator<It> strided_last(last);
     stride_counting_iterator<It> result = std::ranges::next(strided_it, n, strided_last);
@@ -46,13 +47,13 @@ constexpr void check(It it, std::ptr
diff _t n, It last) {
 constexpr bool test() {
   int range[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
 
-  check(cpp17_input_iterator(&range[0]), 1, cpp17_input_iterator(&range[1]));
+  check(cpp17_input_iterator(&range[0]), 1, sentinel_wrapper(cpp17_input_iterator(&range[1])));
   check(forward_iterator(&range[0]), 2, forward_iterator(&range[2]));
   check(bidirectional_iterator(&range[2]), 6, bidirectional_iterator(&range[8]));
   check(random_access_iterator(&range[3]), 2, random_access_iterator(&range[5]));
   check(contiguous_iterator(&range[0]), 5, contiguous_iterator(&range[5]));
 
-  check(cpp17_input_iterator(&range[0]), 0, cpp17_input_iterator(&range[0]));
+  check(cpp17_input_iterator(&range[0]), 0, sentinel_wrapper(cpp17_input_iterator(&range[0])));
   check(forward_iterator(&range[0]), 0, forward_iterator(&range[0]));
   check(bidirectional_iterator(&range[2]), 0, bidirectional_iterator(&range[2]));
   check(random_access_iterator(&range[3]), 0, random_access_iterator(&range[3]));

diff  --git a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_sentinel.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_sentinel.pass.cpp
index 354cdffeae5e..545e01b547b6 100644
--- a/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_sentinel.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.primitives/range.iter.ops/range.iter.ops.next/iterator_sentinel.pass.cpp
@@ -21,6 +21,20 @@
 
 using range_t = std::array<int, 10>;
 
+// Sentinel type that can be assigned to an iterator. This is to test the case where
+// std::ranges::next uses assignment instead of successive increments below.
+template <class It>
+class assignable_sentinel {
+public:
+    explicit assignable_sentinel() = default;
+    constexpr explicit assignable_sentinel(const It& it) : base_(base(it)) {}
+    constexpr operator It() const { return It(base_); }
+    constexpr bool operator==(const It& other) const { return base_ == base(other); }
+    friend constexpr It base(const assignable_sentinel& s) { return It(s.base_); }
+private:
+    decltype(base(std::declval<It>())) base_;
+};
+
 class distance_apriori_sentinel {
 public:
   distance_apriori_sentinel() = default;
@@ -45,39 +59,39 @@ class distance_apriori_sentinel {
   std::ptr
diff _t count_ = 0;
 };
 
-template <std::input_or_output_iterator It>
-constexpr void check_assignable(It it, It last, int const* expected) {
+template <bool Count, typename It>
+constexpr void check_assignable(int* it, int* last, int const* expected) {
   {
-    It result = std::ranges::next(std::move(it), std::move(last));
-    assert(&*result == expected);
+    It result = std::ranges::next(It(it), assignable_sentinel(It(last)));
+    assert(base(result) == expected);
   }
 
   // Count operations
-  {
-    auto strided_it = stride_counting_iterator(std::move(it));
-    auto strided_last = stride_counting_iterator(std::move(last));
-    auto result = std::ranges::next(std::move(strided_it), std::move(strided_last));
-    assert(&*result == expected);
+  if constexpr (Count) {
+    auto strided_it = stride_counting_iterator(It(it));
+    auto strided_last = assignable_sentinel(stride_counting_iterator(It(last)));
+    stride_counting_iterator<It> result = std::ranges::next(std::move(strided_it), std::move(strided_last));
+    assert(base(result.base()) == expected);
     assert(result.stride_count() == 0); // because we got here by assigning from last, not by incrementing
   }
 }
 
-template <std::input_or_output_iterator It>
-constexpr void check_sized_sentinel(It it, It last, int const* expected) {
-  auto n = (last.base() - it.base());
+template <typename It>
+constexpr void check_sized_sentinel(int* it, int* last, int const* expected) {
+  auto n = (last - it);
 
   {
     auto sent = distance_apriori_sentinel(n);
-    auto result = std::ranges::next(std::move(it), sent);
-    assert(&*result == expected);
+    auto result = std::ranges::next(It(it), sent);
+    assert(base(result) == expected);
   }
 
   // Count operations
   {
-    auto strided_it = stride_counting_iterator(std::move(it));
+    auto strided_it = stride_counting_iterator(It(it));
     auto sent = distance_apriori_sentinel(n);
     auto result = std::ranges::next(std::move(strided_it), sent);
-    assert(&*result == expected);
+    assert(base(result.base()) == expected);
 
     if constexpr (std::random_access_iterator<It>) {
       assert(result.stride_count() == 1); // should have used exactly one +=
@@ -89,22 +103,22 @@ constexpr void check_sized_sentinel(It it, It last, int const* expected) {
   }
 }
 
-template <std::input_or_output_iterator It>
-constexpr void check_sentinel(It it, It last, int const* expected) {
-  auto n = (last.base() - it.base());
+template <bool Count, typename It>
+constexpr void check_sentinel(int* it, int* last, int const* expected) {
+  auto n = (last - it);
 
   {
-    auto sent = sentinel_wrapper(last);
-    It result = std::ranges::next(std::move(it), sent);
-    assert(&*result == expected);
+    auto sent = sentinel_wrapper(It(last));
+    It result = std::ranges::next(It(it), sent);
+    assert(base(result) == expected);
   }
 
   // Count operations
-  {
-    auto strided_it = stride_counting_iterator(it);
-    auto sent = sentinel_wrapper(stride_counting_iterator(last));
+  if constexpr (Count) {
+    auto strided_it = stride_counting_iterator(It(it));
+    auto sent = sentinel_wrapper(stride_counting_iterator(It(last)));
     stride_counting_iterator result = std::ranges::next(std::move(strided_it), sent);
-    assert(&*result == expected);
+    assert(base(result.base()) == expected);
     assert(result.stride_count() == n); // must have used ++ until it hit the sentinel
   }
 }
@@ -112,25 +126,25 @@ constexpr void check_sentinel(It it, It last, int const* expected) {
 constexpr bool test() {
   int range[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
 
-  check_assignable(cpp17_input_iterator(&range[0]), cpp17_input_iterator(&range[2]), &range[2]);
-  check_assignable(forward_iterator(&range[0]), forward_iterator(&range[3]), &range[3]);
-  check_assignable(bidirectional_iterator(&range[0]), bidirectional_iterator(&range[4]), &range[4]);
-  check_assignable(random_access_iterator(&range[0]), random_access_iterator(&range[5]), &range[5]);
-  check_assignable(contiguous_iterator(&range[0]), contiguous_iterator(&range[6]), &range[6]);
+  check_assignable<false, cpp17_input_iterator<int*>>(  &range[0], &range[2], &range[2]);
+  check_assignable<true,  forward_iterator<int*>>(      &range[0], &range[3], &range[3]);
+  check_assignable<true,  bidirectional_iterator<int*>>(&range[0], &range[4], &range[4]);
+  check_assignable<true,  random_access_iterator<int*>>(&range[0], &range[5], &range[5]);
+  check_assignable<true,  contiguous_iterator<int*>>(   &range[0], &range[6], &range[6]);
 
-  check_sized_sentinel(cpp17_input_iterator(&range[0]), cpp17_input_iterator(&range[7]), &range[7]);
-  check_sized_sentinel(cpp20_input_iterator(&range[0]), cpp20_input_iterator(&range[6]), &range[6]);
-  check_sized_sentinel(forward_iterator(&range[0]), forward_iterator(&range[5]), &range[5]);
-  check_sized_sentinel(bidirectional_iterator(&range[0]), bidirectional_iterator(&range[4]), &range[4]);
-  check_sized_sentinel(random_access_iterator(&range[0]), random_access_iterator(&range[3]), &range[3]);
-  check_sized_sentinel(contiguous_iterator(&range[0]), contiguous_iterator(&range[2]), &range[2]);
+  check_sized_sentinel<cpp17_input_iterator<int*>>(  &range[0], &range[7], &range[7]);
+  check_sized_sentinel<cpp20_input_iterator<int*>>(  &range[0], &range[6], &range[6]);
+  check_sized_sentinel<forward_iterator<int*>>(      &range[0], &range[5], &range[5]);
+  check_sized_sentinel<bidirectional_iterator<int*>>(&range[0], &range[4], &range[4]);
+  check_sized_sentinel<random_access_iterator<int*>>(&range[0], &range[3], &range[3]);
+  check_sized_sentinel<contiguous_iterator<int*>>(   &range[0], &range[2], &range[2]);
 
-  check_sentinel(cpp17_input_iterator(&range[0]), cpp17_input_iterator(&range[1]), &range[1]);
+  check_sentinel<false, cpp17_input_iterator<int*>>(  &range[0], &range[1], &range[1]);
   // cpp20_input_iterator not copyable, so is omitted
-  check_sentinel(forward_iterator(&range[0]), forward_iterator(&range[3]), &range[3]);
-  check_sentinel(bidirectional_iterator(&range[0]), bidirectional_iterator(&range[4]), &range[4]);
-  check_sentinel(random_access_iterator(&range[0]), random_access_iterator(&range[5]), &range[5]);
-  check_sentinel(contiguous_iterator(&range[0]), contiguous_iterator(&range[6]), &range[6]);
+  check_sentinel<true,  forward_iterator<int*>>(      &range[0], &range[3], &range[3]);
+  check_sentinel<true,  bidirectional_iterator<int*>>(&range[0], &range[4], &range[4]);
+  check_sentinel<true,  random_access_iterator<int*>>(&range[0], &range[5], &range[5]);
+  check_sentinel<true,  contiguous_iterator<int*>>(   &range[0], &range[6], &range[6]);
   return true;
 }
 

diff  --git a/libcxx/test/std/iterators/predef.iterators/counted.iterator/ctor.default.pass.cpp b/libcxx/test/std/iterators/predef.iterators/counted.iterator/ctor.default.pass.cpp
index 70c1d422be75..b5b00ad4a9ff 100644
--- a/libcxx/test/std/iterators/predef.iterators/counted.iterator/ctor.default.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/counted.iterator/ctor.default.pass.cpp
@@ -17,11 +17,11 @@
 #include "test_iterators.h"
 
 constexpr bool test() {
-  static_assert( std::default_initializable<std::counted_iterator<cpp17_input_iterator<int*>>>);
-  static_assert(!std::default_initializable<std::counted_iterator<cpp20_input_iterator<int*>>>);
+  static_assert(!std::default_initializable<std::counted_iterator<cpp17_input_iterator<int*>>>);
+  static_assert( std::default_initializable<std::counted_iterator<forward_iterator<int*>>>);
 
-  std::counted_iterator<cpp17_input_iterator<int*>> iter;
-  assert(iter.base() == cpp17_input_iterator<int*>());
+  std::counted_iterator<forward_iterator<int*>> iter;
+  assert(iter.base() == forward_iterator<int*>());
   assert(iter.count() == 0);
 
   return true;

diff  --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp
index 40a9e7f1ae89..04d3d6e1866a 100644
--- a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/default.pass.cpp
@@ -29,7 +29,7 @@ test()
 
 int main(int, char**)
 {
-    test<cpp17_input_iterator<char*> >();
+    // we don't have a test iterator that is both input and default-constructible, so not testing that case
     test<forward_iterator<char*> >();
     test<bidirectional_iterator<char*> >();
     test<random_access_iterator<char*> >();

diff  --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp
index c6dcef9a0d19..a55d7a345074 100644
--- a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op=/move_iterator.pass.cpp
@@ -28,7 +28,7 @@ void
 test(U u)
 {
     const std::move_iterator<U> r2(u);
-    std::move_iterator<It> r1;
+    std::move_iterator<It> r1(It(nullptr));
     std::move_iterator<It>& rr = (r1 = r2);
     assert(r1.base() == u);
     assert(&rr == &r1);

diff  --git a/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/ctor.default.pass.cpp
index 52bae5bb752f..709e2f925a67 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/ctor.default.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/ctor.default.pass.cpp
@@ -23,16 +23,16 @@ struct DefaultCtorParent : std::ranges::view_base {
   T *ptr_;
   constexpr DefaultCtorParent(T *ptr) : ptr_(ptr) {}
 
-  constexpr cpp17_input_iterator<T *> begin() { return cpp17_input_iterator<T *>(ptr_); }
-  constexpr cpp17_input_iterator<const T *> begin() const { return cpp17_input_iterator<const T *>(ptr_); }
+  constexpr forward_iterator<T *> begin() { return forward_iterator<T *>(ptr_); }
+  constexpr forward_iterator<const T *> begin() const { return forward_iterator<const T *>(ptr_); }
   constexpr T *end() { return ptr_ + 4; }
   constexpr const T *end() const { return ptr_ + 4; }
 };
 
 template<class T>
-constexpr bool operator==(const cpp17_input_iterator<T*> &lhs, const T *rhs) { return lhs.base() == rhs; }
+constexpr bool operator==(const forward_iterator<T*> &lhs, const T *rhs) { return lhs.base() == rhs; }
 template<class T>
-constexpr bool operator==(const T *lhs, const cpp17_input_iterator<T*> &rhs) { return rhs.base() == lhs; }
+constexpr bool operator==(const T *lhs, const forward_iterator<T*> &rhs) { return rhs.base() == lhs; }
 
 constexpr bool test() {
   using Base = DefaultCtorParent<ChildView>;

diff  --git a/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/member_types.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/member_types.compile.pass.cpp
index acf7ca17cd69..ba960d4968df 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/member_types.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join.view/iterator/member_types.compile.pass.cpp
@@ -20,18 +20,14 @@
 
 template<class T>
 struct ForwardView : std::ranges::view_base {
-  friend forward_iterator<T*> begin(ForwardView&) { return forward_iterator<T*>(nullptr); }
-  friend forward_iterator<T*> begin(ForwardView const&) { return forward_iterator<T*>(nullptr); }
-  friend forward_iterator<T*> end(ForwardView&) { return forward_iterator<T*>(nullptr); }
-  friend forward_iterator<T*> end(ForwardView const&) { return forward_iterator<T*>(nullptr); }
+  forward_iterator<T*> begin() const;
+  sentinel_wrapper<forward_iterator<T*>> end() const;
 };
 
 template<class T>
 struct InputView : std::ranges::view_base {
-  friend cpp17_input_iterator<T*> begin(InputView&) { return cpp17_input_iterator<T*>(nullptr); }
-  friend cpp17_input_iterator<T*> begin(InputView const&) { return cpp17_input_iterator<T*>(nullptr); }
-  friend cpp17_input_iterator<T*> end(InputView&) { return cpp17_input_iterator<T*>(nullptr); }
-  friend cpp17_input_iterator<T*> end(InputView const&) { return cpp17_input_iterator<T*>(nullptr); }
+  cpp17_input_iterator<T*> begin() const;
+  sentinel_wrapper<cpp17_input_iterator<T*>> end() const;
 };
 
 template<class T>

diff  --git a/libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp
index 5288ed684407..267a4c9c3c1a 100644
--- a/libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.req/range.range/sentinel_t.compile.pass.cpp
@@ -25,6 +25,6 @@
 static_assert(std::same_as<std::ranges::sentinel_t<test_range<cpp20_input_iterator> >, sentinel>);
 static_assert(std::same_as<std::ranges::sentinel_t<test_range<cpp20_input_iterator> const>, sentinel>);
 static_assert(std::same_as<std::ranges::sentinel_t<test_non_const_range<cpp20_input_iterator> >, sentinel>);
-static_assert(std::same_as<std::ranges::sentinel_t<test_common_range<cpp17_input_iterator> >, cpp17_input_iterator<int*> >);
-static_assert(std::same_as<std::ranges::sentinel_t<test_common_range<cpp17_input_iterator> const>, cpp17_input_iterator<int const*> >);
-static_assert(std::same_as<std::ranges::sentinel_t<test_non_const_common_range<cpp17_input_iterator> >, cpp17_input_iterator<int*> >);
+static_assert(std::same_as<std::ranges::sentinel_t<test_common_range<forward_iterator> >, forward_iterator<int*> >);
+static_assert(std::same_as<std::ranges::sentinel_t<test_common_range<forward_iterator> const>, forward_iterator<int const*> >);
+static_assert(std::same_as<std::ranges::sentinel_t<test_non_const_common_range<forward_iterator> >, forward_iterator<int*> >);

diff  --git a/libcxx/test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp
index dd606be1cd5d..0ee8eed08a0b 100644
--- a/libcxx/test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp
@@ -16,41 +16,51 @@
 #include <ranges>
 
 #include "test_iterators.h"
-#include "test_range.h"
 
+template<class It>             struct Common { It begin() const; It end() const; };
+template<class It>             struct NonCommon { It begin() const; sentinel_wrapper<It> end() const; };
+template<class It, class Sent> struct Range { It begin() const; Sent end() const; };
 
+static_assert(!std::ranges::common_range<Common<cpp17_input_iterator<int*>>>); // not a sentinel for itself
+static_assert(!std::ranges::common_range<Common<cpp20_input_iterator<int*>>>); // not a sentinel for itself
+static_assert( std::ranges::common_range<Common<forward_iterator<int*>>>);
+static_assert( std::ranges::common_range<Common<bidirectional_iterator<int*>>>);
+static_assert( std::ranges::common_range<Common<random_access_iterator<int*>>>);
+static_assert( std::ranges::common_range<Common<contiguous_iterator<int*>>>);
+static_assert( std::ranges::common_range<Common<int*>>);
 
-static_assert(!std::ranges::common_range<test_range<cpp17_input_iterator> >);
-static_assert(!std::ranges::common_range<test_range<cpp17_input_iterator> const>);
+static_assert(!std::ranges::common_range<NonCommon<cpp17_input_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<cpp20_input_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<forward_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<bidirectional_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<random_access_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<contiguous_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<int*>>);
 
-static_assert(!std::ranges::common_range<test_non_const_range<cpp17_input_iterator> >);
-static_assert(!std::ranges::common_range<test_non_const_range<cpp17_input_iterator> const>);
+// Test when begin() and end() only 
diff er by their constness.
+static_assert(!std::ranges::common_range<Range<int*, int const*>>);
 
-static_assert(std::ranges::common_range<test_common_range<cpp17_input_iterator> >);
-static_assert(std::ranges::common_range<test_common_range<cpp17_input_iterator> const>);
+// Simple test with a sized_sentinel.
+static_assert(!std::ranges::common_range<Range<int*, sized_sentinel<int*>>>);
 
-static_assert(std::ranges::common_range<test_non_const_common_range<cpp17_input_iterator> >);
-static_assert(!std::ranges::common_range<test_non_const_common_range<cpp17_input_iterator> const>);
+// Make sure cv-qualification doesn't impact the concept when begin() and end() have matching qualifiers.
+static_assert( std::ranges::common_range<Common<forward_iterator<int*>> const>);
+static_assert(!std::ranges::common_range<NonCommon<forward_iterator<int*>> const>);
 
-struct subtly_not_common {
-  int* begin() const;
+// Test with a range that's a common_range only when const-qualified.
+struct Range1 {
+  int* begin();
+  int const* begin() const;
   int const* end() const;
 };
-static_assert(std::ranges::range<subtly_not_common> && !std::ranges::common_range<subtly_not_common>);
-static_assert(std::ranges::range<subtly_not_common const> && !std::ranges::common_range<subtly_not_common const>);
+static_assert(!std::ranges::common_range<Range1>);
+static_assert( std::ranges::common_range<Range1 const>);
 
-struct common_range_non_const_only {
+// Test with a range that's a common_range only when not const-qualified.
+struct Range2 {
   int* begin() const;
   int* end();
   int const* end() const;
 };
-static_assert(std::ranges::range<common_range_non_const_only>&& std::ranges::common_range<common_range_non_const_only>);
-static_assert(std::ranges::range<common_range_non_const_only const> && !std::ranges::common_range<common_range_non_const_only const>);
-
-struct common_range_const_only {
-  int* begin();
-  int const* begin() const;
-  int const* end() const;
-};
-static_assert(std::ranges::range<common_range_const_only> && !std::ranges::common_range<common_range_const_only>);
-static_assert(std::ranges::range<common_range_const_only const>&& std::ranges::common_range<common_range_const_only const>);
+static_assert( std::ranges::common_range<Range2>);
+static_assert(!std::ranges::common_range<Range2 const>);

diff  --git a/libcxx/test/std/ranges/range.req/range.refinements/input_range.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.refinements/input_range.compile.pass.cpp
index 1a2b66cb3837..c27c972294e5 100644
--- a/libcxx/test/std/ranges/range.req/range.refinements/input_range.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.req/range.refinements/input_range.compile.pass.cpp
@@ -32,14 +32,14 @@ static_assert(std::ranges::input_range<test_non_const_range<cpp20_input_iterator
 static_assert(!std::ranges::input_range<test_non_const_range<cpp17_input_iterator> const>);
 static_assert(!std::ranges::input_range<test_non_const_range<cpp20_input_iterator> const>);
 
-static_assert(std::ranges::input_range<test_common_range<cpp17_input_iterator> >);
+static_assert(std::ranges::input_range<test_common_range<forward_iterator> >);
 static_assert(!std::ranges::input_range<test_common_range<cpp20_input_iterator> >);
 
-static_assert(std::ranges::input_range<test_common_range<cpp17_input_iterator> const>);
+static_assert(std::ranges::input_range<test_common_range<forward_iterator> const>);
 static_assert(!std::ranges::input_range<test_common_range<cpp20_input_iterator> const>);
 
-static_assert(std::ranges::input_range<test_non_const_common_range<cpp17_input_iterator> >);
+static_assert(std::ranges::input_range<test_non_const_common_range<forward_iterator> >);
 static_assert(!std::ranges::input_range<test_non_const_common_range<cpp20_input_iterator> >);
 
-static_assert(!std::ranges::input_range<test_non_const_common_range<cpp17_input_iterator> const>);
+static_assert(!std::ranges::input_range<test_non_const_common_range<forward_iterator> const>);
 static_assert(!std::ranges::input_range<test_non_const_common_range<cpp20_input_iterator> const>);

diff  --git a/libcxx/test/std/ranges/range.utility/range.subrange/advance.pass.cpp b/libcxx/test/std/ranges/range.utility/range.subrange/advance.pass.cpp
index 336af63e4a3e..419a47f092f7 100644
--- a/libcxx/test/std/ranges/range.utility/range.subrange/advance.pass.cpp
+++ b/libcxx/test/std/ranges/range.utility/range.subrange/advance.pass.cpp
@@ -31,7 +31,7 @@ constexpr bool test() {
   assert(a4.begin() == globalBuff + 4);
   assert(a4.size() == 4);
 
-  std::ranges::subrange<InputIter> b(InputIter(globalBuff), InputIter(globalBuff + 8));
+  std::ranges::subrange<InputIter, sentinel_wrapper<InputIter>> b(InputIter(globalBuff), sentinel_wrapper(InputIter(globalBuff + 8)));
   auto b1 = std::move(b).next();
   assert(b1.begin().base() == globalBuff + 1);
 

diff  --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
index 34b5d4139b39..07c5586419b5 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_append/iterator.pass.cpp
@@ -178,9 +178,9 @@ int main(int, char**)
     typedef ThrowingIterator<char> TIter;
     typedef cpp17_input_iterator<TIter> IIter;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-    test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
-    test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
-    test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
+    test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
+    test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
 
     test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
     test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter());

diff  --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
index f8b10c6e056c..87f3885713da 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_assign/iterator.pass.cpp
@@ -178,9 +178,9 @@ int main(int, char**)
     typedef ThrowingIterator<char> TIter;
     typedef cpp17_input_iterator<TIter> IIter;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-    test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
-    test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
-    test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+    test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
+    test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
+    test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
 
     test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
     test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter());

diff  --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
index 1f0b12ff7be9..e0e7ff906634 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_insert/iter_iter_iter.pass.cpp
@@ -156,9 +156,9 @@ int main(int, char**)
     typedef ThrowingIterator<char> TIter;
     typedef cpp17_input_iterator<TIter> IIter;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-    test_exceptions(S(), 0, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
-    test_exceptions(S(), 0, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
-    test_exceptions(S(), 0, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
+    test_exceptions(S(), 0, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
 
     test_exceptions(S(), 0, TIter(s, s+10, 4, TIter::TAIncrement), TIter());
     test_exceptions(S(), 0, TIter(s, s+10, 5, TIter::TADereference), TIter());

diff  --git a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
index 9ce4a375aab8..ea6f234f1a00 100644
--- a/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.modifiers/string_replace/iter_iter_iter_iter.pass.cpp
@@ -1008,9 +1008,9 @@ int main(int, char**)
     typedef ThrowingIterator<char> TIter;
     typedef cpp17_input_iterator<TIter> IIter;
     const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
-    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
-    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
+    test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
 
     test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 4, TIter::TAIncrement), TIter());
     test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 5, TIter::TADereference), TIter());

diff  --git a/libcxx/test/support/test_iterators.h b/libcxx/test/support/test_iterators.h
index 4bf082b3634f..36f7caeb5b84 100644
--- a/libcxx/test/support/test_iterators.h
+++ b/libcxx/test/support/test_iterators.h
@@ -66,7 +66,6 @@ class cpp17_input_iterator
 
     TEST_CONSTEXPR_CXX14 It base() const {return it_;}
 
-    TEST_CONSTEXPR_CXX14 cpp17_input_iterator() : it_() {}
     explicit TEST_CONSTEXPR_CXX14 cpp17_input_iterator(It it) : it_(it) {}
     template <class U, class T>
         TEST_CONSTEXPR_CXX14 cpp17_input_iterator(const cpp17_input_iterator<U, T>& u) :it_(u.it_) {}


        


More information about the libcxx-commits mailing list