[libcxx-commits] [libcxx] [libc++] Fix `take_view::__sentinel`'s `operator==` (PR #74655)
Jakub Mazurkiewicz via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Dec 7 06:17:50 PST 2023
================
@@ -0,0 +1,192 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// friend constexpr bool operator==(const CI<Const>& y, const sentinel& x);
+// template<bool OtherConst = !Const>
+// requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
+// friend constexpr bool operator==(const CI<OtherConst>& y, const sentinel& x);
+
+#include <cassert>
+#include <cstddef>
+#include <ranges>
+#include <type_traits>
+#include <utility>
+
+#include "test_iterators.h"
+
+template <bool Const>
+class StrictIterator {
+ using Base = std::conditional_t<Const, const int*, int*>;
+ Base base_;
+
+public:
+ using value_type = int;
+ using difference_type = std::ptrdiff_t;
+
+ constexpr explicit StrictIterator(Base base) : base_(base) {}
+
+ StrictIterator(StrictIterator&&) = default;
+ StrictIterator& operator=(StrictIterator&&) = default;
+
+ constexpr StrictIterator& operator++() {
+ ++base_;
+ return *this;
+ }
+
+ constexpr void operator++(int) { ++*this; }
+ constexpr decltype(auto) operator*() const { return *base_; }
+ constexpr Base base() const { return base_; }
+};
+
+static_assert(std::input_iterator<StrictIterator<false>>);
+static_assert(!std::copyable<StrictIterator<false>>);
+static_assert(!std::forward_iterator<StrictIterator<false>>);
+static_assert(std::input_iterator<StrictIterator<true>>);
+static_assert(!std::copyable<StrictIterator<true>>);
+static_assert(!std::forward_iterator<StrictIterator<true>>);
+
+template <bool Const>
+class StrictSentinel {
+ using Base = std::conditional_t<Const, const int*, int*>;
+ Base base_;
+
+public:
+ StrictSentinel() = default;
+ constexpr explicit StrictSentinel(Base base) : base_(base) {}
+
+ friend constexpr bool operator==(const StrictIterator<Const>& it, const StrictSentinel& se) {
+ return it.base() == se.base_;
+ }
+
+ friend constexpr bool operator==(const StrictIterator<!Const>& it, const StrictSentinel& se) {
+ return it.base() == se.base_;
+ }
+};
+
+static_assert(std::sentinel_for<StrictSentinel<true>, StrictIterator<false>>);
+static_assert(std::sentinel_for<StrictSentinel<true>, StrictIterator<true>>);
+static_assert(std::sentinel_for<StrictSentinel<false>, StrictIterator<false>>);
+static_assert(std::sentinel_for<StrictSentinel<false>, StrictIterator<true>>);
+
+struct NotSimpleView : std::ranges::view_base {
+ template <std::size_t N>
+ constexpr explicit NotSimpleView(int (&arr)[N]) : b_(arr), e_(arr + N) {}
+
+ constexpr StrictIterator<false> begin() { return StrictIterator<false>{b_}; }
+ constexpr StrictSentinel<false> end() { return StrictSentinel<false>{e_}; }
+
+ constexpr StrictIterator<true> begin() const { return StrictIterator<true>{b_}; }
+ constexpr StrictSentinel<true> end() const { return StrictSentinel<true>{e_}; }
+
+private:
+ int* b_;
+ int* e_;
+};
+
+static_assert(std::ranges::range<NotSimpleView>);
+static_assert(std::ranges::range<const NotSimpleView>);
+
+struct FancyNonSimpleView : std::ranges::view_base {
----------------
JMazurkiewicz wrote:
I've renamed these things to:
* `StrictIterator` -> `MaybeConstIterator`
* `FancyNonSimpleView` -> `NonCrossConstComparableView`
* `NonSimpleView` -> `CrossConstComparableView`
* `StrictSentinel` -> `CrossConstComparableSentinel`
I hope this is ok.
https://github.com/llvm/llvm-project/pull/74655
More information about the libcxx-commits
mailing list