[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,181 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// constexpr auto end() requires(!simple-view<_View>)
+// constexpr auto end() const requires range<const _View>
+
+#include <array>
+#include <cassert>
+#include <iterator>
+#include <ranges>
+#include <type_traits>
+#include <utility>
+
+#include "../range_adaptor_types.h"
+
+template <class Underlying, std::size_t N>
+constexpr void test_one() {
+  {
+    int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+    std::ranges::adjacent_view<Underlying, N> v{Underlying{buffer}};
+
+    auto it     = v.begin();
+    auto cit    = std::as_const(v).begin();
+    auto endIt  = v.end();
+    auto cendIt = std::as_const(v).end();
+    assert(it != endIt);
+    assert(cit != cendIt);
+    std::ranges::advance(it, 8 - (N - 1));
+    std::ranges::advance(cit, 8 - (N - 1));
+    assert(it == endIt);
+    assert(cit == cendIt);
+  }
+  {
+    // empty range
+    std::array<int, 0> buffer = {};
+    std::ranges::adjacent_view<Underlying, N> v{Underlying{buffer.data(), 0}};
+    auto it     = v.begin();
+    auto cit    = std::as_const(v).begin();
+    auto endIt  = v.end();
+    auto cendIt = std::as_const(v).end();
+    assert(it == endIt);
+    assert(cit == cendIt);
+  }
+  if constexpr (N > 2) {
+    // N greater than range size
+    int buffer[2] = {1, 2};
+    std::ranges::adjacent_view<Underlying, N> v{Underlying{buffer}};
+    auto it     = v.begin();
+    auto cit    = std::as_const(v).begin();
+    auto endIt  = v.end();
+    auto cendIt = std::as_const(v).end();
+    assert(it == endIt);
+    assert(cit == cendIt);
+  }
+}
+
+template <class Underlying, std::size_t N>
+constexpr void test_decrement_back() {
+  int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+  std::ranges::adjacent_view<Underlying, N> v{Underlying{buffer}};
+  auto endIt  = v.end();
+  auto cendIt = std::as_const(v).end();
+
+  --endIt;
+  --cendIt;
+  auto tuple  = *endIt;
+  auto ctuple = *cendIt;
+  assert(std::get<0>(tuple) == buffer[8 - N]);
+  assert(std::get<0>(ctuple) == buffer[8 - N]);
+  if constexpr (N >= 2) {
+    assert(std::get<1>(tuple) == buffer[9 - N]);
+    assert(std::get<1>(ctuple) == buffer[9 - N]);
+  }
+  if constexpr (N >= 3) {
+    assert(std::get<2>(tuple) == buffer[10 - N]);
+    assert(std::get<2>(ctuple) == buffer[10 - N]);
+  }
+  if constexpr (N >= 4) {
+    assert(std::get<3>(tuple) == buffer[11 - N]);
+    assert(std::get<3>(ctuple) == buffer[11 - N]);
+  }
+  if constexpr (N >= 5) {
+    assert(std::get<4>(tuple) == buffer[12 - N]);
+    assert(std::get<4>(ctuple) == buffer[12 - N]);
+  }
+}
+
+template <std::size_t N>
+constexpr void test_simple_common_types() {
----------------
ldionne wrote:

I would suggest inlining these functions into the caller but defining a scope around each test case. IMO it makes it easier to follow where things are called.

https://github.com/llvm/llvm-project/pull/165089


More information about the libcxx-commits mailing list