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 // <algorithm> 10 11 // UNSUPPORTED: c++03, c++11, c++14, c++17 12 // UNSUPPORTED: libcpp-has-no-incomplete-ranges 13 14 // template<class T, output_iterator<const T&> O, sentinel_for<O> S> 15 // constexpr O ranges::fill(O first, S last, const T& value); 16 // template<class T, output_range<const T&> R> 17 // constexpr borrowed_iterator_t<R> ranges::fill(R&& r, const T& value); 18 19 #include <algorithm> 20 #include <array> 21 #include <cassert> 22 #include <ranges> 23 #include <string> 24 25 #include "almost_satisfies_types.h" 26 #include "test_iterators.h" 27 28 template <class Iter, class Sent = sentinel_wrapper<Iter>> 29 concept HasFillIt = requires(Iter iter, Sent sent) { std::ranges::fill(iter, sent, int{}); }; 30 31 static_assert(HasFillIt<int*>); 32 static_assert(!HasFillIt<OutputIteratorNotIndirectlyWritable>); 33 static_assert(!HasFillIt<OutputIteratorNotInputOrOutputIterator>); 34 static_assert(!HasFillIt<int*, SentinelForNotSemiregular>); 35 static_assert(!HasFillIt<int*, SentinelForNotWeaklyEqualityComparableWith>); 36 37 template <class Range> 38 concept HasFillR = requires(Range range) { std::ranges::fill(range, int{}); }; 39 40 static_assert(HasFillR<UncheckedRange<int*>>); 41 static_assert(!HasFillR<OutputRangeNotIndirectlyWritable>); 42 static_assert(!HasFillR<OutputRangeNotInputOrOutputIterator>); 43 static_assert(!HasFillR<OutputRangeNotSentinelSemiregular>); 44 static_assert(!HasFillR<OutputRangeNotSentinelEqualityComparableWith>); 45 46 template <class It, class Sent = It> 47 constexpr void test_iterators() { 48 { // simple test 49 { 50 int a[3]; 51 std::same_as<It> auto ret = std::ranges::fill(It(a), Sent(It(a + 3)), 1); 52 assert(std::all_of(a, a + 3, [](int i) { return i == 1; })); 53 assert(base(ret) == a + 3); 54 } 55 { 56 int a[3]; 57 auto range = std::ranges::subrange(It(a), Sent(It(a + 3))); 58 std::same_as<It> auto ret = std::ranges::fill(range, 1); 59 assert(std::all_of(a, a + 3, [](int i) { return i == 1; })); 60 assert(base(ret) == a + 3); 61 } 62 } 63 64 { // check that an empty range works 65 { 66 std::array<int, 0> a; 67 auto ret = std::ranges::fill(It(a.data()), Sent(It(a.data())), 1); 68 assert(base(ret) == a.data()); 69 } 70 { 71 std::array<int, 0> a; 72 auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data()))); 73 auto ret = std::ranges::fill(range, 1); 74 assert(base(ret) == a.data()); 75 } 76 } 77 } 78 79 constexpr bool test() { 80 test_iterators<cpp17_output_iterator<int*>, sentinel_wrapper<cpp17_output_iterator<int*>>>(); 81 test_iterators<cpp20_output_iterator<int*>, sentinel_wrapper<cpp20_output_iterator<int*>>>(); 82 test_iterators<forward_iterator<int*>>(); 83 test_iterators<bidirectional_iterator<int*>>(); 84 test_iterators<random_access_iterator<int*>>(); 85 test_iterators<contiguous_iterator<int*>>(); 86 test_iterators<int*>(); 87 88 { // check that every element is copied once 89 struct S { 90 bool copied = false; 91 constexpr S& operator=(const S&) { 92 copied = true; 93 return *this; 94 } 95 }; 96 { 97 S a[5]; 98 std::ranges::fill(a, a + 5, S {true}); 99 assert(std::all_of(a, a + 5, [](S& s) { return s.copied; })); 100 } 101 { 102 S a[5]; 103 std::ranges::fill(a, S {true}); 104 assert(std::all_of(a, a + 5, [](S& s) { return s.copied; })); 105 } 106 } 107 108 { // check that std::ranges::dangling is returned 109 [[maybe_unused]] std::same_as<std::ranges::dangling> decltype(auto) ret = 110 std::ranges::fill(std::array<int, 10> {}, 1); 111 } 112 113 { // check that std::ranges::dangling isn't returned with a borrowing range 114 std::array<int, 10> a{}; 115 [[maybe_unused]] std::same_as<std::array<int, 10>::iterator> decltype(auto) ret = 116 std::ranges::fill(std::views::all(a), 1); 117 assert(std::all_of(a.begin(), a.end(), [](int i) { return i == 1; })); 118 } 119 120 { // check that non-trivially copyable items are copied properly 121 { 122 std::array<std::string, 10> a; 123 auto ret = std::ranges::fill(a.begin(), a.end(), "long long string so no SSO"); 124 assert(ret == a.data() + a.size()); 125 assert(std::all_of(a.begin(), a.end(), [](auto& s) { return s == "long long string so no SSO"; })); 126 } 127 { 128 std::array<std::string, 10> a; 129 auto ret = std::ranges::fill(a, "long long string so no SSO"); 130 assert(ret == a.data() + a.size()); 131 assert(std::all_of(a.begin(), a.end(), [](auto& s) { return s == "long long string so no SSO"; })); 132 } 133 } 134 135 return true; 136 } 137 138 int main(int, char**) { 139 test(); 140 static_assert(test()); 141 142 return 0; 143 } 144