17af89a37SNikolas Klauser //===----------------------------------------------------------------------===//
27af89a37SNikolas Klauser //
37af89a37SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47af89a37SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
57af89a37SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67af89a37SNikolas Klauser //
77af89a37SNikolas Klauser //===----------------------------------------------------------------------===//
87af89a37SNikolas Klauser
97af89a37SNikolas Klauser // <algorithm>
107af89a37SNikolas Klauser
117af89a37SNikolas Klauser // UNSUPPORTED: c++03, c++11, c++14, c++17
127af89a37SNikolas Klauser
137af89a37SNikolas Klauser // template<class T, output_iterator<const T&> O, sentinel_for<O> S>
147af89a37SNikolas Klauser // constexpr O ranges::fill(O first, S last, const T& value);
157af89a37SNikolas Klauser // template<class T, output_range<const T&> R>
167af89a37SNikolas Klauser // constexpr borrowed_iterator_t<R> ranges::fill(R&& r, const T& value);
177af89a37SNikolas Klauser
187af89a37SNikolas Klauser #include <algorithm>
197af89a37SNikolas Klauser #include <array>
207af89a37SNikolas Klauser #include <cassert>
217af89a37SNikolas Klauser #include <ranges>
227af89a37SNikolas Klauser #include <string>
237af89a37SNikolas Klauser
247af89a37SNikolas Klauser #include "almost_satisfies_types.h"
257af89a37SNikolas Klauser #include "test_iterators.h"
267af89a37SNikolas Klauser
277af89a37SNikolas Klauser template <class Iter, class Sent = sentinel_wrapper<Iter>>
287af89a37SNikolas Klauser concept HasFillIt = requires(Iter iter, Sent sent) { std::ranges::fill(iter, sent, int{}); };
297af89a37SNikolas Klauser
307af89a37SNikolas Klauser static_assert(HasFillIt<int*>);
317af89a37SNikolas Klauser static_assert(!HasFillIt<OutputIteratorNotIndirectlyWritable>);
327af89a37SNikolas Klauser static_assert(!HasFillIt<OutputIteratorNotInputOrOutputIterator>);
337af89a37SNikolas Klauser static_assert(!HasFillIt<int*, SentinelForNotSemiregular>);
347af89a37SNikolas Klauser static_assert(!HasFillIt<int*, SentinelForNotWeaklyEqualityComparableWith>);
357af89a37SNikolas Klauser
367af89a37SNikolas Klauser template <class Range>
377af89a37SNikolas Klauser concept HasFillR = requires(Range range) { std::ranges::fill(range, int{}); };
387af89a37SNikolas Klauser
397af89a37SNikolas Klauser static_assert(HasFillR<UncheckedRange<int*>>);
407af89a37SNikolas Klauser static_assert(!HasFillR<OutputRangeNotIndirectlyWritable>);
417af89a37SNikolas Klauser static_assert(!HasFillR<OutputRangeNotInputOrOutputIterator>);
427af89a37SNikolas Klauser static_assert(!HasFillR<OutputRangeNotSentinelSemiregular>);
437af89a37SNikolas Klauser static_assert(!HasFillR<OutputRangeNotSentinelEqualityComparableWith>);
447af89a37SNikolas Klauser
457af89a37SNikolas Klauser template <class It, class Sent = It>
test_iterators()467af89a37SNikolas Klauser constexpr void test_iterators() {
477af89a37SNikolas Klauser { // simple test
487af89a37SNikolas Klauser {
497af89a37SNikolas Klauser int a[3];
507af89a37SNikolas Klauser std::same_as<It> auto ret = std::ranges::fill(It(a), Sent(It(a + 3)), 1);
517af89a37SNikolas Klauser assert(std::all_of(a, a + 3, [](int i) { return i == 1; }));
527af89a37SNikolas Klauser assert(base(ret) == a + 3);
537af89a37SNikolas Klauser }
547af89a37SNikolas Klauser {
557af89a37SNikolas Klauser int a[3];
567af89a37SNikolas Klauser auto range = std::ranges::subrange(It(a), Sent(It(a + 3)));
577af89a37SNikolas Klauser std::same_as<It> auto ret = std::ranges::fill(range, 1);
587af89a37SNikolas Klauser assert(std::all_of(a, a + 3, [](int i) { return i == 1; }));
597af89a37SNikolas Klauser assert(base(ret) == a + 3);
607af89a37SNikolas Klauser }
617af89a37SNikolas Klauser }
627af89a37SNikolas Klauser
637af89a37SNikolas Klauser { // check that an empty range works
647af89a37SNikolas Klauser {
657af89a37SNikolas Klauser std::array<int, 0> a;
667af89a37SNikolas Klauser auto ret = std::ranges::fill(It(a.data()), Sent(It(a.data())), 1);
677af89a37SNikolas Klauser assert(base(ret) == a.data());
687af89a37SNikolas Klauser }
697af89a37SNikolas Klauser {
707af89a37SNikolas Klauser std::array<int, 0> a;
717af89a37SNikolas Klauser auto range = std::ranges::subrange(It(a.data()), Sent(It(a.data())));
727af89a37SNikolas Klauser auto ret = std::ranges::fill(range, 1);
737af89a37SNikolas Klauser assert(base(ret) == a.data());
747af89a37SNikolas Klauser }
757af89a37SNikolas Klauser }
767af89a37SNikolas Klauser }
777af89a37SNikolas Klauser
test()787af89a37SNikolas Klauser constexpr bool test() {
797af89a37SNikolas Klauser test_iterators<cpp17_output_iterator<int*>, sentinel_wrapper<cpp17_output_iterator<int*>>>();
807af89a37SNikolas Klauser test_iterators<cpp20_output_iterator<int*>, sentinel_wrapper<cpp20_output_iterator<int*>>>();
817af89a37SNikolas Klauser test_iterators<forward_iterator<int*>>();
827af89a37SNikolas Klauser test_iterators<bidirectional_iterator<int*>>();
837af89a37SNikolas Klauser test_iterators<random_access_iterator<int*>>();
847af89a37SNikolas Klauser test_iterators<contiguous_iterator<int*>>();
857af89a37SNikolas Klauser test_iterators<int*>();
867af89a37SNikolas Klauser
877af89a37SNikolas Klauser { // check that every element is copied once
887af89a37SNikolas Klauser struct S {
897af89a37SNikolas Klauser bool copied = false;
907af89a37SNikolas Klauser constexpr S& operator=(const S&) {
917af89a37SNikolas Klauser copied = true;
927af89a37SNikolas Klauser return *this;
937af89a37SNikolas Klauser }
947af89a37SNikolas Klauser };
957af89a37SNikolas Klauser {
967af89a37SNikolas Klauser S a[5];
977af89a37SNikolas Klauser std::ranges::fill(a, a + 5, S {true});
987af89a37SNikolas Klauser assert(std::all_of(a, a + 5, [](S& s) { return s.copied; }));
997af89a37SNikolas Klauser }
1007af89a37SNikolas Klauser {
1017af89a37SNikolas Klauser S a[5];
1027af89a37SNikolas Klauser std::ranges::fill(a, S {true});
1037af89a37SNikolas Klauser assert(std::all_of(a, a + 5, [](S& s) { return s.copied; }));
1047af89a37SNikolas Klauser }
1057af89a37SNikolas Klauser }
1067af89a37SNikolas Klauser
1077af89a37SNikolas Klauser { // check that std::ranges::dangling is returned
1087af89a37SNikolas Klauser [[maybe_unused]] std::same_as<std::ranges::dangling> decltype(auto) ret =
1097af89a37SNikolas Klauser std::ranges::fill(std::array<int, 10> {}, 1);
1107af89a37SNikolas Klauser }
1117af89a37SNikolas Klauser
1127af89a37SNikolas Klauser { // check that std::ranges::dangling isn't returned with a borrowing range
1137af89a37SNikolas Klauser std::array<int, 10> a{};
1147af89a37SNikolas Klauser [[maybe_unused]] std::same_as<std::array<int, 10>::iterator> decltype(auto) ret =
1157af89a37SNikolas Klauser std::ranges::fill(std::views::all(a), 1);
1167af89a37SNikolas Klauser assert(std::all_of(a.begin(), a.end(), [](int i) { return i == 1; }));
1177af89a37SNikolas Klauser }
1187af89a37SNikolas Klauser
1197af89a37SNikolas Klauser { // check that non-trivially copyable items are copied properly
1207af89a37SNikolas Klauser {
1217af89a37SNikolas Klauser std::array<std::string, 10> a;
1227af89a37SNikolas Klauser auto ret = std::ranges::fill(a.begin(), a.end(), "long long string so no SSO");
123*d05bada5SDuo Wang assert(ret == a.end());
1247af89a37SNikolas Klauser assert(std::all_of(a.begin(), a.end(), [](auto& s) { return s == "long long string so no SSO"; }));
1257af89a37SNikolas Klauser }
1267af89a37SNikolas Klauser {
1277af89a37SNikolas Klauser std::array<std::string, 10> a;
1287af89a37SNikolas Klauser auto ret = std::ranges::fill(a, "long long string so no SSO");
129*d05bada5SDuo Wang assert(ret == a.end());
1307af89a37SNikolas Klauser assert(std::all_of(a.begin(), a.end(), [](auto& s) { return s == "long long string so no SSO"; }));
1317af89a37SNikolas Klauser }
1327af89a37SNikolas Klauser }
1337af89a37SNikolas Klauser
1347af89a37SNikolas Klauser return true;
1357af89a37SNikolas Klauser }
1367af89a37SNikolas Klauser
main(int,char **)1377af89a37SNikolas Klauser int main(int, char**) {
1387af89a37SNikolas Klauser test();
1397af89a37SNikolas Klauser static_assert(test());
1407af89a37SNikolas Klauser
1417af89a37SNikolas Klauser return 0;
1427af89a37SNikolas Klauser }
143