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> 15 // constexpr O ranges::fill_n(O first, iter_difference_t<O> n, const T& value); 16 17 #include <algorithm> 18 #include <array> 19 #include <cassert> 20 #include <ranges> 21 #include <string> 22 23 #include "almost_satisfies_types.h" 24 #include "test_iterators.h" 25 26 template <class Iter> 27 concept HasFillN = requires(Iter iter) { std::ranges::fill_n(iter, int{}, int{}); }; 28 29 struct WrongType {}; 30 31 static_assert(HasFillN<int*>); 32 static_assert(!HasFillN<WrongType*>); 33 static_assert(!HasFillN<OutputIteratorNotIndirectlyWritable>); 34 static_assert(!HasFillN<OutputIteratorNotInputOrOutputIterator>); 35 36 template <class It, class Sent = It> 37 constexpr void test_iterators() { 38 { // simple test 39 int a[3]; 40 std::same_as<It> decltype(auto) ret = std::ranges::fill_n(It(a), 3, 1); 41 assert(std::all_of(a, a + 3, [](int i) { return i == 1; })); 42 assert(base(ret) == a + 3); 43 } 44 45 { // check that an empty range works 46 std::array<int, 0> a; 47 auto ret = std::ranges::fill_n(It(a.data()), 0, 1); 48 assert(base(ret) == a.data()); 49 } 50 } 51 52 constexpr bool test() { 53 test_iterators<cpp17_output_iterator<int*>, sentinel_wrapper<cpp17_output_iterator<int*>>>(); 54 test_iterators<cpp20_output_iterator<int*>, sentinel_wrapper<cpp20_output_iterator<int*>>>(); 55 test_iterators<forward_iterator<int*>>(); 56 test_iterators<bidirectional_iterator<int*>>(); 57 test_iterators<random_access_iterator<int*>>(); 58 test_iterators<contiguous_iterator<int*>>(); 59 test_iterators<int*>(); 60 61 { // check that every element is copied once 62 struct S { 63 bool copied = false; 64 constexpr S& operator=(const S&) { 65 assert(!copied); 66 copied = true; 67 return *this; 68 } 69 }; 70 71 S a[5]; 72 std::ranges::fill_n(a, 5, S {}); 73 assert(std::all_of(a, a + 5, [](S& s) { return s.copied; })); 74 } 75 76 { // check that non-trivially copyable items are copied properly 77 std::array<std::string, 10> a; 78 auto ret = std::ranges::fill_n(a.data(), 10, "long long string so no SSO"); 79 assert(ret == a.data() + a.size()); 80 assert(std::all_of(a.begin(), a.end(), [](auto& s) { return s == "long long string so no SSO"; })); 81 } 82 83 return true; 84 } 85 86 int main(int, char**) { 87 test(); 88 static_assert(test()); 89 90 return 0; 91 } 92