1// 24.1.5 Random access iterators 2// 24.3.1 Iterator traits 3// (basic_string and vector implementations) 4// 5// Copyright (C) 1999-2015 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 25int 26string_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 251int 252vector_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 489int 490reverse_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 515int 516wrong_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 580int 581test6642() 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 590int 591main() 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