[libcxx-commits] [libcxx] [libc++][c++23] P2374: `views::cartesian_product` (PR #111215)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Apr 22 13:47:15 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_));
+  }
----------------
PaulXiCao wrote:

Started implementation for `cartesian_product_view::begin()` here: 2bd9a15c22d0, 7d3e60cec92b. More to come..

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


More information about the libcxx-commits mailing list