1 // 24.1.5 Random access iterators
2 // 24.3.1 Iterator traits
3 // (basic_string and vector implementations)
4 //
5 // Copyright (C) 1999-2018 Free Software Foundation, Inc.
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; see the file COPYING3.  If not see
18 // <http://www.gnu.org/licenses/>.
19 
20 
21 #include <string>
22 #include <vector>
23 #include <testsuite_hooks.h>
24 
25 int
string_stuff()26 string_stuff()
27 {
28    int failures(0);
29 
30    std::string s("abcde");
31 
32    std::string::iterator i1(s.begin());
33    if (*i1 != 'a')
34       ++failures;
35 
36    ++i1;
37    if (*i1 != 'b')
38       ++failures;
39 
40    if (*i1++ != 'b')
41        ++failures;
42    if (*i1 != 'c')
43       ++failures;
44 
45    ++ ++i1;
46    if (*i1 != 'e')
47       ++failures;
48 
49    --i1;
50    if (*i1 != 'd')
51       ++failures;
52 
53    if (*i1-- != 'd')
54       ++failures;
55    if (*i1 != 'c')
56       ++failures;
57 
58    -- --i1;
59    if (*i1 != 'a')
60       ++failures;
61 
62    std::string::iterator i2;
63    i2 = s.end();
64    std::iterator_traits<std::string::iterator>::difference_type d1;
65    d1 = i2 - i1;
66    if (d1 != 5)
67       ++failures;
68 
69    std::iterator_traits<std::string::iterator>::value_type v1;
70    v1 = i1[0];
71    if (v1 != 'a')
72       ++failures;
73 
74    std::iterator_traits<std::string::iterator>::reference r1(i1[0]);
75    if (r1 != 'a')
76       ++failures;
77    r1 = 'x';
78    if (r1 != 'x')
79       ++failures;
80    r1 = 'a';
81 
82    if ((i1 != i2) != true)
83       ++failures;
84    if ((i1 == i2) != false)
85       ++failures;
86    if ((i1 <  i2) != true)
87       ++failures;
88    if ((i1 >  i2) != false)
89       ++failures;
90    if ((i1 <= i2) != true)
91       ++failures;
92    if ((i1 >= i2) != false)
93       ++failures;
94 
95    std::string::iterator i3;
96    i3 = i1;
97    if ((i3 == i1) != true)
98       ++failures;
99 
100    i3 += 5;
101    if ((i3 == i2) != true)
102       ++failures;
103 
104    i3 -= 5;
105    if ((i3 == i1) != true)
106       ++failures;
107 
108    if (i3 + 5 != i2)
109       ++failures;
110 
111    if (5 + i3 != i2)
112       ++failures;
113 
114    if (i2 - 5 != i3)
115       ++failures;
116 
117    if (i1[0] != 'a')
118       ++failures;
119 
120    i1[4] = 'x';
121    if (i2[-1] != 'x')
122       ++failures;
123    i1[4] = 'e';
124 
125    i1[2] = 'x';
126    if (i2[-3] != 'x')
127       ++failures;
128    i1[2] = 'c';
129 
130    std::string::const_iterator ci1(s.begin());
131    if (*ci1 != 'a')
132       ++failures;
133 
134    ++ci1;
135    if (*ci1 != 'b')
136       ++failures;
137 
138    if (*ci1++ != 'b')
139       ++failures;
140    if (*ci1 != 'c')
141       ++failures;
142 
143    ++ ++ci1;
144    if (*ci1 != 'e')
145       ++failures;
146 
147    --ci1;
148    if (*ci1 != 'd')
149       ++failures;
150 
151    if (*ci1-- != 'd')
152       ++failures;
153    if (*ci1 != 'c')
154       ++failures;
155 
156    -- --ci1;
157    if (*ci1 != 'a')
158       ++failures;
159 
160    std::string::const_iterator ci2;
161    ci2 = s.end();
162    std::iterator_traits<std::string::const_iterator>::difference_type d2;
163    d2 = ci2 - ci1;
164    if (d2 != 5)
165      ++failures;
166 
167    std::iterator_traits<std::string::const_iterator>::value_type v2;
168    v2 = ci1[0];
169    if (v2 != 'a')
170      ++failures;
171 
172    std::iterator_traits<std::string::const_iterator>::reference r2(ci1[0]);
173    if (r2 != 'a')
174       ++failures;
175 
176    if ((ci1 != ci2) != true)
177       ++failures;
178    if ((ci1 == ci2) != false)
179       ++failures;
180    if ((ci1 <  ci2) != true)
181       ++failures;
182    if ((ci1 >  ci2) != false)
183       ++failures;
184    if ((ci1 <= ci2) != true)
185       ++failures;
186    if ((ci1 >= ci2) != false)
187       ++failures;
188 
189    std::string::const_iterator ci3;
190    ci3 = ci1;
191    if ((ci3 == ci1) != true)
192       ++failures;
193 
194    ci3 += 5;
195    if ((ci3 == ci2) != true)
196       ++failures;
197 
198    ci3 -= 5;
199    if ((ci3 == ci1) != true)
200       ++failures;
201 
202    if (ci3 + 5 != ci2)
203       ++failures;
204 
205    if (5 + ci3 != ci2)
206       ++failures;
207 
208    if (ci2 - 5 != ci3)
209       ++failures;
210 
211    if (ci1[2] != 'c')
212       ++failures;
213 
214    if (ci2[-1] != 'e')
215       ++failures;
216 
217    // iterator and const_iterator
218    std::string::const_iterator ci4(i1);
219    if ((ci4 == i1) != true)
220       ++failures;
221    if ((ci4 != i1) != false)
222       ++failures;
223    if ((ci4 < i1)  != false)
224      ++failures;
225    if ((ci4 > i1)  != false)
226      ++failures;
227    if ((ci4 <= i1) != true)
228      ++failures;
229    if ((ci4 >= i1) != true)
230      ++failures;
231    ci4 = i2;
232    if ((i2 == ci4) != true)
233      ++failures;
234    if ((i2 < ci4)  != false)
235      ++failures;
236    if ((i2 > ci4)  != false)
237      ++failures;
238    if ((i2 <= ci4) != true)
239      ++failures;
240    if ((i2 >= ci4) != true)
241      ++failures;
242 
243    const std::string cs("ABCDE");
244    std::string::const_iterator ci5(cs.begin());
245    if (ci5[0] != 'A')
246       ++failures;
247 
248    return failures;
249 }
250 
251 int
vector_stuff()252 vector_stuff()
253 {
254    int failures(0);
255 
256    std::vector<int> v;
257    v.push_back(int(1));
258    v.push_back(int(2));
259    v.push_back(int(3));
260    v.push_back(int(4));
261    v.push_back(int(5));
262 
263    std::vector<int>::iterator i1(v.begin());
264    if (*i1 != 1)
265       ++failures;
266 
267    ++i1;
268    if (*i1 != 2)
269       ++failures;
270 
271    if (*i1++ != 2)
272       ++failures;
273    if (*i1 != 3)
274       ++failures;
275 
276    ++ ++i1;
277    if (*i1 != 5)
278       ++failures;
279 
280    --i1;
281    if (*i1 != 4)
282       ++failures;
283 
284    if (*i1-- != 4)
285       ++failures;
286    if (*i1 != 3)
287       ++failures;
288 
289    -- --i1;
290    if (*i1 != 1)
291       ++failures;
292 
293    std::vector<int>::iterator i2;
294    i2 = v.end();
295    std::iterator_traits<std::vector<int>::iterator>::difference_type d1;
296    d1 = i2 - i1;
297    if (d1 != 5)
298       ++failures;
299 
300    std::iterator_traits<std::vector<int>::iterator>::value_type v1;
301    v1 = i1[0];
302    if (v1 != 1)
303       ++failures;
304 
305    std::iterator_traits<std::vector<int>::iterator>::reference r1(i1[0]);
306    if (r1 != 1)
307       ++failures;
308    r1 = 9;
309    if (r1 != 9)
310       ++failures;
311    r1 = 1;
312 
313    if ((i1 != i2) != true)
314       ++failures;
315    if ((i1 == i2) != false)
316       ++failures;
317    if ((i1 <  i2) != true)
318       ++failures;
319    if ((i1 >  i2) != false)
320       ++failures;
321    if ((i1 <= i2) != true)
322       ++failures;
323    if ((i1 >= i2) != false)
324       ++failures;
325 
326    std::vector<int>::iterator i3;
327    i3 = i1;
328    if ((i3 == i1) != true)
329       ++failures;
330 
331    i3 += 5;
332    if ((i3 == i2) != true)
333       ++failures;
334 
335    i3 -= 5;
336    if ((i3 == i1) != true)
337       ++failures;
338 
339    if (i3 + 5 != i2)
340       ++failures;
341 
342    if (5 + i3 != i2)
343       ++failures;
344 
345    if (i2 - 5 != i3)
346       ++failures;
347 
348    if (i1[0] != 1)
349       ++failures;
350 
351    i1[4] = 9;
352    if (i2[-1] != 9)
353       ++failures;
354    i1[4] = 5;
355 
356    i1[2] = 9;
357    if (i2[-3] != 9)
358       ++failures;
359    i1[2] = 3;
360 
361    std::vector<int>::const_iterator ci1(v.begin());
362    if (*ci1 != 1)
363       ++failures;
364 
365    ++ci1;
366    if (*ci1 != 2)
367       ++failures;
368 
369    if (*ci1++ != 2)
370       ++failures;
371    if (*ci1 != 3)
372       ++failures;
373 
374    ++ ++ci1;
375    if (*ci1 != 5)
376       ++failures;
377 
378    --ci1;
379    if (*ci1 != 4)
380       ++failures;
381 
382    if (*ci1-- != 4)
383       ++failures;
384    if (*ci1 != 3)
385       ++failures;
386 
387    -- --ci1;
388    if (*ci1 != 1)
389       ++failures;
390 
391    std::vector<int>::const_iterator ci2;
392    ci2 = v.end();
393    std::iterator_traits<std::vector<int>::const_iterator>::difference_type d2;
394    d2 = ci2 - ci1;
395    if (d2 != 5)
396       ++failures;
397 
398    std::iterator_traits<std::vector<int>::const_iterator>::value_type v2;
399    v2 = ci1[0];
400    if (v2 != 1)
401       ++failures;
402 
403    std::iterator_traits<std::vector<int>::const_iterator>::reference
404       r2(ci1[0]);
405    if (r2 != 1)
406       ++failures;
407 
408    if ((ci1 != ci2) != true)
409       ++failures;
410    if ((ci1 == ci2) != false)
411       ++failures;
412    if ((ci1 <  ci2) != true)
413       ++failures;
414    if ((ci1 >  ci2) != false)
415       ++failures;
416    if ((ci1 <= ci2) != true)
417       ++failures;
418    if ((ci1 >= ci2) != false)
419       ++failures;
420 
421    std::vector<int>::const_iterator ci3;
422    ci3 = ci1;
423    if ((ci3 == ci1) != true)
424       ++failures;
425 
426    ci3 += 5;
427    if ((ci3 == ci2) != true)
428       ++failures;
429 
430    ci3 -= 5;
431    if ((ci3 == ci1) != true)
432       ++failures;
433 
434    if (ci3 + 5 != ci2)
435       ++failures;
436 
437    if (5 + ci3 != ci2)
438       ++failures;
439 
440    if (ci2 - 5 != ci3)
441       ++failures;
442 
443    if (ci1[2] != 3)
444       ++failures;
445 
446    if (ci2[-1] != 5)
447       ++failures;
448 
449    // iterator to const_iterator
450    std::vector<int>::const_iterator ci4(i1);
451    if ((ci4 == i1) != true)
452       ++failures;
453    if ((ci4 != i1) != false)
454       ++failures;
455    if ((ci4 < i1)  != false)
456      ++failures;
457    if ((ci4 > i1)  != false)
458      ++failures;
459    if ((ci4 <= i1) != true)
460      ++failures;
461    if ((ci4 >= i1) != true)
462      ++failures;
463    ci4 = i2;
464    if ((i2 == ci4) != true)
465      ++failures;
466    if ((i2 < ci4)  != false)
467      ++failures;
468    if ((i2 > ci4)  != false)
469      ++failures;
470    if ((i2 <= ci4) != true)
471      ++failures;
472    if ((i2 >= ci4) != true)
473      ++failures;
474 
475    const std::vector<int> cv(v);
476    std::vector<int>::const_iterator ci5(cv.begin());
477    if (ci5[0] != 1)
478       ++failures;
479 
480    std::vector<std::string> vs;
481    vs.push_back(std::string("abc"));
482    std::vector<std::string>::iterator ivs(vs.begin());
483    if (ivs->c_str()[1] != 'b')
484       ++failures;
485 
486    return failures;
487 }
488 
489 int
reverse_stuff()490 reverse_stuff()
491 {
492    int failures(0);
493 
494    std::string s("abcde");
495 
496    std::string::reverse_iterator ri(s.rbegin());
497    if (*ri != 'e')
498       ++failures;
499 
500    std::iterator_traits<std::string::reverse_iterator>::difference_type d;
501    d = s.rend() - ri;
502    if (d != 5)
503       ++failures;
504 
505    const std::string cs("abcde");
506    std::string::const_reverse_iterator cri(cs.rend());
507    if (cri - 5 != cs.rbegin())
508       ++failures;
509 
510    return failures;
511 }
512 
513 // the following should be compiler errors
514 // flag runtime errors in case they slip through the compiler
515 int
wrong_stuff()516 wrong_stuff()
517 {
518    int failures(0);
519 
520 #ifdef ITER24_F1
521    extern void f(std::vector<std::string*>::iterator);
522    std::vector<std::string*> vs[2];
523    f(vs);                       // address of array is not an iterator
524    failures++;
525 #endif
526 
527 #ifdef ITER24_F2
528    std::string s;
529    char *i = s.begin();         // begin() doesn't return a pointer
530    failures++;
531 #endif
532 
533 #ifdef ITER24_F3
534    std::string::const_iterator ci;
535    std::string::iterator i;
536    if (i - ci)                  // remove const_ is a warning
537       i++;
538    // failures++;  only a warning
539 #endif
540 
541 #ifdef ITER24_F4
542    std::vector<char>::iterator iv;
543    std::string::iterator is(iv);// vector<char> is not string
544    failures++;
545 #endif
546 
547 #ifdef ITER24_F5
548    std::vector<char>::iterator iv;
549    std::string::iterator is;
550    if (iv == is)                // vector<char> is not string
551       ++iv;
552    failures++;
553 #endif
554 
555 #ifdef ITER24_F6
556    std::vector<char>::const_iterator ci;
557    std::vector<char>::iterator i = ci;  // remove const_ is a warning
558    ++i;
559    // failures++; only a warning
560 #endif
561 
562 #ifdef ITER24_F7
563    std::vector<int> v(1);
564    std::vector<int>::const_iterator ci(v.begin());
565    *ci = 1;                     // cannot assign through const_iterator
566    failures++;
567 #endif
568 
569 #ifdef ITER24_F8
570    std::vector<const int> v(1);
571    std::vector<const int>::reference r(v.begin()[0]);
572    r = 1;                       // cannot assign through reference to const
573    failures++;
574 #endif
575 
576    return failures;
577 }
578 
579 // libstdc++/6642
580 int
test6642()581 test6642()
582 {
583    std::string s;
584    std::string::iterator it = s.begin();
585    std::string::const_iterator cit = s.begin();
586 
587    return it - cit;
588 }
589 
590 int
main()591 main()
592 {
593    int failures(0);
594 
595    failures += string_stuff();
596 
597    failures += vector_stuff();
598 
599    failures += reverse_stuff();
600 
601    failures += wrong_stuff();
602 
603    failures += test6642();
604 
605    VERIFY(failures == 0);
606    return 0;
607 }
608