[libcxx-commits] [libcxx] [libc++][ranges] Implement `ranges::stride_view`. (PR #65200)

Konstantin Varlamov via libcxx-commits libcxx-commits at lists.llvm.org
Mon Oct 2 20:44:21 PDT 2023


================
@@ -0,0 +1,413 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_STRIDE_VIEW_H
+#define _LIBCPP___RANGES_STRIDE_VIEW_H
+
+#include <__config>
+
+#include <__compare/three_way_comparable.h>
+#include <__concepts/constructible.h>
+#include <__concepts/convertible_to.h>
+#include <__concepts/derived_from.h>
+#include <__functional/bind_back.h>
+#include <__iterator/advance.h>
+#include <__iterator/concepts.h>
+#include <__iterator/default_sentinel.h>
+#include <__iterator/distance.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/iter_swap.h>
+#include <__iterator/iterator_traits.h>
+#include <__iterator/next.h>
+#include <__ranges/access.h>
+#include <__ranges/all.h>
+#include <__ranges/concepts.h>
+#include <__ranges/enable_borrowed_range.h>
+#include <__ranges/non_propagating_cache.h>
+#include <__ranges/range_adaptor.h>
+#include <__ranges/size.h>
+#include <__ranges/subrange.h>
+#include <__ranges/view_interface.h>
+#include <__ranges/views.h>
+#include <__type_traits/conditional.h>
+#include <__type_traits/maybe_const.h>
+#include <__type_traits/remove_cvref.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template <class _Value>
+_LIBCPP_HIDE_FROM_ABI constexpr _Value __div_ceil(_Value __left, _Value __right) {
+  _Value __r = __left / __right;
+  if (__left % __right) {
+    __r++;
+  }
+  return __r;
+}
+
+template <input_range _View>
+  requires view<_View>
+class stride_view : public view_interface<stride_view<_View>> {
+  _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
+  range_difference_t<_View> __stride_     = 0;
+
+  template <bool _Const>
+  class __iterator;
+
+public:
+  _LIBCPP_HIDE_FROM_ABI constexpr explicit stride_view(_View __base, range_difference_t<_View> __stride)
+      : __base_(std::move(__base)), __stride_(__stride) {}
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
+    requires copy_constructible<_View>
+  {
+    return __base_;
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_View> stride() const noexcept { return __stride_; }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto size()
+    requires sized_range<_View>
+  {
+    return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
+    requires sized_range<const _View>
+  {
+    return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_));
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr auto begin()
+    requires(!__simple_view<_View>)
+  {
+    return __iterator<false>{*this, ranges::begin(__base_)};
----------------
var-const wrote:

I think the Standard doesn't use list initialization here and in similar functions below. Like mentioned in another comment, I think it's better to avoid introducing a diff without a strong reason. In this case, it adds some cognitive burden, however small, to make sure there is no case where the rules for list initialization would differ from direct initialization.

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


More information about the libcxx-commits mailing list