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, c++20 10 // UNSUPPORTED: libcpp-has-no-incomplete-ranges 11 12 // constexpr auto size() requires(sized_range<Views>&&...) 13 // constexpr auto size() const requires(sized_range<const Views>&&...) 14 15 #include <ranges> 16 17 #include <cassert> 18 #include <tuple> 19 #include <utility> 20 21 #include "test_iterators.h" 22 #include "types.h" 23 24 int buffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 25 struct View : std::ranges::view_base { 26 std::size_t size_ = 0; 27 constexpr View(std::size_t s) : size_(s) {} 28 constexpr auto begin() const { return buffer; } 29 constexpr auto end() const { return buffer + size_; } 30 }; 31 32 struct SizedNonConst : std::ranges::view_base { 33 using iterator = forward_iterator<int*>; 34 std::size_t size_ = 0; 35 constexpr SizedNonConst(std::size_t s) : size_(s) {} 36 constexpr auto begin() const { return iterator{buffer}; } 37 constexpr auto end() const { return iterator{buffer + size_}; } 38 constexpr std::size_t size() { return size_; } 39 }; 40 41 struct StrangeSizeView : std::ranges::view_base { 42 constexpr auto begin() const { return buffer; } 43 constexpr auto end() const { return buffer + 8; } 44 45 constexpr auto size() { return 5; } 46 constexpr auto size() const { return 6; } 47 }; 48 49 constexpr bool test() { 50 { 51 // single range 52 std::ranges::zip_view v(View(8)); 53 assert(v.size() == 8); 54 assert(std::as_const(v).size() == 8); 55 } 56 57 { 58 // multiple ranges same type 59 std::ranges::zip_view v(View(2), View(3)); 60 assert(v.size() == 2); 61 assert(std::as_const(v).size() == 2); 62 } 63 64 { 65 // multiple ranges different types 66 std::ranges::zip_view v(std::views::iota(0, 500), View(3)); 67 assert(v.size() == 3); 68 assert(std::as_const(v).size() == 3); 69 } 70 71 { 72 // const-view non-sized range 73 std::ranges::zip_view v(SizedNonConst(2), View(3)); 74 assert(v.size() == 2); 75 static_assert(std::ranges::sized_range<decltype(v)>); 76 static_assert(!std::ranges::sized_range<decltype(std::as_const(v))>); 77 } 78 79 { 80 // const/non-const has different sizes 81 std::ranges::zip_view v(StrangeSizeView{}); 82 assert(v.size() == 5); 83 assert(std::as_const(v).size() == 6); 84 } 85 86 { 87 // underlying range not sized 88 std::ranges::zip_view v(InputCommonView{buffer}); 89 static_assert(!std::ranges::sized_range<decltype(v)>); 90 static_assert(!std::ranges::sized_range<decltype(std::as_const(v))>); 91 } 92 return true; 93 } 94 95 int main(int, char**) { 96 test(); 97 static_assert(test()); 98 99 return 0; 100 } 101