[libcxx-commits] [libcxx] [libc++] Implement `views::join_with` (PR #65536)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Dec 26 07:20:16 PST 2024
================
@@ -0,0 +1,234 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <ranges>
+
+// constexpr auto end();
+// constexpr auto end() const
+// requires forward_range<const V> && forward_range<const Pattern> &&
+// is_reference_v<range_reference_t<const V>> &&
+// input_range<range_reference_t<const V>>;
+
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=10000000
+
+#include <ranges>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "../types.h"
+#include "test_iterators.h"
+
+template <class V, class Pattern>
+concept JoinWithViewHasConstEnd = requires(const std::ranges::join_with_view<V, Pattern> jwv) { jwv.end(); };
+
+template <size_t Bits>
+ requires(Bits < (1 << 7))
+constexpr void test_end() {
+ constexpr bool v_models_forward_range = Bits & (1 << 0);
+ constexpr bool inner_range_is_reference = Bits & (1 << 1);
+ constexpr bool inner_range_models_forward_range = Bits & (1 << 2);
+ constexpr bool v_models_common_range = Bits & (1 << 3);
+ constexpr bool inner_range_models_common_range = Bits & (1 << 4);
+ constexpr bool v_models_simple_range = Bits & (1 << 5);
+ constexpr bool pattern_models_simple_range = Bits & (1 << 6);
+
+ constexpr ViewProperties inner_range_props{.common = inner_range_models_common_range};
+ using InnerRange =
+ std::conditional_t<inner_range_models_forward_range,
+ BasicView<std::vector<int>, inner_range_props, forward_iterator>,
+ BasicView<std::vector<int>, inner_range_props, DefaultCtorInputIter>>;
+
+ constexpr ViewProperties v_props{.simple = v_models_simple_range, .common = v_models_common_range};
+ using UnderlyingV = std::conditional_t<inner_range_is_reference, std::vector<InnerRange>, RvalueVector<InnerRange>>;
+ using V = std::conditional_t<v_models_forward_range,
+ BasicView<UnderlyingV, v_props, forward_iterator>,
+ BasicView<UnderlyingV, v_props, DefaultCtorInputIter>>;
+
+ using UnderlyingPattern = std::vector<int>;
+ using Pattern = BasicView<UnderlyingPattern, ViewProperties{.simple = pattern_models_simple_range}, forward_iterator>;
+
+ using JWV = std::ranges::join_with_view<V, Pattern>;
+ using Iter = std::ranges::iterator_t<JWV>;
+
+ // Test when `JWV` models common range
+ static_assert(std::same_as<Iter, std::ranges::sentinel_t<JWV>> ==
+ (v_models_forward_range && inner_range_is_reference && inner_range_models_forward_range &&
+ v_models_common_range && inner_range_models_common_range));
+
+ { // `V` and `Pattern` are empty
+ V v{};
+ Pattern pattern{};
+ JWV jwv(std::move(v), std::move(pattern));
+ Iter it = jwv.begin();
+ std::sentinel_for<Iter> decltype(auto) se = jwv.end();
+ assert(it == se);
+ }
+
+ { // `V` is empty, `Pattern` contains some elements
+ V v{};
+ Pattern pattern{std::vector<int>{0}};
+ JWV jwv(std::move(v), std::move(pattern));
+ Iter it = jwv.begin();
+ std::sentinel_for<Iter> decltype(auto) se = jwv.end();
+ assert(it == se);
+ }
+
+ { // `V` is not empty, `Pattern is empty`
+ V v{UnderlyingV{
+ std::vector<InnerRange>{InnerRange(std::vector<int>{1, 2, 3}), InnerRange(std::vector<int>{4, 5, 6})}}};
+ Pattern pattern{};
+ JWV jwv(std::move(v), std::move(pattern));
+ Iter it = jwv.begin();
+ std::sentinel_for<Iter> decltype(auto) se = jwv.end();
+ assert(std::ranges::next(it, 6) == se);
+ }
+
+ { // `V` and `Pattern` are not empty
+ V v{UnderlyingV{std::vector<InnerRange>{
+ InnerRange(std::vector<int>{6, 5}),
+ InnerRange(std::vector<int>{4, 3}),
+ InnerRange(std::vector<int>{2, 1, 0})}}};
+ Pattern pattern{std::vector<int>{-1, -1}};
+ JWV jwv(std::move(v), std::move(pattern));
+ Iter it = jwv.begin();
+ std::sentinel_for<Iter> decltype(auto) se = jwv.end();
+ assert(std::ranges::next(it, 11) == se);
+ }
+}
+
+constexpr void test_end() {}
----------------
huixie90 wrote:
why is this needed?
https://github.com/llvm/llvm-project/pull/65536
More information about the libcxx-commits
mailing list