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 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 99 int main(int, char**) { 100 test(); 101 static_assert(test()); 102 103 return 0; 104 } 105