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 // constexpr auto size() requires sized_range<V>; 14 // constexpr auto size() const requires sized_range<const V>; 15 16 #include <ranges> 17 #include <cassert> 18 19 #include "test_macros.h" 20 #include "types.h" 21 22 // end - begin = 8, but size may return something else. 23 template<CopyCategory CC> 24 struct BidirSizedRange : std::ranges::view_base { 25 int *ptr_; 26 size_t size_; 27 28 constexpr BidirSizedRange(int *ptr, size_t size) : ptr_(ptr), size_(size) {} 29 constexpr BidirSizedRange(const BidirSizedRange &) requires (CC == Copyable) = default; 30 constexpr BidirSizedRange(BidirSizedRange &&) requires (CC == MoveOnly) = default; 31 constexpr BidirSizedRange& operator=(const BidirSizedRange &) requires (CC == Copyable) = default; 32 constexpr BidirSizedRange& operator=(BidirSizedRange &&) requires (CC == MoveOnly) = default; 33 34 constexpr bidirectional_iterator<int*> begin() { return bidirectional_iterator<int*>{ptr_}; } 35 constexpr bidirectional_iterator<const int*> begin() const { return bidirectional_iterator<const int*>{ptr_}; } 36 constexpr bidirectional_iterator<int*> end() { return bidirectional_iterator<int*>{ptr_ + 8}; } 37 constexpr bidirectional_iterator<const int*> end() const { return bidirectional_iterator<const int*>{ptr_ + 8}; } 38 39 constexpr size_t size() const { return size_; } 40 }; 41 42 constexpr bool test() { 43 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 44 45 // Non-common, non-const bidirectional range. 46 { 47 auto rev = std::ranges::reverse_view(BidirSizedRange<Copyable>{buffer, 4}); 48 assert(std::ranges::size(rev) == 4); 49 assert(rev.size() == 4); 50 assert(std::move(rev).size() == 4); 51 52 ASSERT_SAME_TYPE(decltype(rev.size()), size_t); 53 ASSERT_SAME_TYPE(decltype(std::move(rev).size()), size_t); 54 } 55 // Non-common, const bidirectional range. 56 { 57 const auto rev = std::ranges::reverse_view(BidirSizedRange<Copyable>{buffer, 4}); 58 assert(std::ranges::size(rev) == 4); 59 assert(rev.size() == 4); 60 assert(std::move(rev).size() == 4); 61 62 ASSERT_SAME_TYPE(decltype(rev.size()), size_t); 63 ASSERT_SAME_TYPE(decltype(std::move(rev).size()), size_t); 64 } 65 // Non-common, non-const (move only) bidirectional range. 66 { 67 auto rev = std::ranges::reverse_view(BidirSizedRange<MoveOnly>{buffer, 4}); 68 assert(std::move(rev).size() == 4); 69 70 ASSERT_SAME_TYPE(decltype(std::move(rev).size()), size_t); 71 } 72 73 return true; 74 } 75 76 int main(int, char**) { 77 test(); 78 static_assert(test()); 79 80 return 0; 81 } 82