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

source code of libcxx/test/std/ranges/range.adaptors/range.all/range.owning.view/empty.pass.cpp