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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14, c++17 10 // UNSUPPORTED: libcpp-no-concepts 11 // UNSUPPORTED: libcpp-has-no-incomplete-ranges 12 13 // std::views::counted; 14 15 #include <concepts> 16 #include <ranges> 17 #include <span> 18 19 #include <cassert> 20 #include "test_macros.h" 21 #include "test_iterators.h" 22 23 struct Unrelated {}; 24 25 struct ConvertibleToSize { 26 constexpr operator std::ptrdiff_t() const { return 8; } 27 }; 28 29 struct ImplicitlyConvertible { 30 operator short(); 31 explicit operator std::ptrdiff_t() = delete; 32 }; 33 34 template<class Iter, class T> 35 concept CountedInvocable = requires(Iter& i, T t) { std::views::counted(i, t); }; 36 37 constexpr bool test() { 38 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 39 40 { 41 static_assert( CountedInvocable<contiguous_iterator<int*>, ConvertibleToSize>); 42 static_assert(!CountedInvocable<contiguous_iterator<int*>, ImplicitlyConvertible>); 43 static_assert(!CountedInvocable<contiguous_iterator<int*>, Unrelated>); 44 45 static_assert(std::semiregular<std::remove_const_t<decltype(std::views::counted)>>); 46 } 47 48 { 49 { 50 contiguous_iterator<int*> iter(buffer); 51 std::span<int> s = std::views::counted(iter, 8); 52 assert(s.size() == 8); 53 assert(s.data() == buffer); 54 55 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), std::span<int>); 56 } 57 { 58 const contiguous_iterator<int*> iter(buffer); 59 std::span<int> s = std::views::counted(iter, 8); 60 assert(s.size() == 8); 61 assert(s.data() == buffer); 62 63 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), std::span<int>); 64 } 65 { 66 contiguous_iterator<const int*> iter(buffer); 67 std::span<const int> s = std::views::counted(iter, 8); 68 assert(s.size() == 8); 69 assert(s.data() == buffer); 70 71 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), std::span<const int>); 72 } 73 { 74 const contiguous_iterator<const int*> iter(buffer); 75 std::span<const int> s = std::views::counted(iter, 8); 76 assert(s.size() == 8); 77 assert(s.data() == buffer); 78 79 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), std::span<const int>); 80 } 81 } 82 83 { 84 { 85 random_access_iterator<int*> iter(buffer); 86 std::ranges::subrange<random_access_iterator<int*>> s = std::views::counted(iter, 8); 87 assert(s.size() == 8); 88 assert(s.begin() == iter); 89 90 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), std::ranges::subrange<random_access_iterator<int*>>); 91 } 92 { 93 const random_access_iterator<int*> iter(buffer); 94 std::ranges::subrange<random_access_iterator<int*>> s = std::views::counted(iter, 8); 95 assert(s.size() == 8); 96 assert(s.begin() == iter); 97 98 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), std::ranges::subrange<random_access_iterator<int*>>); 99 } 100 { 101 random_access_iterator<const int*> iter(buffer); 102 std::ranges::subrange<random_access_iterator<const int*>> s = std::views::counted(iter, 8); 103 assert(s.size() == 8); 104 assert(s.begin() == iter); 105 106 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), std::ranges::subrange<random_access_iterator<const int*>>); 107 } 108 { 109 const random_access_iterator<const int*> iter(buffer); 110 std::ranges::subrange<random_access_iterator<const int*>> s = std::views::counted(iter, 8); 111 assert(s.size() == 8); 112 assert(s.begin() == iter); 113 114 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), std::ranges::subrange<random_access_iterator<const int*>>); 115 } 116 } 117 118 { 119 { 120 bidirectional_iterator<int*> iter(buffer); 121 std::ranges::subrange< 122 std::counted_iterator<bidirectional_iterator<int*>>, 123 std::default_sentinel_t> s = std::views::counted(iter, 8); 124 assert(s.size() == 8); 125 assert(s.begin() == std::counted_iterator(iter, 8)); 126 127 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), 128 std::ranges::subrange< 129 std::counted_iterator<bidirectional_iterator<int*>>, 130 std::default_sentinel_t>); 131 } 132 { 133 const bidirectional_iterator<int*> iter(buffer); 134 std::ranges::subrange< 135 std::counted_iterator<bidirectional_iterator<int*>>, 136 std::default_sentinel_t> s = std::views::counted(iter, 8); 137 assert(s.size() == 8); 138 assert(s.begin() == std::counted_iterator(iter, 8)); 139 140 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), 141 std::ranges::subrange< 142 std::counted_iterator<bidirectional_iterator<int*>>, 143 std::default_sentinel_t>); 144 } 145 { 146 output_iterator<const int*> iter(buffer); 147 std::ranges::subrange< 148 std::counted_iterator<output_iterator<const int*>>, 149 std::default_sentinel_t> s = std::views::counted(iter, 8); 150 assert(s.size() == 8); 151 assert(s.begin() == std::counted_iterator(iter, 8)); 152 153 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), 154 std::ranges::subrange< 155 std::counted_iterator<output_iterator<const int*>>, 156 std::default_sentinel_t>); 157 } 158 { 159 const output_iterator<const int*> iter(buffer); 160 std::ranges::subrange< 161 std::counted_iterator<output_iterator<const int*>>, 162 std::default_sentinel_t> s = std::views::counted(iter, 8); 163 assert(s.size() == 8); 164 assert(s.begin() == std::counted_iterator(iter, 8)); 165 166 ASSERT_SAME_TYPE(decltype(std::views::counted(iter, 8)), 167 std::ranges::subrange< 168 std::counted_iterator<output_iterator<const int*>>, 169 std::default_sentinel_t>); 170 } 171 { 172 cpp20_input_iterator<int*> iter(buffer); 173 std::ranges::subrange< 174 std::counted_iterator<cpp20_input_iterator<int*>>, 175 std::default_sentinel_t> s = std::views::counted(std::move(iter), 8); 176 assert(s.size() == 8); 177 assert(s.begin().base().base() == buffer); 178 179 ASSERT_SAME_TYPE(decltype(std::views::counted(std::move(iter), 8)), 180 std::ranges::subrange< 181 std::counted_iterator<cpp20_input_iterator<int*>>, 182 std::default_sentinel_t>); 183 } 184 { 185 std::ranges::subrange< 186 std::counted_iterator<cpp20_input_iterator<int*>>, 187 std::default_sentinel_t> s = std::views::counted(cpp20_input_iterator<int*>(buffer), 8); 188 assert(s.size() == 8); 189 assert(s.begin().base().base() == buffer); 190 191 ASSERT_SAME_TYPE(decltype(std::views::counted(cpp20_input_iterator<int*>(buffer), 8)), 192 std::ranges::subrange< 193 std::counted_iterator<cpp20_input_iterator<int*>>, 194 std::default_sentinel_t>); 195 } 196 } 197 198 { 199 static_assert(std::same_as<decltype(std::views::counted), decltype(std::ranges::views::counted)>); 200 } 201 202 return true; 203 } 204 205 int main(int, char**) { 206 test(); 207 static_assert(test()); 208 209 return 0; 210 } 211