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 bool empty() requires requires { ranges::empty(r_); }
13 // constexpr bool empty() const requires requires { ranges::empty(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 HasEmpty = requires (T t) {
26 t.empty();
27 };
28
test()29 constexpr bool test()
30 {
31 {
32 struct ComparableIters {
33 forward_iterator<int*> begin();
34 forward_iterator<int*> end();
35 };
36 using OwningView = std::ranges::owning_view<ComparableIters>;
37 static_assert(HasEmpty<OwningView&>);
38 static_assert(HasEmpty<OwningView&&>);
39 static_assert(!HasEmpty<const OwningView&>);
40 static_assert(!HasEmpty<const OwningView&&>);
41 }
42 {
43 struct NoEmpty {
44 cpp20_input_iterator<int*> begin();
45 sentinel_wrapper<cpp20_input_iterator<int*>> end();
46 };
47 static_assert(std::ranges::range<NoEmpty&>);
48 static_assert(!std::invocable<decltype(std::ranges::empty), NoEmpty&>);
49 static_assert(!std::ranges::range<const NoEmpty&>); // no begin/end
50 static_assert(!std::invocable<decltype(std::ranges::empty), const NoEmpty&>);
51 using OwningView = std::ranges::owning_view<NoEmpty>;
52 static_assert(!HasEmpty<OwningView&>);
53 static_assert(!HasEmpty<OwningView&&>);
54 static_assert(!HasEmpty<const OwningView&>);
55 static_assert(!HasEmpty<const OwningView&&>);
56 }
57 {
58 struct EmptyMember {
59 cpp20_input_iterator<int*> begin();
60 sentinel_wrapper<cpp20_input_iterator<int*>> end();
61 bool empty() const;
62 };
63 static_assert(std::ranges::range<EmptyMember&>);
64 static_assert(std::invocable<decltype(std::ranges::empty), EmptyMember&>);
65 static_assert(!std::ranges::range<const EmptyMember&>); // no begin/end
66 static_assert(std::invocable<decltype(std::ranges::empty), const EmptyMember&>);
67 using OwningView = std::ranges::owning_view<EmptyMember>;
68 static_assert(std::ranges::range<OwningView&>);
69 static_assert(!std::ranges::range<const OwningView&>); // no begin/end
70 static_assert(HasEmpty<OwningView&>);
71 static_assert(HasEmpty<OwningView&&>);
72 static_assert(HasEmpty<const OwningView&>); // but it still has empty()
73 static_assert(HasEmpty<const OwningView&&>);
74 }
75 {
76 // Test an empty view.
77 int a[] = {1};
78 auto ov = std::ranges::owning_view(std::ranges::subrange(a, a));
79 assert(ov.empty());
80 assert(std::as_const(ov).empty());
81 }
82 {
83 // Test a non-empty view.
84 int a[] = {1};
85 auto ov = std::ranges::owning_view(std::ranges::subrange(a, a+1));
86 assert(!ov.empty());
87 assert(!std::as_const(ov).empty());
88 }
89 {
90 // Test a non-view.
91 std::array<int, 2> a = {1, 2};
92 auto ov = std::ranges::owning_view(std::move(a));
93 assert(!ov.empty());
94 assert(!std::as_const(ov).empty());
95 }
96 return true;
97 }
98
main(int,char **)99 int main(int, char**) {
100 test();
101 static_assert(test());
102
103 return 0;
104 }
105