namespace ranges {
+template<class _Fn, class _View>
+concept __regular_invocable_with_range_ref =
+ regular_invocable<_Fn, range_reference_t<_View>>;
+
template<class _View, class _Fn>
concept __transform_view_constraints =
- view<_View> && is_object_v<_Fn> &&
- regular_invocable<_Fn&, range_reference_t<_View>> &&
- __referenceable<invoke_result_t<_Fn&, range_reference_t<_View>>>;
+ view<_View> && is_object_v<_Fn> &&
+ regular_invocable<_Fn&, range_reference_t<_View>> &&
+ __referenceable<invoke_result_t<_Fn&, range_reference_t<_View>>>;
template<input_range _View, copy_constructible _Fn>
requires __transform_view_constraints<_View, _Fn>
_LIBCPP_HIDE_FROM_ABI
constexpr __iterator<true> begin() const
requires range<const _View> &&
- regular_invocable<const _Fn&, range_reference_t<const _View>>
+ __regular_invocable_with_range_ref<const _Fn&, const _View>
{
return __iterator<true>(*this, ranges::begin(__base_));
}
_LIBCPP_HIDE_FROM_ABI
constexpr __sentinel<true> end() const
requires range<const _View> &&
- regular_invocable<const _Fn&, range_reference_t<const _View>>
+ __regular_invocable_with_range_ref<const _Fn&, const _View>
{
return __sentinel<true>(ranges::end(__base_));
}
_LIBCPP_HIDE_FROM_ABI
constexpr __iterator<true> end() const
requires common_range<const _View> &&
- regular_invocable<const _Fn&, range_reference_t<const _View>>
+ __regular_invocable_with_range_ref<const _Fn&, const _View>
{
return __iterator<true>(*this, ranges::end(__base_));
}
return std::ranges::transform_view(range, [](char c) { return std::toupper(c); });
}
-unsigned badRandom() { return 42; }
-
-template<std::ranges::range R, class Fn = std::plus<std::iter_value_t<R>>>
-auto withRandom(R&& range, Fn func = Fn()) {
- return std::ranges::transform_view(range, std::bind_front(func, badRandom()));
-}
-
template<class E1, class E2, size_t N, class Join = std::plus<E1>>
auto joinArrays(E1 (&a)[N], E2 (&b)[N], Join join = Join()) {
return std::ranges::transform_view(a, [&a, &b, join](auto& x) {
});
}
+struct NonConstView : std::ranges::view_base {
+ explicit NonConstView(int *b, int *e) : b_(b), e_(e) {}
+ const int *begin() { return b_; } // deliberately non-const
+ const int *end() { return e_; } // deliberately non-const
+ const int *b_;
+ const int *e_;
+};
+
int main(int, char**) {
{
- std::vector vec = {1, 2, 3, 4};
- auto sortOfRandom = withRandom(vec);
- std::vector check = {43, 44, 45, 46};
- assert(std::equal(sortOfRandom.begin(), sortOfRandom.end(), check.begin(), check.end()));
+ std::vector<int> vec = {1, 2, 3, 4};
+ auto transformed = std::ranges::transform_view(vec, [](int x) { return x + 42; });
+ int expected[] = {43, 44, 45, 46};
+ assert(std::equal(transformed.begin(), transformed.end(), expected, expected + 4));
+ const auto& ct = transformed;
+ assert(std::equal(ct.begin(), ct.end(), expected, expected + 4));
+ }
+
+ {
+ // Test a view type that is not const-iterable.
+ int a[] = {1, 2, 3, 4};
+ auto transformed = NonConstView(a, a + 4) | std::views::transform([](int x) { return x + 42; });
+ int expected[4] = {43, 44, 45, 46};
+ assert(std::equal(transformed.begin(), transformed.end(), expected, expected + 4));
}
{
int b[4] = {4, 3, 2, 1};
auto out = joinArrays(a, b);
int check[4] = {5, 5, 5, 5};
- assert(std::equal(out.begin(), out.end(), check));
+ assert(std::equal(out.begin(), out.end(), check, check + 4));
}
{