[libcxx-commits] [libcxx] [libc++][c++23] P2374: `views::cartesian_product` (PR #111215)
Hristo Hristov via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Apr 17 22:54:02 PDT 2026
================
@@ -0,0 +1,477 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_CARTESIAN_PRODUCT_VIEW_H
+#define _LIBCPP___RANGES_CARTESIAN_PRODUCT_VIEW_H
+
+#include <__config>
+#include <__iterator/access.h> // begin
+#include <__iterator/default_sentinel.h>
+#include <__iterator/distance.h>
+#include <__iterator/iter_move.h>
+#include <__iterator/next.h>
+#include <__memory/addressof.h>
+#include <__ranges/concepts.h> // forward_range, view, range_size_t, sized_range, ...
+#include <__ranges/zip_view.h> // tuple_transform
+#include <__type_traits/maybe_const.h>
+#include <tuple> // apply
+#include <type_traits> // common_type_t
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+
+template <bool Const, class First, class... Vs>
+concept cartesian_product_is_random_access =
+ (random_access_range<__maybe_const<Const, First>> && ... &&
+ (random_access_range<__maybe_const<Const, Vs>> && sized_range<__maybe_const<Const, Vs>>));
+
+template <class R>
+concept cartesian_product_common_arg = common_range<R> || (sized_range<R> && random_access_range<R>);
+
+template <bool Const, class First, class... Vs>
+concept cartesian_product_is_bidirectional =
+ (bidirectional_range<__maybe_const<Const, First>> && ... &&
+ (bidirectional_range<__maybe_const<Const, Vs>> && cartesian_product_common_arg<__maybe_const<Const, Vs>>));
+
+template <class First, class... Vs>
+concept cartesian_product_is_common = cartesian_product_common_arg<First>;
+
+template <class... Vs>
+concept cartesian_product_is_sized = (sized_range<Vs> && ...);
+
+template <bool Const, template <class> class FirstSent, class First, class... Vs>
+concept cartesian_is_sized_sentinel =
+ (sized_sentinel_for<FirstSent<__maybe_const<Const, First>>, iterator_t<__maybe_const<Const, First>>> && ... &&
+ (sized_range<__maybe_const<Const, Vs>> &&
+ sized_sentinel_for<iterator_t<__maybe_const<Const, Vs>>, iterator_t<__maybe_const<Const, Vs>>>));
+
+template <cartesian_product_common_arg R>
+constexpr auto cartesian_common_arg_end(R& r) {
+ if constexpr (common_range<R>) {
+ return ranges::end(r);
+ } else {
+ return ranges::begin(r) + ranges::distance(r);
+ }
+}
+
+template <bool Const, class First, class... Vs>
+concept __cartesian_product_all_random_access =
+ (random_access_range<__maybe_const<Const, First>> && ... && random_access_range<__maybe_const<Const, Vs>>);
+
+template <input_range First, forward_range... Vs>
+ requires(view<First> && ... && view<Vs>)
+class cartesian_product_view : public view_interface<cartesian_product_view<First, Vs...>> {
+private:
+ tuple<First, Vs...> bases_;
+
+ template <bool Const>
+ class iterator;
+
+public:
+ constexpr cartesian_product_view() = default;
+ constexpr explicit cartesian_product_view(First first_base, Vs... bases)
+ : bases_{std::move(first_base), std::move(bases)...} {}
+
+ constexpr iterator<false> begin()
+ requires(!__simple_view<First> || ... || !__simple_view<Vs>)
+ {
+ return iterator<false>(*this, __tuple_transform(ranges::begin, bases_));
+ }
----------------
H-G-Hristov wrote:
Please annotate with `[nodiscard]` whereever is relevant + tests according to: https://libcxx.llvm.org/CodingGuidelines.html#apply-nodiscard-where-relevant
```suggestion
[[nodiscard]] constexpr iterator<false> begin()
requires(!__simple_view<First> || ... || !__simple_view<Vs>)
{
return iterator<false>(*this, __tuple_transform(ranges::begin, bases_));
}
```
https://github.com/llvm/llvm-project/pull/111215
More information about the libcxx-commits
mailing list