diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -137,7 +137,22 @@ { __i-- } -> same_as<_Ip>; }; - // clang-format on +template +concept random_access_iterator = + bidirectional_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> && + totally_ordered<_Ip> && + sized_sentinel_for<_Ip, _Ip> && + requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) { + { __i += __n } -> same_as<_Ip&>; + { __j + __n } -> same_as<_Ip>; + { __n + __j } -> same_as<_Ip>; + { __i -= __n } -> same_as<_Ip&>; + { __j - __n } -> same_as<_Ip>; + { __j[__n] } -> same_as>; + }; + +// clang-format on #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h --- a/libcxx/include/__ranges/concepts.h +++ b/libcxx/include/__ranges/concepts.h @@ -62,6 +62,10 @@ template concept common_range = range<_Tp> && same_as, sentinel_t<_Tp> >; + + template + concept random_access_range = + bidirectional_range<_Tp> && random_access_iterator >; } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp b/libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp copy from libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp copy to libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp --- a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp +++ b/libcxx/test/libcxx/iterators/iterator.concepts/iterator.concept.random.access/subsumption.compile.pass.cpp @@ -11,19 +11,20 @@ // UNSUPPORTED: gcc-10 // template -// concept bidirectional_iterator; +// concept random_access_iterator; #include #include -template -[[nodiscard]] constexpr bool check_subsumption() { +template +requires std::derived_from, std::random_access_iterator_tag> +constexpr bool check_subsumption() { return false; } -template -[[nodiscard]] constexpr bool check_subsumption() { +template +constexpr bool check_subsumption() { return true; } diff --git a/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using value_type = std::pair; static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/map/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); diff --git a/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using value_type = std::pair; static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); diff --git a/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using value_type = int; static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/multiset/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); diff --git a/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using value_type = int; static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/associative/set/range_concept_conformance.compile.pass.cpp @@ -21,9 +21,13 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); +static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); static_assert(stdr::common_range); static_assert(stdr::input_range); static_assert(std::same_as, range::const_iterator>); +static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); static_assert(stdr::common_range); static_assert(stdr::input_range); diff --git a/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp @@ -22,6 +22,7 @@ using const_reverse_iterator = std::array::const_reverse_iterator; static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,6 +34,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp @@ -22,8 +22,8 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); diff --git a/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using value_type = int; static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp @@ -22,8 +22,8 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); diff --git a/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using value_type = int; static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); diff --git a/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using value_type = bool; static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp @@ -22,8 +22,8 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); diff --git a/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using value_type = int; static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -34,6 +35,7 @@ static_assert(!std::sized_sentinel_for); static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp @@ -22,8 +22,8 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); diff --git a/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp @@ -22,8 +22,8 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::bidirectional_range); +static_assert(stdr::random_access_range); diff --git a/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp @@ -21,6 +21,7 @@ using value_type = int; static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(!std::sentinel_for); diff --git a/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.path/range_concept_conformance.compile.pass.cpp @@ -22,7 +22,9 @@ static_assert(std::same_as, fs::path::iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); static_assert(std::same_as, fs::path::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::bidirectional_range); +static_assert(!stdr::random_access_range); diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp --- a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp @@ -18,12 +18,12 @@ #include template -[[nodiscard]] constexpr bool check_subsumption() { +constexpr bool check_subsumption() { return false; } template -[[nodiscard]] constexpr bool check_subsumption() { +constexpr bool check_subsumption() { return true; } diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/random_access_iterator.compile.pass.cpp @@ -0,0 +1,218 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept random_access_iterator; + +#include + +#include "test_iterators.h" +#include "test_macros.h" + +static_assert(!std::random_access_iterator >); +static_assert(!std::random_access_iterator >); +static_assert(!std::random_access_iterator >); +static_assert(!std::random_access_iterator >); +static_assert( std::random_access_iterator >); +static_assert( std::random_access_iterator >); + +static_assert(std::random_access_iterator); +static_assert(std::random_access_iterator); +static_assert(std::random_access_iterator); +static_assert(std::random_access_iterator); + +struct wrong_iterator_category { + typedef std::bidirectional_iterator_tag iterator_category; + typedef int value_type; + typedef std::ptrdiff_t difference_type; + typedef int* pointer; + typedef int& reference; + typedef wrong_iterator_category self; + + reference operator*() const; + pointer operator->() const; + friend bool operator==(const self&, const self&); + friend bool operator< (const self&, const self&); + friend bool operator<=(const self&, const self&); + friend bool operator> (const self&, const self&); + friend bool operator>=(const self&, const self&); + + self& operator++(); + self operator++(int); + + self& operator--(); + self operator--(int); + + self& operator+=(difference_type n); + self operator+(difference_type n) const; + friend self operator+(difference_type n, self x); + + self& operator-=(difference_type n); + self operator-(difference_type n) const; + difference_type operator-(const self&) const; + + reference operator[](difference_type n) const; +}; +static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); + +template +struct common_base { + typedef std::random_access_iterator_tag iterator_category; + typedef int value_type; + typedef std::ptrdiff_t difference_type; + typedef int* pointer; + typedef int& reference; + typedef Child self; + + reference operator*() const; + pointer operator->() const; + friend bool operator==(const self&, const self&); + friend bool operator< (const self&, const self&); + friend bool operator<=(const self&, const self&); + friend bool operator> (const self&, const self&); + friend bool operator>=(const self&, const self&); + + self& operator++(); + self operator++(int); + + self& operator--(); + self operator--(int); +}; + +struct simple_random_access_iterator + : common_base { + + self& operator+=(difference_type n); + self operator+(difference_type n) const; + friend self operator+(difference_type n, self x); + + self& operator-=(difference_type n); + self operator-(difference_type n) const; + difference_type operator-(const self&) const; + + reference operator[](difference_type n) const; +}; +static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); + +struct no_plus_equals + : common_base { + + /* self& operator+=(difference_type n); */ + self operator+(difference_type n) const; + friend self operator+(difference_type n, self x); + + self& operator-=(difference_type n); + self operator-(difference_type n) const; + difference_type operator-(const self&) const; + + reference operator[](difference_type n) const; +}; +static_assert( std::bidirectional_iterator); +static_assert(!std::random_access_iterator); + +struct no_plus_difference_type + : common_base { + + self& operator+=(difference_type n); + /* self operator+(difference_type n) const; */ + friend self operator+(difference_type n, self x); + + self& operator-=(difference_type n); + self operator-(difference_type n) const; + difference_type operator-(const self&) const; + + reference operator[](difference_type n) const; +}; +static_assert( std::bidirectional_iterator); +static_assert(!std::random_access_iterator); + +struct difference_type_no_plus + : common_base { + + self& operator+=(difference_type n); + self operator+(difference_type n) const; + /* friend self operator+(difference_type n, self x); */ + + self& operator-=(difference_type n); + self operator-(difference_type n) const; + difference_type operator-(const self&) const; + + reference operator[](difference_type n) const; +}; +static_assert( std::bidirectional_iterator); +static_assert(!std::random_access_iterator); + +struct no_minus_equals + : common_base { + + self& operator+=(difference_type n); + self operator+(difference_type n) const; + friend self operator+(difference_type n, self x); + + /* self& operator-=(difference_type n); */ + self operator-(difference_type n) const; + difference_type operator-(const self&) const; + + reference operator[](difference_type n) const; +}; +static_assert( std::bidirectional_iterator); +static_assert(!std::random_access_iterator); + +struct no_minus + : common_base { + + self& operator+=(difference_type n); + self operator+(difference_type n) const; + friend self operator+(difference_type n, self x); + + self& operator-=(difference_type n); + /* self operator-(difference_type n) const; */ + difference_type operator-(const self&) const; + + reference operator[](difference_type n) const; +}; +static_assert( std::bidirectional_iterator); +static_assert(!std::random_access_iterator); + +struct not_sized_sentinel + : common_base { + + self& operator+=(difference_type n); + self operator+(difference_type n) const; + friend self operator+(difference_type n, self x); + + self& operator-=(difference_type n); + self operator-(difference_type n) const; + /* difference_type operator-(const self&) const; */ + + reference operator[](difference_type n) const; +}; +static_assert( std::bidirectional_iterator); +static_assert(!std::random_access_iterator); + +struct no_subscript + : common_base { + + self& operator+=(difference_type n); + self operator+(difference_type n) const; + friend self operator+(difference_type n, self x); + + self& operator-=(difference_type n); + self operator-(difference_type n) const; + difference_type operator-(const self&) const; + + /* reference operator[](difference_type n) const; */ +}; +static_assert( std::bidirectional_iterator); +static_assert(!std::random_access_iterator); diff --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp @@ -28,14 +28,17 @@ using reverse_bidirectional_iterator = std::reverse_iterator>; static_assert(common_reverse_iterator_checks()); static_assert(std::bidirectional_iterator); +static_assert(!std::random_access_iterator); static_assert(!std::sized_sentinel_for); using reverse_random_access_iterator = std::reverse_iterator>; static_assert(common_reverse_iterator_checks()); static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(std::sized_sentinel_for); using reverse_contiguous_iterator = std::reverse_iterator>; static_assert(common_reverse_iterator_checks()); static_assert(std::bidirectional_iterator); +static_assert(std::random_access_iterator); static_assert(std::sized_sentinel_for); diff --git a/libcxx/test/std/ranges/range.refinements/random_access_range.compile.pass.cpp b/libcxx/test/std/ranges/range.refinements/random_access_range.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.refinements/random_access_range.compile.pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept random_access_range; + +#include + +#include "test_range.h" +#include "test_iterators.h" + +namespace ranges = std::ranges; + +template