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