[libc++][ranges] iterator.concept.sizedsentinel: sized_sentinel_for and disable_sized...
authorzoecarver <z.zoelec2@gmail.com>
Mon, 26 Apr 2021 16:35:47 +0000 (09:35 -0700)
committerzoecarver <z.zoelec2@gmail.com>
Mon, 26 Apr 2021 22:06:19 +0000 (15:06 -0700)
Based on D100160.

Reviewed By: cjdb, ldionne, Quuxplusone, #libc, miscco

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

30 files changed:
libcxx/include/__iterator/concepts.h
libcxx/include/iterator
libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sized_sentinel_for.compile.pass.cpp [new file with mode: 0644]
libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp

index 3a9b628..445a88f 100644 (file)
@@ -99,6 +99,18 @@ concept sentinel_for =
   input_or_output_iterator<_Ip> &&
   __weakly_equality_comparable_with<_Sp, _Ip>;
 
+template<class, class>
+inline constexpr bool disable_sized_sentinel_for = false;
+
+template<class _Sp, class _Ip>
+concept sized_sentinel_for =
+  sentinel_for<_Sp, _Ip> &&
+  !disable_sized_sentinel_for<remove_cv_t<_Sp>, remove_cv_t<_Ip> > &&
+  requires(const _Ip& __i, const _Sp& __s) {
+    { __s - __i } -> same_as<iter_difference_t<_Ip> >;
+    { __i - __s } -> same_as<iter_difference_t<_Ip> >;
+  };
+
 // clang-format on
 
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)
index 74d04ce..918c96d 100644 (file)
@@ -68,6 +68,13 @@ template<class I>
 template<class S, class I>
   concept sentinel_for = see below;                        // since C++20
 
+// [iterator.concept.sizedsentinel], concept sized_sentinel_for
+template<class S, class I>
+  inline constexpr bool disable_sized_sentinel_for = false;
+
+template<class S, class I>
+  concept sized_sentinel_for = see below;
+
 template<class Category, class T, class Distance = ptrdiff_t,
          class Pointer = T*, class Reference = T&>
 struct iterator
@@ -459,6 +466,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
 #include <__iterator/iter_move.h>
 #include <__iterator/iterator_traits.h>
 #include <__iterator/readable_traits.h>
+#include <__iterator/concepts.h>
 #include <__memory/addressof.h>
 #include <__memory/pointer_traits.h>
 #include <version>
index 46cbf2f..0c0fc47 100644 (file)
@@ -31,6 +31,10 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -40,3 +44,7 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
index 6b1a4a9..c284884 100644 (file)
@@ -31,6 +31,10 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -40,3 +44,7 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
index a152d26..a844a0b 100644 (file)
@@ -31,6 +31,10 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -38,3 +42,7 @@ static_assert(std::incrementable<const_iterator>);
 static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
index 15f32b3..280ebf3 100644 (file)
@@ -31,6 +31,10 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -40,3 +44,7 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
index ee376f2..dd15a56 100644 (file)
@@ -39,3 +39,13 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
index a3fcc4f..b3f79b0 100644 (file)
@@ -40,3 +40,13 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
index f3953b1..34d7940 100644 (file)
@@ -27,6 +27,8 @@ static_assert(std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -34,3 +36,5 @@ static_assert(std::incrementable<const_iterator>);
 static_assert(std::input_or_output_iterator<const_iterator>);
 static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
index 94ea2fd..df68e7f 100644 (file)
@@ -31,6 +31,10 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sentinel_for<iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<iterator, const_reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -40,3 +44,7 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
index 66ffccc..4605641 100644 (file)
@@ -40,3 +40,13 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
index de3e622..c2be5b3 100644 (file)
@@ -40,3 +40,13 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
index 4b760b6..898b96a 100644 (file)
@@ -31,21 +31,36 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sentinel_for<iterator, local_iterator>);
 static_assert(!std::sentinel_for<iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
 static_assert(std::incrementable<const_iterator>);
+static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<const_iterator, iterator>);
+static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
+static_assert(!std::indirectly_writable<local_iterator, value_type>);
 static_assert(std::incrementable<local_iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(!std::sentinel_for<local_iterator, iterator>);
 static_assert(!std::sentinel_for<local_iterator, const_iterator>);
 static_assert(std::sentinel_for<local_iterator, local_iterator>);
 static_assert(std::sentinel_for<local_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
@@ -55,3 +70,7 @@ static_assert(!std::sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sentinel_for<const_local_iterator, const_iterator>);
 static_assert(std::sentinel_for<const_local_iterator, local_iterator>);
 static_assert(std::sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
index 192576b..bca6fa8 100644 (file)
@@ -31,6 +31,10 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sentinel_for<iterator, local_iterator>);
 static_assert(!std::sentinel_for<iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -40,6 +44,10 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
 static_assert(!std::indirectly_writable<local_iterator, value_type>);
@@ -49,6 +57,10 @@ static_assert(!std::sentinel_for<local_iterator, iterator>);
 static_assert(!std::sentinel_for<local_iterator, const_iterator>);
 static_assert(std::sentinel_for<local_iterator, local_iterator>);
 static_assert(std::sentinel_for<local_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
@@ -58,3 +70,7 @@ static_assert(!std::sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sentinel_for<const_local_iterator, const_iterator>);
 static_assert(std::sentinel_for<const_local_iterator, local_iterator>);
 static_assert(std::sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
index 55447ac..5424594 100644 (file)
@@ -31,6 +31,10 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sentinel_for<iterator, const_iterator>);
 static_assert(!std::sentinel_for<iterator, local_iterator>);
 static_assert(!std::sentinel_for<iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -40,6 +44,10 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<local_iterator>);
 static_assert(!std::indirectly_writable<local_iterator, value_type>);
@@ -49,6 +57,10 @@ static_assert(!std::sentinel_for<local_iterator, iterator>);
 static_assert(!std::sentinel_for<local_iterator, const_iterator>);
 static_assert(std::sentinel_for<local_iterator, local_iterator>);
 static_assert(std::sentinel_for<local_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
 
 static_assert(std::indirectly_readable<const_local_iterator>);
 static_assert(!std::indirectly_writable<const_local_iterator, value_type>);
@@ -58,3 +70,7 @@ static_assert(!std::sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sentinel_for<const_local_iterator, const_iterator>);
 static_assert(std::sentinel_for<const_local_iterator, local_iterator>);
 static_assert(std::sentinel_for<const_local_iterator, const_local_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
+static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
index 6273fdd..98d3f11 100644 (file)
@@ -27,3 +27,5 @@ static_assert(std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(!std::sentinel_for<iterator, reverse_iterator>);
+static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
index 527b444..ec62bcb 100644 (file)
@@ -23,6 +23,7 @@ static_assert(std::weakly_incrementable<fs::directory_iterator>);
 static_assert(!std::incrementable<fs::directory_iterator>);
 static_assert(std::input_or_output_iterator<fs::directory_iterator>);
 static_assert(std::sentinel_for<fs::directory_iterator, fs::directory_iterator>);
+static_assert(!std::sized_sentinel_for<fs::directory_iterator, fs::directory_iterator>);
 
 static_assert(std::indirectly_readable<fs::recursive_directory_iterator>);
 static_assert(
@@ -31,3 +32,4 @@ static_assert(std::weakly_incrementable<fs::recursive_directory_iterator>);
 static_assert(!std::incrementable<fs::recursive_directory_iterator>);
 static_assert(std::input_or_output_iterator<fs::recursive_directory_iterator>);
 static_assert(std::sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
+static_assert(!std::sized_sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sized_sentinel_for.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.sentinel/sized_sentinel_for.compile.pass.cpp
new file mode 100644 (file)
index 0000000..619280f
--- /dev/null
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: gcc-10
+// XFAIL: msvc && clang
+
+// [iterator.concept.sizedsentinel], concept sized_sentinel_for
+//
+// template<class S, class I>
+//   inline constexpr bool disable_sized_sentinel_for = false;
+//
+// template<class S, class I>
+//   concept sized_sentinel_for = see below;
+
+#include <iterator>
+
+#include <array>
+#include <concepts>
+#include <deque>
+#include <string>
+#include <string_view>
+#include <vector>
+
+#include "test_iterators.h"
+#include "test_macros.h"
+
+static_assert(std::sized_sentinel_for<random_access_iterator<int*>, random_access_iterator<int*> >);
+static_assert(!std::sized_sentinel_for<bidirectional_iterator<int*>, bidirectional_iterator<int*> >);
+
+struct int_sized_sentinel {
+  friend bool operator==(int_sized_sentinel, int*);
+  friend std::ptrdiff_t operator-(int_sized_sentinel, int*);
+  friend std::ptrdiff_t operator-(int*, int_sized_sentinel);
+};
+static_assert(std::sized_sentinel_for<int_sized_sentinel, int*>);
+// int_sized_sentinel is not an iterator.
+static_assert(!std::sized_sentinel_for<int*, int_sized_sentinel>);
+
+struct no_default_ctor {
+  no_default_ctor() = delete;
+  bool operator==(std::input_or_output_iterator auto) const;
+};
+static_assert(!std::sized_sentinel_for<no_default_ctor, int*>);
+
+struct not_copyable {
+  not_copyable() = default;
+  not_copyable(not_copyable const&) = delete;
+  bool operator==(std::input_or_output_iterator auto) const;
+};
+static_assert(!std::sized_sentinel_for<not_copyable, int*>);
+
+struct double_sized_sentinel {
+  friend bool operator==(double_sized_sentinel, double*);
+  friend int operator-(double_sized_sentinel, double*);
+  friend int operator-(double*, double_sized_sentinel);
+};
+template <>
+inline constexpr bool std::disable_sized_sentinel_for<double_sized_sentinel, double*> = true;
+
+static_assert(!std::sized_sentinel_for<double_sized_sentinel, double*>);
+
+struct only_one_sub_op {
+  friend bool operator==(only_one_sub_op, std::input_or_output_iterator auto);
+  friend std::ptrdiff_t operator-(only_one_sub_op, std::input_or_output_iterator auto);
+};
+static_assert(!std::sized_sentinel_for<only_one_sub_op, int*>);
+
+struct wrong_return_type {
+  friend bool operator==(wrong_return_type, std::input_or_output_iterator auto);
+  friend std::ptrdiff_t operator-(wrong_return_type, std::input_or_output_iterator auto);
+  friend void operator-(std::input_or_output_iterator auto, wrong_return_type);
+};
+static_assert(!std::sized_sentinel_for<wrong_return_type, int*>);
+
+// Standard types
+static_assert(std::sized_sentinel_for<int*, int*>);
+static_assert(std::sized_sentinel_for<const int*, int*>);
+static_assert(std::sized_sentinel_for<const int*, const int*>);
+static_assert(std::sized_sentinel_for<int*, const int*>);
index 49f392e..485df7c 100644 (file)
@@ -21,3 +21,4 @@ static_assert(!std::indirectly_writable<iterator, int>);
 static_assert(std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sized_sentinel_for<iterator, iterator>);
index 2ea97d9..f5b9082 100644 (file)
@@ -22,6 +22,8 @@ static_assert(std::indirectly_writable<iterator, int>);
 static_assert(std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(std::sized_sentinel_for<iterator, iterator>);
 
 using other_iterator = std::reverse_iterator<float*>;
 static_assert(std::sentinel_for<iterator, other_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, other_iterator>);
index 1b4da23..6db8603 100644 (file)
@@ -23,3 +23,4 @@ static_assert(!std::indirectly_writable<iterator, int>);
 static_assert(std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
index ef50781..2cbe4e0 100644 (file)
@@ -25,3 +25,4 @@ static_assert(std::weakly_incrementable<iterator>);
 static_assert(!std::incrementable<iterator>);
 static_assert(std::input_or_output_iterator<iterator>);
 static_assert(std::sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
index d68c33b..efe5a17 100644 (file)
@@ -23,3 +23,4 @@ static_assert(std::indirectly_writable<iterator, int>);
 static_assert(!std::weakly_incrementable<iterator>);
 static_assert(!std::input_or_output_iterator<iterator>);
 static_assert(!std::sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
index c2743c2..fc28ce9 100644 (file)
@@ -24,3 +24,4 @@ static_assert(std::indirectly_writable<iterator, char>);
 static_assert(!std::weakly_incrementable<iterator>);
 static_assert(!std::input_or_output_iterator<iterator>);
 static_assert(!std::sentinel_for<iterator, iterator>);
+static_assert(!std::sized_sentinel_for<iterator, iterator>);
index 38565e4..897e744 100644 (file)
@@ -22,3 +22,4 @@ static_assert(!std::indirectly_writable<std::cregex_iterator, char>);
 static_assert(std::incrementable<std::cregex_iterator>);
 static_assert(std::input_or_output_iterator<std::cregex_iterator>);
 static_assert(std::sentinel_for<std::cregex_iterator, std::cregex_iterator>);
+static_assert(!std::sized_sentinel_for<std::cregex_iterator, std::cregex_iterator>);
index 63027cb..f94382f 100644 (file)
@@ -22,3 +22,4 @@ static_assert(!std::indirectly_writable<std::cregex_token_iterator, char>);
 static_assert(std::incrementable<std::cregex_token_iterator>);
 static_assert(std::input_or_output_iterator<std::cregex_token_iterator>);
 static_assert(std::sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);
+static_assert(!std::sized_sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);
index 8ff56b9..a1e2164 100644 (file)
@@ -39,3 +39,13 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
index 5a4fe87..9640712 100644 (file)
@@ -39,3 +39,13 @@ static_assert(std::sentinel_for<const_iterator, iterator>);
 static_assert(std::sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sentinel_for<const_iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<iterator, iterator>);
+static_assert(std::sized_sentinel_for<iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
+
+static_assert(std::sized_sentinel_for<const_iterator, iterator>);
+static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
+static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);