104 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 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/end49 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/end65 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/end69 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