libstdc++: Add a testsuite range type that has a sized sentinel
authorPatrick Palka <ppalka@redhat.com>
Tue, 3 Mar 2020 03:32:22 +0000 (22:32 -0500)
committerPatrick Palka <ppalka@redhat.com>
Wed, 4 Mar 2020 03:44:39 +0000 (22:44 -0500)
This adds a testsuite range type whose end() is a sized sentinel to
<testsuite_iterators.h>, which will be used in the tests that verify LWG 3355.

libstdc++-v3/ChangeLog:

* testsuite/util/testsuite_iterators.h (test_range::get_iterator): Make
protected instead of private.
(test_sized_range_sized_sent): New.

libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/util/testsuite_iterators.h

index 1d68f7c..ca5f0d0 100644 (file)
@@ -1,5 +1,9 @@
 2020-03-04  Patrick Palka  <ppalka@redhat.com>
 
+       * testsuite/util/testsuite_iterators.h (test_range::get_iterator): Make
+       protected instead of private.
+       (test_sized_range_sized_sent): New.
+
        * testsuite/util/testsuite_iterators.h (input_iterator_wrapper_nocopy):
        New testsuite iterator.
        * testsuite/24_iterators/counted_iterator/lwg3389.cc: use it.
index e47b2b0..a915c02 100644 (file)
@@ -735,6 +735,7 @@ namespace __gnu_test
          { return i.ptr - s.end; }
        };
 
+    protected:
       auto
       get_iterator(T* p)
       {
@@ -812,6 +813,37 @@ namespace __gnu_test
     using test_output_sized_range
       = test_sized_range<T, output_iterator_wrapper>;
 
+  // A type meeting the minimum std::sized_range requirements, and whose end()
+  // returns a sized sentinel.
+  template<typename T, template<typename> class Iter>
+    struct test_sized_range_sized_sent : test_sized_range<T, Iter>
+    {
+      using test_sized_range<T, Iter>::test_sized_range;
+
+      template<typename I>
+       struct sentinel
+       {
+         T* end;
+
+         friend bool operator==(const sentinel& s, const I& i) noexcept
+         { return s.end == i.ptr; }
+
+         friend std::iter_difference_t<I>
+         operator-(const sentinel& s, const I& i) noexcept
+         { return s.end - i.ptr; }
+
+         friend std::iter_difference_t<I>
+         operator-(const I& i, const sentinel& s) noexcept
+         { return i.ptr - s.end; }
+       };
+
+      auto end() &
+      {
+       using I = decltype(this->get_iterator(this->bounds.last));
+       return sentinel<I>{this->bounds.last};
+      }
+    };
+
 // test_range and test_sized_range do not own their elements, so they model
 // std::ranges::borrowed_range.  This file does not define specializations of
 // std::ranges::enable_borrowed_range, so that individual tests can decide