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// template<ForwardIterator Iter, class T>
12// requires OutputIterator<Iter, const T&>
13// constexpr void // constexpr after C++17
14// fill(Iter first, Iter last, const T& value);
15
16#include <algorithm>
17#include <array>
18#include <cassert>
19#include <cstddef>
20#include <vector>
21
22#include "sized_allocator.h"
23#include "test_macros.h"
24#include "test_iterators.h"
25#include "type_algorithms.h"
26
27template <class Iter, class Container>
28TEST_CONSTEXPR_CXX20 void
29test(Container in, size_t from, size_t to, typename Container::value_type value, Container expected) {
30 std::fill(Iter(in.data() + from), Iter(in.data() + to), value);
31 assert(in == expected);
32}
33
34template <class T>
35struct Test {
36 template <class Iter>
37 TEST_CONSTEXPR_CXX20 void operator()() {
38 {
39 std::array<T, 4> in = {1, 2, 3, 4};
40 std::array<T, 4> expected = {5, 5, 5, 5};
41 test<Iter>(in, 0, 4, 5, expected);
42 }
43 {
44 std::array<T, 4> in = {1, 2, 3, 4};
45 std::array<T, 4> expected = {1, 5, 5, 4};
46 test<Iter>(in, 1, 3, 5, expected);
47 }
48 }
49};
50
51TEST_CONSTEXPR_CXX20 bool test_vector_bool(std::size_t N) {
52 { // Test cases validating leading/trailing bits unfilled remain unchanged
53 { // Leading bits are not filled
54 std::vector<bool> in(N, false);
55 std::vector<bool> expected(N, true);
56 expected[0] = expected[1] = false;
57 std::fill(first: in.begin() + 2, last: in.end(), value: true);
58 assert(in == expected);
59 }
60 { // Trailing bits are not filled
61 std::vector<bool> in(N, false);
62 std::vector<bool> expected(N, true);
63 expected[N - 1] = expected[N - 2] = false;
64 std::fill(first: in.begin(), last: in.end() - 2, value: true);
65 assert(in == expected);
66 }
67 { // Leading and trailing bits are not filled
68 std::vector<bool> in(N, false);
69 std::vector<bool> expected(N, true);
70 expected[0] = expected[1] = expected[N - 1] = expected[N - 2] = false;
71 std::fill(first: in.begin() + 2, last: in.end() - 2, value: true);
72 assert(in == expected);
73 }
74 }
75
76 { // Test cases with full or partial bytes filled
77 { // Full bytes filled
78 std::vector<bool> in(N, false);
79 std::vector<bool> expected(N, true);
80 std::fill(first: in.begin(), last: in.end(), value: true);
81 assert(in == expected);
82 }
83 { // Partial bytes with offset filled
84 std::vector<bool> in(N, false);
85 std::vector<bool> expected(N, true);
86 std::fill(first: in.begin() + 4, last: in.end() - 4, value: true);
87 std::fill(first: expected.begin(), last: expected.begin() + 4, value: false);
88 std::fill(first: expected.end() - 4, last: expected.end(), value: false);
89 assert(in == expected);
90 }
91 }
92
93 return true;
94}
95
96TEST_CONSTEXPR_CXX20 bool test() {
97 types::for_each(types::forward_iterator_list<char*>(), Test<char>());
98 types::for_each(types::forward_iterator_list<int*>(), Test<int>());
99
100 { // Test vector<bool>::iterator optimization
101 assert(test_vector_bool(8));
102 assert(test_vector_bool(19));
103 assert(test_vector_bool(32));
104 assert(test_vector_bool(49));
105 assert(test_vector_bool(64));
106 assert(test_vector_bool(199));
107 assert(test_vector_bool(256));
108
109 // Make sure std::fill behaves properly with std::vector<bool> iterators with custom size types.
110 // See https://github.com/llvm/llvm-project/pull/122410.
111 {
112 using Alloc = sized_allocator<bool, std::uint8_t, std::int8_t>;
113 std::vector<bool, Alloc> in(100, false, Alloc(1));
114 std::vector<bool, Alloc> expected(100, true, Alloc(1));
115 std::fill(in.begin(), in.end(), true);
116 assert(in == expected);
117 }
118 {
119 using Alloc = sized_allocator<bool, std::uint16_t, std::int16_t>;
120 std::vector<bool, Alloc> in(200, false, Alloc(1));
121 std::vector<bool, Alloc> expected(200, true, Alloc(1));
122 std::fill(in.begin(), in.end(), true);
123 assert(in == expected);
124 }
125 {
126 using Alloc = sized_allocator<bool, std::uint32_t, std::int32_t>;
127 std::vector<bool, Alloc> in(200, false, Alloc(1));
128 std::vector<bool, Alloc> expected(200, true, Alloc(1));
129 std::fill(in.begin(), in.end(), true);
130 assert(in == expected);
131 }
132 {
133 using Alloc = sized_allocator<bool, std::uint64_t, std::int64_t>;
134 std::vector<bool, Alloc> in(200, false, Alloc(1));
135 std::vector<bool, Alloc> expected(200, true, Alloc(1));
136 std::fill(in.begin(), in.end(), true);
137 assert(in == expected);
138 }
139 }
140
141 return true;
142}
143
144int main(int, char**) {
145 test();
146#if TEST_STD_VER >= 20
147 static_assert(test());
148#endif
149
150 return 0;
151}
152

source code of libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill.pass.cpp