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 // REQUIRES: long_tests
11 
12 // <deque>
13 
14 // template <class InputIterator>
15 //   iterator insert (const_iterator p, InputIterator f, InputIterator l);
16 
17 #include <deque>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 #include "test_iterators.h"
22 #include "MoveOnly.h"
23 #include "../../../stack_allocator.h"
24 #include "min_allocator.h"
25 
26 template <class C>
27 C
make(int size,int start=0)28 make(int size, int start = 0 )
29 {
30     const int b = 4096 / sizeof(int);
31     int init = 0;
32     if (start > 0)
33     {
34         init = (start+1) / b + ((start+1) % b != 0);
35         init *= b;
36         --init;
37     }
38     C c(init, 0);
39     for (int i = 0; i < init-start; ++i)
40         c.pop_back();
41     for (int i = 0; i < size; ++i)
42         c.push_back(i);
43     for (int i = 0; i < start; ++i)
44         c.pop_front();
45     return c;
46 }
47 
48 template <class C>
49 void
test(int P,const C & c0,const C & c2)50 test(int P, const C& c0, const C& c2)
51 {
52     {
53     typedef typename C::const_iterator CI;
54     typedef input_iterator<CI> BCI;
55     C c1 = c0;
56     std::size_t c1_osize = c1.size();
57     CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end()));
58     assert(i == c1.begin() + P);
59     assert(c1.size() == c1_osize + c2.size());
60     assert(distance(c1.begin(), c1.end()) == c1.size());
61     i = c1.begin();
62     for (int j = 0; j < P; ++j, ++i)
63         assert(*i == j);
64     for (int j = 0; j < c2.size(); ++j, ++i)
65         assert(*i == j);
66     for (int j = P; j < c1_osize; ++j, ++i)
67         assert(*i == j);
68     }
69     {
70     typedef typename C::const_iterator CI;
71     typedef forward_iterator<CI> BCI;
72     C c1 = c0;
73     std::size_t c1_osize = c1.size();
74     CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end()));
75     assert(i == c1.begin() + P);
76     assert(c1.size() == c1_osize + c2.size());
77     assert(distance(c1.begin(), c1.end()) == c1.size());
78     i = c1.begin();
79     for (int j = 0; j < P; ++j, ++i)
80         assert(*i == j);
81     for (int j = 0; j < c2.size(); ++j, ++i)
82         assert(*i == j);
83     for (int j = P; j < c1_osize; ++j, ++i)
84         assert(*i == j);
85     }
86     {
87     typedef typename C::const_iterator CI;
88     typedef bidirectional_iterator<CI> BCI;
89     C c1 = c0;
90     std::size_t c1_osize = c1.size();
91     CI i = c1.insert(c1.begin() + P, BCI(c2.begin()), BCI(c2.end()));
92     assert(i == c1.begin() + P);
93     assert(c1.size() == c1_osize + c2.size());
94     assert(distance(c1.begin(), c1.end()) == c1.size());
95     i = c1.begin();
96     for (int j = 0; j < P; ++j, ++i)
97         assert(*i == j);
98     for (int j = 0; j < c2.size(); ++j, ++i)
99         assert(*i == j);
100     for (int j = P; j < c1_osize; ++j, ++i)
101         assert(*i == j);
102     }
103 }
104 
105 template <class C>
106 void
testN(int start,int N,int M)107 testN(int start, int N, int M)
108 {
109     for (int i = 0; i <= 3; ++i)
110     {
111         if (0 <= i && i <= N)
112         {
113             C c1 = make<C>(N, start);
114             C c2 = make<C>(M);
115             test(i, c1, c2);
116         }
117     }
118     for (int i = M-1; i <= M+1; ++i)
119     {
120         if (0 <= i && i <= N)
121         {
122             C c1 = make<C>(N, start);
123             C c2 = make<C>(M);
124             test(i, c1, c2);
125         }
126     }
127     for (int i = N/2-1; i <= N/2+1; ++i)
128     {
129         if (0 <= i && i <= N)
130         {
131             C c1 = make<C>(N, start);
132             C c2 = make<C>(M);
133             test(i, c1, c2);
134         }
135     }
136     for (int i = N - M - 1; i <= N - M + 1; ++i)
137     {
138         if (0 <= i && i <= N)
139         {
140             C c1 = make<C>(N, start);
141             C c2 = make<C>(M);
142             test(i, c1, c2);
143         }
144     }
145     for (int i = N - M - 1; i <= N - M + 1; ++i)
146     {
147         if (0 <= i && i <= N)
148         {
149             C c1 = make<C>(N, start);
150             C c2 = make<C>(M);
151             test(i, c1, c2);
152         }
153     }
154     for (int i = N - 3; i <= N; ++i)
155     {
156         if (0 <= i && i <= N)
157         {
158             C c1 = make<C>(N, start);
159             C c2 = make<C>(M);
160             test(i, c1, c2);
161         }
162     }
163 }
164 
165 template <class C>
166 void
testI(int P,C & c1,const C & c2)167 testI(int P, C& c1, const C& c2)
168 {
169     typedef typename C::const_iterator CI;
170     typedef input_iterator<CI> ICI;
171     std::size_t c1_osize = c1.size();
172     CI i = c1.insert(c1.begin() + P, ICI(c2.begin()), ICI(c2.end()));
173     assert(i == c1.begin() + P);
174     assert(c1.size() == c1_osize + c2.size());
175     assert(distance(c1.begin(), c1.end()) == c1.size());
176     i = c1.begin();
177     for (int j = 0; j < P; ++j, ++i)
178         assert(*i == j);
179     for (int j = 0; j < c2.size(); ++j, ++i)
180         assert(*i == j);
181     for (int j = P; j < c1_osize; ++j, ++i)
182         assert(*i == j);
183 }
184 
185 template <class C>
186 void
testNI(int start,int N,int M)187 testNI(int start, int N, int M)
188 {
189     for (int i = 0; i <= 3; ++i)
190     {
191         if (0 <= i && i <= N)
192         {
193             C c1 = make<C>(N, start);
194             C c2 = make<C>(M);
195             testI(i, c1, c2);
196         }
197     }
198     for (int i = M-1; i <= M+1; ++i)
199     {
200         if (0 <= i && i <= N)
201         {
202             C c1 = make<C>(N, start);
203             C c2 = make<C>(M);
204             testI(i, c1, c2);
205         }
206     }
207     for (int i = N/2-1; i <= N/2+1; ++i)
208     {
209         if (0 <= i && i <= N)
210         {
211             C c1 = make<C>(N, start);
212             C c2 = make<C>(M);
213             testI(i, c1, c2);
214         }
215     }
216     for (int i = N - M - 1; i <= N - M + 1; ++i)
217     {
218         if (0 <= i && i <= N)
219         {
220             C c1 = make<C>(N, start);
221             C c2 = make<C>(M);
222             testI(i, c1, c2);
223         }
224     }
225     for (int i = N - 3; i <= N; ++i)
226     {
227         if (0 <= i && i <= N)
228         {
229             C c1 = make<C>(N, start);
230             C c2 = make<C>(M);
231             testI(i, c1, c2);
232         }
233     }
234 }
235 
236 template <class C>
237 void
test_move()238 test_move()
239 {
240 #if TEST_STD_VER >= 11
241     C c;
242     typedef typename C::const_iterator CI;
243     {
244         MoveOnly mo(0);
245         typedef MoveOnly* I;
246         c.insert(c.end(), std::move_iterator<I>(&mo), std::move_iterator<I>(&mo+1));
247     }
248     int j = 0;
249     for (CI i = c.begin(); i != c.end(); ++i, ++j)
250         assert(*i == MoveOnly(j));
251     {
252         MoveOnly mo(1);
253         typedef input_iterator<MoveOnly*> I;
254         c.insert(c.end(), std::move_iterator<I>(I(&mo)), std::move_iterator<I>(I(&mo+1)));
255     }
256     j = 0;
257     for (CI i = c.begin(); i != c.end(); ++i, ++j)
258         assert(*i == MoveOnly(j));
259 #endif
260 }
261 
main()262 int main()
263 {
264     {
265     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
266     const int N = sizeof(rng)/sizeof(rng[0]);
267     for (int i = 0; i < N; ++i)
268         for (int j = 0; j < N; ++j)
269             for (int k = 0; k < N; ++k)
270                 testN<std::deque<int> >(rng[i], rng[j], rng[k]);
271     testNI<std::deque<int> >(1500, 2000, 1000);
272 #if TEST_STD_VER >= 11
273     test_move<std::deque<MoveOnly, stack_allocator<MoveOnly, 2000> > >();
274 #endif
275     }
276 #if TEST_STD_VER >= 11
277     {
278     int rng[] = {0, 1, 2, 3, 1023, 1024, 1025, 2047, 2048, 2049};
279     const int N = sizeof(rng)/sizeof(rng[0]);
280     for (int i = 0; i < N; ++i)
281         for (int j = 0; j < N; ++j)
282             for (int k = 0; k < N; ++k)
283                 testN<std::deque<int, min_allocator<int>> >(rng[i], rng[j], rng[k]);
284     testNI<std::deque<int> >(1500, 2000, 1000);
285     test_move<std::deque<MoveOnly, min_allocator<MoveOnly> > >();
286     }
287 #endif
288 }
289