1f9e58f35Szoecarver //===----------------------------------------------------------------------===// 2f9e58f35Szoecarver // 3f9e58f35Szoecarver // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f9e58f35Szoecarver // See https://llvm.org/LICENSE.txt for license information. 5f9e58f35Szoecarver // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f9e58f35Szoecarver // 7f9e58f35Szoecarver //===----------------------------------------------------------------------===// 8f9e58f35Szoecarver 9f9e58f35Szoecarver // UNSUPPORTED: c++03, c++11, c++14, c++17 10f9e58f35Szoecarver 11f9e58f35Szoecarver // std::views::counted; 12f9e58f35Szoecarver 13f9e58f35Szoecarver #include <ranges> 14f9e58f35Szoecarver #include <cassert> 15bd0c0e5bSArthur O'Dwyer #include <concepts> 16bd0c0e5bSArthur O'Dwyer #include <cstddef> 17bd0c0e5bSArthur O'Dwyer #include <memory> 18bd0c0e5bSArthur O'Dwyer #include <span> 19bd0c0e5bSArthur O'Dwyer #include <utility> 20bd0c0e5bSArthur O'Dwyer 21f9e58f35Szoecarver #include "test_macros.h" 22f9e58f35Szoecarver #include "test_iterators.h" 23f9e58f35Szoecarver 24bd0c0e5bSArthur O'Dwyer struct RvalueConvertible { 25bd0c0e5bSArthur O'Dwyer RvalueConvertible(const RvalueConvertible&) = delete; 26bd0c0e5bSArthur O'Dwyer operator int() &&; 27f9e58f35Szoecarver }; 28f9e58f35Szoecarver 29bd0c0e5bSArthur O'Dwyer struct LvalueConvertible { 30bd0c0e5bSArthur O'Dwyer LvalueConvertible(const LvalueConvertible&) = delete; 31bd0c0e5bSArthur O'Dwyer operator int() &; 32f9e58f35Szoecarver }; 33f9e58f35Szoecarver 34bd0c0e5bSArthur O'Dwyer struct OnlyExplicitlyConvertible { 35bd0c0e5bSArthur O'Dwyer explicit operator int() const; 36bd0c0e5bSArthur O'Dwyer }; 37bd0c0e5bSArthur O'Dwyer 38bd0c0e5bSArthur O'Dwyer template<class... Ts> 39bd0c0e5bSArthur O'Dwyer concept CountedInvocable = requires (Ts&&... ts) { 40bd0c0e5bSArthur O'Dwyer std::views::counted(std::forward<Ts>(ts)...); 41bd0c0e5bSArthur O'Dwyer }; 42f9e58f35Szoecarver 43f9e58f35Szoecarver constexpr bool test() { 44f9e58f35Szoecarver int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 45f9e58f35Szoecarver 46f9e58f35Szoecarver { 47bd0c0e5bSArthur O'Dwyer static_assert(std::addressof(std::views::counted) == std::addressof(std::ranges::views::counted)); 48f9e58f35Szoecarver 49fb855eb9SMark de Wever static_assert( CountedInvocable<int*, std::size_t>); 50bd0c0e5bSArthur O'Dwyer static_assert(!CountedInvocable<int*, LvalueConvertible>); 51bd0c0e5bSArthur O'Dwyer static_assert( CountedInvocable<int*, LvalueConvertible&>); 52bd0c0e5bSArthur O'Dwyer static_assert( CountedInvocable<int*, RvalueConvertible>); 53bd0c0e5bSArthur O'Dwyer static_assert(!CountedInvocable<int*, RvalueConvertible&>); 54bd0c0e5bSArthur O'Dwyer static_assert(!CountedInvocable<int*, OnlyExplicitlyConvertible>); 55bd0c0e5bSArthur O'Dwyer static_assert(!CountedInvocable<int*, int*>); 56bd0c0e5bSArthur O'Dwyer static_assert(!CountedInvocable<int*>); 57fb855eb9SMark de Wever static_assert(!CountedInvocable<std::size_t>); 58bd0c0e5bSArthur O'Dwyer static_assert(!CountedInvocable<>); 59f9e58f35Szoecarver } 60f9e58f35Szoecarver 61f9e58f35Szoecarver { 62bd0c0e5bSArthur O'Dwyer auto c1 = std::views::counted(buffer, 3); 63bd0c0e5bSArthur O'Dwyer auto c2 = std::views::counted(std::as_const(buffer), 3); 64f9e58f35Szoecarver 65bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c1), std::span<int>); 66bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c2), std::span<const int>); 67f9e58f35Szoecarver 68bd0c0e5bSArthur O'Dwyer assert(c1.data() == buffer && c1.size() == 3); 69bd0c0e5bSArthur O'Dwyer assert(c2.data() == buffer && c2.size() == 3); 70f9e58f35Szoecarver } 71f9e58f35Szoecarver 72f9e58f35Szoecarver { 73bd0c0e5bSArthur O'Dwyer auto it = contiguous_iterator<int*>(buffer); 74bd0c0e5bSArthur O'Dwyer auto cit = contiguous_iterator<const int*>(buffer); 75f9e58f35Szoecarver 76bd0c0e5bSArthur O'Dwyer auto c1 = std::views::counted(it, 3); 77bd0c0e5bSArthur O'Dwyer auto c2 = std::views::counted(std::as_const(it), 3); 78bd0c0e5bSArthur O'Dwyer auto c3 = std::views::counted(std::move(it), 3); 79bd0c0e5bSArthur O'Dwyer auto c4 = std::views::counted(contiguous_iterator<int*>(buffer), 3); 80bd0c0e5bSArthur O'Dwyer auto c5 = std::views::counted(cit, 3); 81bd0c0e5bSArthur O'Dwyer auto c6 = std::views::counted(std::as_const(cit), 3); 82bd0c0e5bSArthur O'Dwyer auto c7 = std::views::counted(std::move(cit), 3); 83bd0c0e5bSArthur O'Dwyer auto c8 = std::views::counted(contiguous_iterator<const int*>(buffer), 3); 84f9e58f35Szoecarver 85bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c1), std::span<int>); 86bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c2), std::span<int>); 87bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c3), std::span<int>); 88bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c4), std::span<int>); 89bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c5), std::span<const int>); 90bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c6), std::span<const int>); 91bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c7), std::span<const int>); 92bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c8), std::span<const int>); 93f9e58f35Szoecarver 94bd0c0e5bSArthur O'Dwyer assert(c1.data() == buffer && c1.size() == 3); 95bd0c0e5bSArthur O'Dwyer assert(c2.data() == buffer && c2.size() == 3); 96bd0c0e5bSArthur O'Dwyer assert(c3.data() == buffer && c3.size() == 3); 97bd0c0e5bSArthur O'Dwyer assert(c4.data() == buffer && c4.size() == 3); 98bd0c0e5bSArthur O'Dwyer assert(c5.data() == buffer && c5.size() == 3); 99bd0c0e5bSArthur O'Dwyer assert(c6.data() == buffer && c6.size() == 3); 100bd0c0e5bSArthur O'Dwyer assert(c7.data() == buffer && c7.size() == 3); 101bd0c0e5bSArthur O'Dwyer assert(c8.data() == buffer && c8.size() == 3); 102f9e58f35Szoecarver } 103f9e58f35Szoecarver 104f9e58f35Szoecarver { 105bd0c0e5bSArthur O'Dwyer auto it = random_access_iterator<int*>(buffer); 106bd0c0e5bSArthur O'Dwyer auto cit = random_access_iterator<const int*>(buffer); 107*f73050e7SLouis Dionne auto it_copy = it; 108*f73050e7SLouis Dionne auto cit_copy = cit; 109f9e58f35Szoecarver 110bd0c0e5bSArthur O'Dwyer auto c1 = std::views::counted(it, 3); 111bd0c0e5bSArthur O'Dwyer auto c2 = std::views::counted(std::as_const(it), 3); 112*f73050e7SLouis Dionne auto c3 = std::views::counted(std::move(it_copy), 3); 113bd0c0e5bSArthur O'Dwyer auto c4 = std::views::counted(random_access_iterator<int*>(buffer), 3); 114bd0c0e5bSArthur O'Dwyer auto c5 = std::views::counted(cit, 3); 115bd0c0e5bSArthur O'Dwyer auto c6 = std::views::counted(std::as_const(cit), 3); 116*f73050e7SLouis Dionne auto c7 = std::views::counted(std::move(cit_copy), 3); 117bd0c0e5bSArthur O'Dwyer auto c8 = std::views::counted(random_access_iterator<const int*>(buffer), 3); 118f9e58f35Szoecarver 119bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c1), std::ranges::subrange<random_access_iterator<int*>>); 120bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c2), std::ranges::subrange<random_access_iterator<int*>>); 121bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c3), std::ranges::subrange<random_access_iterator<int*>>); 122bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c4), std::ranges::subrange<random_access_iterator<int*>>); 123bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c5), std::ranges::subrange<random_access_iterator<const int*>>); 124bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c6), std::ranges::subrange<random_access_iterator<const int*>>); 125bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c7), std::ranges::subrange<random_access_iterator<const int*>>); 126bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c8), std::ranges::subrange<random_access_iterator<const int*>>); 127f9e58f35Szoecarver 128bd0c0e5bSArthur O'Dwyer assert(c1.begin() == it && c1.end() == it + 3); 129bd0c0e5bSArthur O'Dwyer assert(c2.begin() == it && c2.end() == it + 3); 130bd0c0e5bSArthur O'Dwyer assert(c3.begin() == it && c3.end() == it + 3); 131bd0c0e5bSArthur O'Dwyer assert(c4.begin() == it && c4.end() == it + 3); 132bd0c0e5bSArthur O'Dwyer assert(c5.begin() == cit && c5.end() == cit + 3); 133bd0c0e5bSArthur O'Dwyer assert(c6.begin() == cit && c6.end() == cit + 3); 134bd0c0e5bSArthur O'Dwyer assert(c7.begin() == cit && c7.end() == cit + 3); 135bd0c0e5bSArthur O'Dwyer assert(c8.begin() == cit && c8.end() == cit + 3); 136f9e58f35Szoecarver } 137f9e58f35Szoecarver 1389ed07781Szoecarver { 139bd0c0e5bSArthur O'Dwyer auto it = bidirectional_iterator<int*>(buffer); 140bd0c0e5bSArthur O'Dwyer auto cit = bidirectional_iterator<const int*>(buffer); 141*f73050e7SLouis Dionne auto it_copy = it; 142*f73050e7SLouis Dionne auto cit_copy = cit; 143bd0c0e5bSArthur O'Dwyer 144bd0c0e5bSArthur O'Dwyer auto c1 = std::views::counted(it, 3); 145bd0c0e5bSArthur O'Dwyer auto c2 = std::views::counted(std::as_const(it), 3); 146*f73050e7SLouis Dionne auto c3 = std::views::counted(std::move(it_copy), 3); 147bd0c0e5bSArthur O'Dwyer auto c4 = std::views::counted(bidirectional_iterator<int*>(buffer), 3); 148bd0c0e5bSArthur O'Dwyer auto c5 = std::views::counted(cit, 3); 149bd0c0e5bSArthur O'Dwyer auto c6 = std::views::counted(std::as_const(cit), 3); 150*f73050e7SLouis Dionne auto c7 = std::views::counted(std::move(cit_copy), 3); 151bd0c0e5bSArthur O'Dwyer auto c8 = std::views::counted(bidirectional_iterator<const int*>(buffer), 3); 152bd0c0e5bSArthur O'Dwyer 153bd0c0e5bSArthur O'Dwyer using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 154bd0c0e5bSArthur O'Dwyer using ConstExpected = std::ranges::subrange<std::counted_iterator<decltype(cit)>, std::default_sentinel_t>; 155bd0c0e5bSArthur O'Dwyer 156bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c1), Expected); 157bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c2), Expected); 158bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c3), Expected); 159bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c4), Expected); 160bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c5), ConstExpected); 161bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c6), ConstExpected); 162bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c7), ConstExpected); 163bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c8), ConstExpected); 164bd0c0e5bSArthur O'Dwyer 165bd0c0e5bSArthur O'Dwyer assert(c1.begin().base() == it && c1.size() == 3); 166bd0c0e5bSArthur O'Dwyer assert(c2.begin().base() == it && c2.size() == 3); 167bd0c0e5bSArthur O'Dwyer assert(c3.begin().base() == it && c3.size() == 3); 168bd0c0e5bSArthur O'Dwyer assert(c4.begin().base() == it && c4.size() == 3); 169bd0c0e5bSArthur O'Dwyer assert(c5.begin().base() == cit && c5.size() == 3); 170bd0c0e5bSArthur O'Dwyer assert(c6.begin().base() == cit && c6.size() == 3); 171bd0c0e5bSArthur O'Dwyer assert(c7.begin().base() == cit && c7.size() == 3); 172bd0c0e5bSArthur O'Dwyer assert(c8.begin().base() == cit && c8.size() == 3); 173bd0c0e5bSArthur O'Dwyer } 174bd0c0e5bSArthur O'Dwyer 175bd0c0e5bSArthur O'Dwyer { 1765e97d37bSMark de Wever auto it = cpp17_output_iterator<int*>(buffer); 177*f73050e7SLouis Dionne auto it_copy = it; 178bd0c0e5bSArthur O'Dwyer 179bd0c0e5bSArthur O'Dwyer auto c1 = std::views::counted(it, 3); 180bd0c0e5bSArthur O'Dwyer auto c2 = std::views::counted(std::as_const(it), 3); 181*f73050e7SLouis Dionne auto c3 = std::views::counted(std::move(it_copy), 3); 1825e97d37bSMark de Wever auto c4 = std::views::counted(cpp17_output_iterator<int*>(buffer), 3); 183bd0c0e5bSArthur O'Dwyer 184bd0c0e5bSArthur O'Dwyer using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 185bd0c0e5bSArthur O'Dwyer 186bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c1), Expected); 187bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c2), Expected); 188bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c3), Expected); 189bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c4), Expected); 190bd0c0e5bSArthur O'Dwyer 191bd0c0e5bSArthur O'Dwyer assert(base(c1.begin().base()) == buffer && c1.size() == 3); 192bd0c0e5bSArthur O'Dwyer assert(base(c2.begin().base()) == buffer && c2.size() == 3); 193bd0c0e5bSArthur O'Dwyer assert(base(c3.begin().base()) == buffer && c3.size() == 3); 194bd0c0e5bSArthur O'Dwyer assert(base(c4.begin().base()) == buffer && c4.size() == 3); 195bd0c0e5bSArthur O'Dwyer } 196bd0c0e5bSArthur O'Dwyer 197bd0c0e5bSArthur O'Dwyer { 198bd0c0e5bSArthur O'Dwyer auto it = cpp17_input_iterator<int*>(buffer); 199*f73050e7SLouis Dionne auto it_copy = it; 200bd0c0e5bSArthur O'Dwyer 201bd0c0e5bSArthur O'Dwyer auto c1 = std::views::counted(it, 3); 202bd0c0e5bSArthur O'Dwyer auto c2 = std::views::counted(std::as_const(it), 3); 203*f73050e7SLouis Dionne auto c3 = std::views::counted(std::move(it_copy), 3); 204bd0c0e5bSArthur O'Dwyer auto c4 = std::views::counted(cpp17_input_iterator<int*>(buffer), 3); 205bd0c0e5bSArthur O'Dwyer 206bd0c0e5bSArthur O'Dwyer using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 207bd0c0e5bSArthur O'Dwyer 208bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c1), Expected); 209bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c2), Expected); 210bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c3), Expected); 211bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c4), Expected); 212bd0c0e5bSArthur O'Dwyer 213bd0c0e5bSArthur O'Dwyer assert(base(c1.begin().base()) == buffer && c1.size() == 3); 214bd0c0e5bSArthur O'Dwyer assert(base(c2.begin().base()) == buffer && c2.size() == 3); 215bd0c0e5bSArthur O'Dwyer assert(base(c3.begin().base()) == buffer && c3.size() == 3); 216bd0c0e5bSArthur O'Dwyer assert(base(c4.begin().base()) == buffer && c4.size() == 3); 217bd0c0e5bSArthur O'Dwyer } 218bd0c0e5bSArthur O'Dwyer 219bd0c0e5bSArthur O'Dwyer { 220bd0c0e5bSArthur O'Dwyer auto it = cpp20_input_iterator<int*>(buffer); 221bd0c0e5bSArthur O'Dwyer 222bd0c0e5bSArthur O'Dwyer static_assert(!std::copyable<cpp20_input_iterator<int*>>); 223bd0c0e5bSArthur O'Dwyer static_assert(!CountedInvocable<cpp20_input_iterator<int*>&, int>); 224bd0c0e5bSArthur O'Dwyer static_assert(!CountedInvocable<const cpp20_input_iterator<int*>&, int>); 225bd0c0e5bSArthur O'Dwyer auto c3 = std::views::counted(std::move(it), 3); 226bd0c0e5bSArthur O'Dwyer auto c4 = std::views::counted(cpp20_input_iterator<int*>(buffer), 3); 227bd0c0e5bSArthur O'Dwyer 228bd0c0e5bSArthur O'Dwyer using Expected = std::ranges::subrange<std::counted_iterator<decltype(it)>, std::default_sentinel_t>; 229bd0c0e5bSArthur O'Dwyer 230bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c3), Expected); 231bd0c0e5bSArthur O'Dwyer ASSERT_SAME_TYPE(decltype(c4), Expected); 232bd0c0e5bSArthur O'Dwyer 233bd0c0e5bSArthur O'Dwyer assert(base(c3.begin().base()) == buffer && c3.size() == 3); 234bd0c0e5bSArthur O'Dwyer assert(base(c4.begin().base()) == buffer && c4.size() == 3); 2359ed07781Szoecarver } 2369ed07781Szoecarver 237f9e58f35Szoecarver return true; 238f9e58f35Szoecarver } 239f9e58f35Szoecarver 240f9e58f35Szoecarver int main(int, char**) { 241f9e58f35Szoecarver test(); 242f9e58f35Szoecarver static_assert(test()); 243f9e58f35Szoecarver 244f9e58f35Szoecarver return 0; 245f9e58f35Szoecarver } 246