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