[libcxx-commits] [PATCH] D113695: [libcxx] Implement three-way comparison for std::reverse_iterator

Mikhail Maltsev via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Nov 11 10:35:48 PST 2021


miyuki created this revision.
miyuki added reviewers: ldionne, Quuxplusone.
miyuki requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

This patch implements operator<=> for std::reverse_iterator and
also adds a test that checks that three-way comparison of different
instantiations of std::reverse_iterator works as expected (related to
D113417 <https://reviews.llvm.org/D113417>).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113695

Files:
  libcxx/include/__iterator/reverse_iterator.h
  libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/three-way.pass.cpp


Index: libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/three-way.pass.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/three-way.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <iterator>
+
+// reverse_iterator
+
+// template<class Iterator1, three_way_comparable_with<Iterator1> Iterator2>
+//   constexpr compare_three_way_result_t<Iterator1, Iterator2>
+//    operator<=>(const reverse_iterator<Iterator1>& x,
+//                const reverse_iterator<Iterator2>& y);
+
+#include <iterator>
+#include <cassert>
+
+#include "test_macros.h"
+#include "test_iterators.h"
+
+template <class ItL, class ItR>
+constexpr void test(ItL l, ItR r, std::strong_ordering x) {
+    const std::reverse_iterator<ItL> l1(l);
+    const std::reverse_iterator<ItR> r1(r);
+    ASSERT_SAME_TYPE(decltype(l1 <=> r1), std::strong_ordering);
+    assert((l1 <=> r1) == x);
+}
+
+constexpr bool tests() {
+    char s[] = "1234567890";
+    test(three_way_contiguous_iterator<const char*>(s),
+         three_way_contiguous_iterator<const char*>(s),
+         std::strong_ordering::equal);
+    test(three_way_contiguous_iterator<const char*>(s),
+         three_way_contiguous_iterator<const char*>(s+1),
+         std::strong_ordering::greater);
+    test(three_way_contiguous_iterator<const char*>(s+1),
+         three_way_contiguous_iterator<const char*>(s),
+         std::strong_ordering::less);
+    test(s, s, std::strong_ordering::equal);
+    test(s, s+1, std::strong_ordering::greater);
+    test(s+1, s, std::strong_ordering::less);
+    const char* cs = s;
+    test(cs, s, std::strong_ordering::equal);
+    test(cs, s+1, std::strong_ordering::greater);
+    test(cs+1, s, std::strong_ordering::less);
+    return true;
+}
+
+int main(int, char**) {
+    tests();
+    static_assert(tests(), "");
+    return 0;
+}
Index: libcxx/include/__iterator/reverse_iterator.h
===================================================================
--- libcxx/include/__iterator/reverse_iterator.h
+++ libcxx/include/__iterator/reverse_iterator.h
@@ -193,6 +193,16 @@
     return __x.base() >= __y.base();
 }
 
+#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_SPACESHIP_OPERATOR) && !defined(_LIBCPP_HAS_NO_CONCEPTS)
+template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2>
+inline _LIBCPP_INLINE_VISIBILITY constexpr
+compare_three_way_result_t<_Iter1, _Iter2>
+operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y)
+{
+    return __y.base() <=> __x.base();
+}
+#endif
+
 #ifndef _LIBCPP_CXX03_LANG
 template <class _Iter1, class _Iter2>
 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113695.386584.patch
Type: text/x-patch
Size: 3220 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211111/39ac2cf8/attachment-0001.bin>


More information about the libcxx-commits mailing list