128 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 11// constexpr auto begin();12// constexpr auto begin() const13// requires range<const InnerView> &&14// regular_invocable<const F&, range_reference_t<const Views>...>;15 16#include <ranges>17 18#include <cassert>19#include <concepts>20 21#include "types.h"22 23template <class T>24concept HasConstBegin = requires(const T& ct) { ct.begin(); };25 26template <class T>27concept HasBegin = requires(T& t) { t.begin(); };28 29constexpr bool test() {30 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};31 {32 // all underlying iterators should be at the begin position33 std::ranges::zip_transform_view v(34 MakeTuple{}, SimpleCommon{buffer}, std::views::iota(0), std::ranges::single_view(2.));35 auto it = v.begin();36 assert(*it == std::make_tuple(1, 0, 2.0));37 38 auto const_it = std::as_const(v).begin();39 assert(*const_it == *it);40 41 static_assert(!std::same_as<decltype(it), decltype(const_it)>);42 }43 44 {45 // one range46 std::ranges::zip_transform_view v(MakeTuple{}, SimpleCommon{buffer});47 auto it = v.begin();48 assert(*it == std::make_tuple(1));49 auto cit = std::as_const(v).begin();50 assert(*cit == std::make_tuple(1));51 }52 53 {54 // two ranges55 std::ranges::zip_transform_view v(GetFirst{}, SimpleCommon{buffer}, std::views::iota(0));56 auto it = v.begin();57 assert(&*it == &buffer[0]);58 auto cit = std::as_const(v).begin();59 assert(&*cit == &buffer[0]);60 }61 62 {63 // three ranges64 std::ranges::zip_transform_view v(Tie{}, SimpleCommon{buffer}, SimpleCommon{buffer}, std::ranges::single_view(2.));65 auto it = v.begin();66 assert(&std::get<0>(*it) == &buffer[0]);67 assert(&std::get<1>(*it) == &buffer[0]);68 assert(std::get<2>(*it) == 2.0);69 auto cit = std::as_const(v).begin();70 assert(&std::get<0>(*cit) == &buffer[0]);71 assert(&std::get<1>(*cit) == &buffer[0]);72 assert(std::get<2>(*cit) == 2.0);73 }74 75 {76 // single empty range77 std::ranges::zip_transform_view v(MakeTuple{}, std::ranges::empty_view<int>());78 assert(v.begin() == v.end());79 assert(std::as_const(v).begin() == std::as_const(v).end());80 }81 82 {83 // empty range at the beginning84 std::ranges::zip_transform_view v(85 MakeTuple{}, std::ranges::empty_view<int>(), SimpleCommon{buffer}, SimpleCommon{buffer});86 assert(v.begin() == v.end());87 assert(std::as_const(v).begin() == std::as_const(v).end());88 }89 90 {91 // empty range in the middle92 std::ranges::zip_transform_view v(93 MakeTuple{}, SimpleCommon{buffer}, std::ranges::empty_view<int>(), SimpleCommon{buffer});94 assert(v.begin() == v.end());95 assert(std::as_const(v).begin() == std::as_const(v).end());96 }97 98 {99 // empty range at the end100 std::ranges::zip_transform_view v(101 MakeTuple{}, SimpleCommon{buffer}, SimpleCommon{buffer}, std::ranges::empty_view<int>());102 assert(v.begin() == v.end());103 assert(std::as_const(v).begin() == std::as_const(v).end());104 }105 106 {107 // underlying const R is not a range108 using ZTV = std::ranges::zip_transform_view<MakeTuple, SimpleCommon, NoConstBeginView>;109 static_assert(HasBegin<ZTV>);110 static_assert(!HasConstBegin<ZTV>);111 }112 113 {114 // Fn cannot be invoked on const range115 using ZTV = std::ranges::zip_transform_view<NonConstOnlyFn, ConstNonConstDifferentView>;116 static_assert(HasBegin<ZTV>);117 static_assert(!HasConstBegin<ZTV>);118 }119 return true;120}121 122int main(int, char**) {123 test();124 static_assert(test());125 126 return 0;127}128