diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h index 3e6022b7cd8f0..c83fd92364c8e 100644 --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -127,7 +127,17 @@ concept forward_iterator = incrementable<_Ip> && sentinel_for<_Ip, _Ip>; -// clang-format on +// [iterator.concept.bidir] +template +concept bidirectional_iterator = + forward_iterator<_Ip> && + derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> && + requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> same_as<_Ip>; + }; + + // clang-format on #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h index 36e6739e1851d..578b153ad00e1 100644 --- a/libcxx/include/__ranges/concepts.h +++ b/libcxx/include/__ranges/concepts.h @@ -58,8 +58,10 @@ namespace ranges { concept forward_range = input_range<_Tp> && forward_iterator >; template - concept common_range = range<_Tp> && same_as, sentinel_t<_Tp> >; + concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator >; + template + concept common_range = range<_Tp> && same_as, sentinel_t<_Tp> >; } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/iterator b/libcxx/include/iterator index 78f67ddf22290..97677feee030e 100644 --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -83,6 +83,10 @@ template template concept forward_iterator = see below; // since C++20 +// [iterator.concept.bidir], concept bidirectional_iterator +template + concept bidirectional_iterator = see below; // since C++20 + template struct iterator diff --git a/libcxx/include/ranges b/libcxx/include/ranges index 58b67f1d086e1..0328360b4ffe3 100644 --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -54,6 +54,9 @@ namespace std::ranges { template concept forward_range = see below; + template + concept bidirectional_range = see below; + template concept common_range = see below; } 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 index a833200a17c0a..1f2707a9c9eb4 100644 --- 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 @@ -22,7 +22,7 @@ using reverse_iterator = std::map::reverse_iterator; using const_reverse_iterator = std::map::const_reverse_iterator; using value_type = std::pair; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,7 +33,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index 998227d0e0de6..2995a5256c649 100644 --- 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 @@ -22,8 +22,8 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_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 index 1693fa076d6e5..1f223d9984a69 100644 --- 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 @@ -22,7 +22,7 @@ using reverse_iterator = std::multimap::reverse_iterator; using const_reverse_iterator = std::multimap::const_reverse_iterator; using value_type = std::pair; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,7 +33,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index dde9ba12f73a5..f9d28d48813f2 100644 --- 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 @@ -22,8 +22,8 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_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 index 1c88b557dab3e..f09efa6aed001 100644 --- 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 @@ -22,7 +22,7 @@ using reverse_iterator = std::multiset::reverse_iterator; using const_reverse_iterator = std::multiset::const_reverse_iterator; using value_type = int; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,7 +33,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index b5c8e2459b90a..d35995a91be03 100644 --- 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 @@ -22,8 +22,8 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_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 index f5f92a997906b..662bf74fa2617 100644 --- 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 @@ -22,7 +22,7 @@ using reverse_iterator = std::set::reverse_iterator; using const_reverse_iterator = std::set::const_reverse_iterator; using value_type = int; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,7 +33,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp index 846c0e39890fb..2816cd29b6f3d 100644 --- 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 @@ -21,7 +21,7 @@ using const_iterator = std::array::const_iterator; using reverse_iterator = std::array::reverse_iterator; using const_reverse_iterator = std::array::const_reverse_iterator; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -32,7 +32,7 @@ static_assert(std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index cdb245ba71f0e..02ea3ca87ece2 100644 --- 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 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_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 index d5d455eda13e1..f301f4d61123a 100644 --- 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 @@ -22,7 +22,7 @@ using reverse_iterator = std::deque::reverse_iterator; using const_reverse_iterator = std::deque::const_reverse_iterator; using value_type = int; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,7 +33,7 @@ static_assert(std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index afb76778141f3..ce8f709e66a2c 100644 --- 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 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp index fae2648706199..6a3edcbd98b5d 100644 --- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp @@ -21,6 +21,7 @@ using const_iterator = std::forward_list::const_iterator; using value_type = int; static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -28,6 +29,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); diff --git a/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp index 19fe3537163aa..a5a73a9e0a9b2 100644 --- a/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/sequences/forwardlist/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_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 index e2b60ce74157c..3acaa34bb33d9 100644 --- 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 @@ -22,7 +22,7 @@ using reverse_iterator = std::list::reverse_iterator; using const_reverse_iterator = std::list::const_reverse_iterator; using value_type = int; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,7 +33,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index c83185036b6f9..404d424d31f03 100644 --- 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 @@ -22,8 +22,8 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_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 index 33203170e7166..1fc5f5d6c3864 100644 --- 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 @@ -22,7 +22,7 @@ using reverse_iterator = std::vector::reverse_iterator; using const_reverse_iterator = std::vector::const_reverse_iterator; using value_type = bool; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,7 +33,7 @@ static_assert(std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index 3fe82de405983..0ed3618797652 100644 --- 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 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_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 index 8f676705047eb..c8a76470debee 100644 --- 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 @@ -22,7 +22,7 @@ using reverse_iterator = std::vector::reverse_iterator; using const_reverse_iterator = std::vector::const_reverse_iterator; using value_type = int; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -33,7 +33,7 @@ static_assert(std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index ab8005427d654..880f5bd5195e0 100644 --- 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 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); diff --git a/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp index 1bc67b21ccdc0..8f23959c11815 100644 --- a/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using const_local_iterator = std::unordered_map::const_local_iterator; using value_type = std::pair; static_assert(std::forward_iterator); +static_assert(!std::bidirectional_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::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -45,6 +47,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(!std::sentinel_for); static_assert(!std::sentinel_for); @@ -56,6 +59,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(!std::sentinel_for); static_assert(!std::sentinel_for); diff --git a/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp index a62ca693f00be..dd50b31c4f24d 100644 --- a/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_range); diff --git a/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp index a53edc95a2c65..1b73f1785b2ff 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using const_local_iterator = std::unordered_multimap::const_local_iter using value_type = std::pair; static_assert(std::forward_iterator); +static_assert(!std::bidirectional_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::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -45,6 +47,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(!std::sentinel_for); static_assert(!std::sentinel_for); @@ -56,6 +59,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(!std::sentinel_for); static_assert(!std::sentinel_for); diff --git a/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp index 2418b0f0fa956..0a6a10f1bb833 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_range); diff --git a/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp index c1b05fe57b224..25e25c4493fec 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using const_local_iterator = std::unordered_multiset::const_local_iterator; using value_type = int; static_assert(std::forward_iterator); +static_assert(!std::bidirectional_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::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -45,6 +47,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(!std::sentinel_for); static_assert(!std::sentinel_for); @@ -56,6 +59,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(!std::sentinel_for); static_assert(!std::sentinel_for); diff --git a/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp index 8d34570890d15..b244fce256fdb 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_range); diff --git a/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp index 01e36e191fe51..50426a2a4c37c 100644 --- a/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp @@ -23,6 +23,7 @@ using const_local_iterator = std::unordered_set::const_local_iterator; using value_type = int; static_assert(std::forward_iterator); +static_assert(!std::bidirectional_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::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(std::sentinel_for); static_assert(std::sentinel_for); @@ -45,6 +47,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::sentinel_for); static_assert(!std::sentinel_for); static_assert(std::sentinel_for); @@ -55,6 +58,7 @@ static_assert(!std::sized_sentinel_for); static_assert(!std::sized_sentinel_for); static_assert(std::forward_iterator); +static_assert(!std::bidirectional_iterator); static_assert(!std::indirectly_writable); static_assert(!std::sentinel_for); static_assert(!std::sentinel_for); diff --git a/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp index e792ce052d648..ab72da83b5432 100644 --- a/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/range_concept_conformance.compile.pass.cpp @@ -23,7 +23,9 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_range); static_assert(std::same_as, range::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::forward_range); +static_assert(!stdr::bidirectional_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 index 53f4e9082ec41..9234639dcf184 100644 --- 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 @@ namespace stdr = std::ranges; static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_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 index 55d5c38569311..355ece63681cd 100644 --- 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 @@ -20,7 +20,7 @@ using iterator = std::span::iterator; using reverse_iterator = std::span::reverse_iterator; using value_type = int; -static_assert(std::forward_iterator); +static_assert(std::bidirectional_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 index 6f22e25da77a2..281679c6dfda6 100644 --- 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 @@ -21,8 +21,8 @@ namespace stdr = std::ranges; static_assert(std::same_as, fs::path::iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); static_assert(std::same_as, fs::path::const_iterator>); static_assert(stdr::common_range); -static_assert(stdr::forward_range); +static_assert(stdr::bidirectional_range); diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/bidirectional_iterator.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/bidirectional_iterator.compile.pass.cpp new file mode 100644 index 0000000000000..3fec74d2f86d3 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/bidirectional_iterator.compile.pass.cpp @@ -0,0 +1,149 @@ +//===----------------------------------------------------------------------===// +// +// 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 bidirectional_iterator; + +#include + +#include + +#include "test_iterators.h" + +static_assert(!std::bidirectional_iterator >); +static_assert(!std::bidirectional_iterator >); +static_assert(!std::bidirectional_iterator >); +static_assert(std::bidirectional_iterator >); +static_assert(std::bidirectional_iterator >); +static_assert(std::bidirectional_iterator >); + + +static_assert(std::bidirectional_iterator); +static_assert(std::bidirectional_iterator); +static_assert(std::bidirectional_iterator); +static_assert(std::bidirectional_iterator); + +struct not_forward_iterator { + using value_type = int; + using difference_type = std::ptrdiff_t; + using iterator_concept = std::bidirectional_iterator_tag; + + value_type operator*() const; + + not_forward_iterator& operator++(); + not_forward_iterator operator++(int); + + not_forward_iterator& operator--(); + not_forward_iterator& operator--(int); +}; +static_assert(std::input_iterator && !std::forward_iterator && + !std::bidirectional_iterator); + +struct wrong_iterator_category { + using value_type = int; + using difference_type = std::ptrdiff_t; + using iterator_category = std::forward_iterator_tag; + + value_type& operator*() const; + + wrong_iterator_category& operator++(); + wrong_iterator_category operator++(int); + + wrong_iterator_category& operator--(); + wrong_iterator_category operator--(int); + + bool operator==(wrong_iterator_category const&) const = default; +}; +static_assert(!std::bidirectional_iterator); + +struct wrong_iterator_concept { + using value_type = int; + using difference_type = std::ptrdiff_t; + using iterator_concept = std::forward_iterator_tag; + + value_type& operator*() const; + + wrong_iterator_concept& operator++(); + wrong_iterator_concept operator++(int); + + wrong_iterator_concept& operator--(); + wrong_iterator_concept operator--(int); + + bool operator==(wrong_iterator_concept const&) const = default; +}; +static_assert(!std::bidirectional_iterator); + +struct no_predecrement { + using value_type = int; + using difference_type = std::ptrdiff_t; + using iterator_concept = std::bidirectional_iterator_tag; + + value_type& operator*() const; + + no_predecrement& operator++(); + no_predecrement operator++(int); + + no_predecrement operator--(int); + + bool operator==(no_predecrement const&) const = default; +}; +static_assert(!std::bidirectional_iterator); + +struct bad_predecrement { + using value_type = int; + using difference_type = std::ptrdiff_t; + using iterator_concept = std::bidirectional_iterator_tag; + + value_type& operator*() const; + + bad_predecrement& operator++(); + bad_predecrement operator++(int); + + bad_predecrement operator--(); + bad_predecrement operator--(int); + + bool operator==(bad_predecrement const&) const = default; +}; +static_assert(!std::bidirectional_iterator); + +struct no_postdecrement { + using value_type = int; + using difference_type = std::ptrdiff_t; + using iterator_concept = std::bidirectional_iterator_tag; + + value_type& operator*() const; + + no_postdecrement& operator++(); + no_postdecrement operator++(int); + + no_postdecrement& operator--(); + + bool operator==(no_postdecrement const&) const = default; +}; +static_assert(!std::bidirectional_iterator); + +struct bad_postdecrement { + using value_type = int; + using difference_type = std::ptrdiff_t; + using iterator_concept = std::bidirectional_iterator_tag; + + value_type& operator*() const; + + bad_postdecrement& operator++(); + bad_postdecrement operator++(int); + + bad_postdecrement& operator--(); + bad_postdecrement& operator--(int); + + bool operator==(bad_postdecrement const&) const = default; +}; +static_assert(!std::bidirectional_iterator); 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 new file mode 100644 index 0000000000000..b3d0e9c931d32 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.bidir/subsumption.compile.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 bidirectional_iterator; + +#include + +#include + +template +[[nodiscard]] constexpr bool check_subsumption() { + return false; +} + +template +[[nodiscard]] constexpr bool check_subsumption() { + return true; +} + +static_assert(check_subsumption()); 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 index 4144617e233ed..dac2c4dbcf053 100644 --- 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 @@ -27,15 +27,15 @@ template using reverse_bidirectional_iterator = std::reverse_iterator>; static_assert(common_reverse_iterator_checks()); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(!std::sized_sentinel_for); using reverse_random_access_iterator = std::reverse_iterator>; static_assert(common_reverse_iterator_checks()); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(std::sized_sentinel_for); using reverse_contiguous_iterator = std::reverse_iterator>; static_assert(common_reverse_iterator_checks()); -static_assert(std::forward_iterator); +static_assert(std::bidirectional_iterator); static_assert(std::sized_sentinel_for); diff --git a/libcxx/test/std/ranges/range.refinements/bidirectional_range.compile.pass.cpp b/libcxx/test/std/ranges/range.refinements/bidirectional_range.compile.pass.cpp new file mode 100644 index 0000000000000..56245c9f7dbf9 --- /dev/null +++ b/libcxx/test/std/ranges/range.refinements/bidirectional_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 bidirectional_range; + +#include + +#include "test_range.h" + +namespace stdr = std::ranges; + +template