[libc] Build with -Wdeprecated, fix some warnings (#125373)
[llvm-project.git] / libcxx / test / std / ranges / range.access / empty.pass.cpp
blob990b75bf6452d98c4bd402bea334613581812886
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 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // std::ranges::empty
13 #include <ranges>
15 #include <cassert>
16 #include <utility>
17 #include "test_macros.h"
18 #include "test_iterators.h"
20 using RangeEmptyT = decltype(std::ranges::empty);
22 static_assert(!std::is_invocable_v<RangeEmptyT, int[]>);
23 static_assert(!std::is_invocable_v<RangeEmptyT, int(&)[]>);
24 static_assert(!std::is_invocable_v<RangeEmptyT, int(&&)[]>);
25 static_assert( std::is_invocable_v<RangeEmptyT, int[1]>);
26 static_assert( std::is_invocable_v<RangeEmptyT, const int[1]>);
27 static_assert( std::is_invocable_v<RangeEmptyT, int (&&)[1]>);
28 static_assert( std::is_invocable_v<RangeEmptyT, int (&)[1]>);
29 static_assert( std::is_invocable_v<RangeEmptyT, const int (&)[1]>);
31 struct Incomplete;
32 static_assert(!std::is_invocable_v<RangeEmptyT, Incomplete[]>);
33 static_assert(!std::is_invocable_v<RangeEmptyT, Incomplete(&)[]>);
34 static_assert(!std::is_invocable_v<RangeEmptyT, Incomplete(&&)[]>);
36 extern Incomplete array_of_incomplete[42];
37 static_assert(!std::ranges::empty(array_of_incomplete));
38 static_assert(!std::ranges::empty(std::move(array_of_incomplete)));
39 static_assert(!std::ranges::empty(std::as_const(array_of_incomplete)));
40 static_assert(!std::ranges::empty(static_cast<const Incomplete(&&)[42]>(array_of_incomplete)));
42 struct InputRangeWithoutSize {
43 cpp17_input_iterator<int*> begin() const;
44 cpp17_input_iterator<int*> end() const;
46 static_assert(!std::is_invocable_v<RangeEmptyT, const InputRangeWithoutSize&>);
48 struct NonConstEmpty {
49 bool empty();
51 static_assert(!std::is_invocable_v<RangeEmptyT, const NonConstEmpty&>);
53 struct HasMemberAndFunction {
54 constexpr bool empty() const { return true; }
55 // We should never do ADL lookup for std::ranges::empty.
56 friend bool empty(const HasMemberAndFunction&) { return false; }
59 struct BadReturnType {
60 BadReturnType empty() { return {}; }
62 static_assert(!std::is_invocable_v<RangeEmptyT, BadReturnType&>);
64 struct BoolConvertible {
65 constexpr explicit operator bool() noexcept(false) { return true; }
67 struct BoolConvertibleReturnType {
68 constexpr BoolConvertible empty() noexcept { return {}; }
70 static_assert(!noexcept(std::ranges::empty(BoolConvertibleReturnType())));
72 struct InputIterators {
73 cpp17_input_iterator<int*> begin() const;
74 cpp17_input_iterator<int*> end() const;
76 static_assert(std::is_same_v<decltype(InputIterators().begin() == InputIterators().end()), bool>);
77 static_assert(!std::is_invocable_v<RangeEmptyT, const InputIterators&>);
79 constexpr bool testEmptyMember() {
80 HasMemberAndFunction a;
81 assert(std::ranges::empty(a));
83 BoolConvertibleReturnType b;
84 assert(std::ranges::empty(b));
86 return true;
89 struct SizeMember {
90 std::size_t size_;
91 constexpr std::size_t size() const { return size_; }
94 struct SizeFunction {
95 std::size_t size_;
96 friend constexpr std::size_t size(SizeFunction sf) { return sf.size_; }
99 struct BeginEndSizedSentinel {
100 constexpr int *begin() const { return nullptr; }
101 constexpr auto end() const { return sized_sentinel<int*>(nullptr); }
103 static_assert(std::ranges::forward_range<BeginEndSizedSentinel>);
104 static_assert(std::ranges::sized_range<BeginEndSizedSentinel>);
106 constexpr bool testUsingRangesSize() {
107 SizeMember a{1};
108 assert(!std::ranges::empty(a));
109 SizeMember b{0};
110 assert(std::ranges::empty(b));
112 SizeFunction c{1};
113 assert(!std::ranges::empty(c));
114 SizeFunction d{0};
115 assert(std::ranges::empty(d));
117 BeginEndSizedSentinel e;
118 assert(std::ranges::empty(e));
120 return true;
123 struct BeginEndNotSizedSentinel {
124 constexpr int *begin() const { return nullptr; }
125 constexpr auto end() const { return sentinel_wrapper<int*>(nullptr); }
127 static_assert( std::ranges::forward_range<BeginEndNotSizedSentinel>);
128 static_assert(!std::ranges::sized_range<BeginEndNotSizedSentinel>);
130 // size is disabled here, so we have to compare begin and end.
131 struct DisabledSizeRangeWithBeginEnd {
132 constexpr int *begin() const { return nullptr; }
133 constexpr auto end() const { return sentinel_wrapper<int*>(nullptr); }
134 std::size_t size() const;
136 template<>
137 inline constexpr bool std::ranges::disable_sized_range<DisabledSizeRangeWithBeginEnd> = true;
138 static_assert(std::ranges::contiguous_range<DisabledSizeRangeWithBeginEnd>);
139 static_assert(!std::ranges::sized_range<DisabledSizeRangeWithBeginEnd>);
141 struct BeginEndAndEmpty {
142 constexpr int *begin() const { return nullptr; }
143 constexpr auto end() const { return sentinel_wrapper<int*>(nullptr); }
144 constexpr bool empty() { return false; }
147 struct EvilBeginEnd {
148 bool empty() &&;
149 constexpr int *begin() & { return nullptr; }
150 constexpr int *end() & { return nullptr; }
153 constexpr bool testBeginEqualsEnd() {
154 BeginEndNotSizedSentinel a;
155 assert(std::ranges::empty(a));
157 DisabledSizeRangeWithBeginEnd d;
158 assert(std::ranges::empty(d));
160 BeginEndAndEmpty e;
161 assert(!std::ranges::empty(e)); // e.empty()
162 assert(std::ranges::empty(std::as_const(e))); // e.begin() == e.end()
164 assert(std::ranges::empty(EvilBeginEnd()));
166 return true;
169 // Test ADL-proofing.
170 struct Incomplete;
171 template<class T> struct Holder { T t; };
172 static_assert(!std::is_invocable_v<RangeEmptyT, Holder<Incomplete>*>);
173 static_assert(!std::is_invocable_v<RangeEmptyT, Holder<Incomplete>*&>);
175 int main(int, char**) {
176 testEmptyMember();
177 static_assert(testEmptyMember());
179 testUsingRangesSize();
180 static_assert(testUsingRangesSize());
182 testBeginEqualsEnd();
183 static_assert(testBeginEqualsEnd());
185 return 0;