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