[libcxx-commits] [libcxx] [libc++] Implement adjacent_view (PR #165089)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Dec 5 12:03:56 PST 2025
================
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++20
+// UNSUPPORTED: no-exceptions
+
+// If the invocation of any non-const member function of `iterator` exits via an
+// exception, the iterator acquires a singular value.
+
+#include <ranges>
+
+#include <tuple>
+
+#include "../../range_adaptor_types.h"
+
+struct ThrowOnDecrementIterator {
+ int* it_;
+
+ using value_type = int;
+ using difference_type = std::intptr_t;
+
+ ThrowOnDecrementIterator() = default;
+ explicit ThrowOnDecrementIterator(int* it) : it_(it) {}
+
+ ThrowOnDecrementIterator& operator++() {
+ ++it_;
+ return *this;
+ }
+ ThrowOnDecrementIterator operator++(int) {
+ auto tmp = *this;
+ ++it_;
+ return tmp;
+ }
+
+ ThrowOnDecrementIterator& operator--() { throw 5; }
+ ThrowOnDecrementIterator operator--(int) { throw 5; }
+
+ int& operator*() const { return *it_; }
+
+ friend bool operator==(ThrowOnDecrementIterator const&, ThrowOnDecrementIterator const&) = default;
+};
+
+struct ThrowOnIncrementView : IntBufferView {
+ ThrowOnDecrementIterator begin() const { return ThrowOnDecrementIterator{buffer_}; }
+ ThrowOnDecrementIterator end() const { return ThrowOnDecrementIterator{buffer_ + size_}; }
+};
+
+template <std::size_t N>
+void test() {
+ int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8};
+ {
+ // adjacent_view iterator should be able to be destroyed after member function throws
+ auto v = ThrowOnIncrementView{buffer} | std::views::adjacent<N>;
+ auto it = v.begin();
+ ++it;
+ try {
+ --it;
+ assert(false); // should not be reached as the above expression should throw.
+ } catch (int e) {
+ assert(e == 5);
+ }
+ }
+
+ {
+ // adjacent_view iterator should be able to be assigned after member function throws
----------------
ldionne wrote:
```suggestion
// adjacent_view iterator should be assignable after member function throws
```
https://github.com/llvm/llvm-project/pull/165089
More information about the libcxx-commits
mailing list