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<class Iter, IntegralLike Size, class T> |
12 | // requires OutputIterator<Iter, const T&> |
13 | // constexpr OutputIterator // constexpr after C++17 |
14 | // fill_n(Iter first, Size n, const T& value); |
15 | |
16 | #include <algorithm> |
17 | #include <cassert> |
18 | |
19 | #include "test_macros.h" |
20 | #include "test_iterators.h" |
21 | #include "user_defined_integral.h" |
22 | |
23 | #if TEST_STD_VER > 17 |
24 | TEST_CONSTEXPR bool test_constexpr() { |
25 | const std::size_t N = 5; |
26 | int ib[] = {0, 0, 0, 0, 0, 0}; // one bigger than N |
27 | |
28 | auto it = std::fill_n(std::begin(ib), N, 5); |
29 | return it == (std::begin(ib) + N) |
30 | && std::all_of(std::begin(ib), it, [](int a) {return a == 5; }) |
31 | && *it == 0 // don't overwrite the last value in the output array |
32 | ; |
33 | } |
34 | #endif |
35 | |
36 | typedef UserDefinedIntegral<unsigned> UDI; |
37 | |
38 | template <class Iter> |
39 | void |
40 | test_char() |
41 | { |
42 | char a[4] = {}; |
43 | Iter it = std::fill_n(Iter(a), UDI(4), char(1)); |
44 | assert(base(it) == a + 4); |
45 | assert(a[0] == 1); |
46 | assert(a[1] == 1); |
47 | assert(a[2] == 1); |
48 | assert(a[3] == 1); |
49 | } |
50 | |
51 | template <class Iter> |
52 | void |
53 | test_int() |
54 | { |
55 | int a[4] = {}; |
56 | Iter it = std::fill_n(Iter(a), UDI(4), 1); |
57 | assert(base(it) == a + 4); |
58 | assert(a[0] == 1); |
59 | assert(a[1] == 1); |
60 | assert(a[2] == 1); |
61 | assert(a[3] == 1); |
62 | } |
63 | |
64 | void |
65 | test_int_array() |
66 | { |
67 | int a[4] = {}; |
68 | assert(std::fill_n(a, UDI(4), static_cast<char>(1)) == a + 4); |
69 | assert(a[0] == 1); |
70 | assert(a[1] == 1); |
71 | assert(a[2] == 1); |
72 | assert(a[3] == 1); |
73 | } |
74 | |
75 | struct source { |
76 | source() : i(0) { } |
77 | |
78 | operator int() const { return i++; } |
79 | mutable int i; |
80 | }; |
81 | |
82 | void |
83 | test_int_array_struct_source() |
84 | { |
85 | int a[4] = {}; |
86 | assert(std::fill_n(a, UDI(4), source()) == a + 4); |
87 | assert(a[0] == 0); |
88 | assert(a[1] == 1); |
89 | assert(a[2] == 2); |
90 | assert(a[3] == 3); |
91 | } |
92 | |
93 | struct test1 { |
94 | test1() : c(0) { } |
95 | test1(char xc) : c(xc + 1) { } |
96 | char c; |
97 | }; |
98 | |
99 | void |
100 | test_struct_array() |
101 | { |
102 | test1 test1a[4] = {}; |
103 | assert(std::fill_n(test1a, UDI(4), static_cast<char>(10)) == test1a + 4); |
104 | assert(test1a[0].c == 11); |
105 | assert(test1a[1].c == 11); |
106 | assert(test1a[2].c == 11); |
107 | assert(test1a[3].c == 11); |
108 | } |
109 | |
110 | class A |
111 | { |
112 | char a_; |
113 | public: |
114 | A() {} |
115 | explicit A(char a) : a_(a) {} |
116 | operator unsigned char() const {return 'b';} |
117 | |
118 | friend bool operator==(const A& x, const A& y) |
119 | {return x.a_ == y.a_;} |
120 | }; |
121 | |
122 | void |
123 | test5() |
124 | { |
125 | A a[3]; |
126 | assert(std::fill_n(&a[0], UDI(3), A('a')) == a+3); |
127 | assert(a[0] == A('a')); |
128 | assert(a[1] == A('a')); |
129 | assert(a[2] == A('a')); |
130 | } |
131 | |
132 | struct Storage |
133 | { |
134 | union |
135 | { |
136 | unsigned char a; |
137 | unsigned char b; |
138 | }; |
139 | }; |
140 | |
141 | void test6() |
142 | { |
143 | Storage foo[5]; |
144 | std::fill_n(first: &foo[0], n: UDI(5), value: Storage()); |
145 | } |
146 | |
147 | |
148 | int main(int, char**) |
149 | { |
150 | test_char<cpp17_output_iterator<char*> >(); |
151 | test_char<forward_iterator<char*> >(); |
152 | test_char<bidirectional_iterator<char*> >(); |
153 | test_char<random_access_iterator<char*> >(); |
154 | test_char<char*>(); |
155 | |
156 | test_int<cpp17_output_iterator<int*> >(); |
157 | test_int<forward_iterator<int*> >(); |
158 | test_int<bidirectional_iterator<int*> >(); |
159 | test_int<random_access_iterator<int*> >(); |
160 | test_int<int*>(); |
161 | |
162 | test_int_array(); |
163 | test_int_array_struct_source(); |
164 | test_struct_array(); |
165 | |
166 | test5(); |
167 | test6(); |
168 | |
169 | #if TEST_STD_VER > 17 |
170 | static_assert(test_constexpr()); |
171 | #endif |
172 | |
173 | return 0; |
174 | } |
175 | |