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-has-no-incomplete-ranges
11
12 // constexpr auto size() requires sized_range<R>
13 // constexpr auto size() const requires sized_range<const R>
14
15 #include <ranges>
16
17 #include <array>
18 #include <cassert>
19 #include <concepts>
20
21 #include "test_iterators.h"
22 #include "test_macros.h"
23
24 template <class T>
25 concept HasSize = requires (T t) {
26 t.size();
27 };
28
test()29 constexpr bool test()
30 {
31 {
32 struct SubtractableIters {
33 forward_iterator<int*> begin();
34 sized_sentinel<forward_iterator<int*>> end();
35 };
36 using OwningView = std::ranges::owning_view<SubtractableIters>;
37 static_assert(std::ranges::sized_range<OwningView&>);
38 static_assert(!std::ranges::range<const OwningView&>); // no begin/end
39 static_assert(HasSize<OwningView&>);
40 static_assert(HasSize<OwningView&&>);
41 static_assert(!HasSize<const OwningView&>);
42 static_assert(!HasSize<const OwningView&&>);
43 }
44 {
45 struct NoSize {
46 bidirectional_iterator<int*> begin();
47 bidirectional_iterator<int*> end();
48 };
49 using OwningView = std::ranges::owning_view<NoSize>;
50 static_assert(!HasSize<OwningView&>);
51 static_assert(!HasSize<OwningView&&>);
52 static_assert(!HasSize<const OwningView&>);
53 static_assert(!HasSize<const OwningView&&>);
54 }
55 {
56 struct SizeMember {
57 bidirectional_iterator<int*> begin();
58 bidirectional_iterator<int*> end();
59 int size() const;
60 };
61 using OwningView = std::ranges::owning_view<SizeMember>;
62 static_assert(std::ranges::sized_range<OwningView&>);
63 static_assert(!std::ranges::range<const OwningView&>); // no begin/end
64 static_assert(HasSize<OwningView&>);
65 static_assert(HasSize<OwningView&&>);
66 static_assert(!HasSize<const OwningView&>); // not a range, therefore no size()
67 static_assert(!HasSize<const OwningView&&>);
68 }
69 {
70 // Test an empty view.
71 int a[] = {1};
72 auto ov = std::ranges::owning_view(std::ranges::subrange(a, a));
73 assert(ov.size() == 0);
74 assert(std::as_const(ov).size() == 0);
75 }
76 {
77 // Test a non-empty view.
78 int a[] = {1};
79 auto ov = std::ranges::owning_view(std::ranges::subrange(a, a+1));
80 assert(ov.size() == 1);
81 assert(std::as_const(ov).size() == 1);
82 }
83 {
84 // Test a non-view.
85 std::array<int, 2> a = {1, 2};
86 auto ov = std::ranges::owning_view(std::move(a));
87 assert(ov.size() == 2);
88 assert(std::as_const(ov).size() == 2);
89 }
90 return true;
91 }
92
main(int,char **)93 int main(int, char**) {
94 test();
95 static_assert(test());
96
97 return 0;
98 }
99