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