1 //Has to be first for StackAllocator swap overload to be taken 2 //into account (at least using GCC 4.0.1) 3 #include "stack_allocator.h" 4 5 #include <algorithm> 6 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 7 # include <slist> 8 # if !defined (_STLP_USE_NO_IOSTREAMS) 9 # include <sstream> 10 # endif 11 # include <iterator> 12 # include <functional> 13 #endif 14 15 #include "cppunit/cppunit_proxy.h" 16 17 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) 18 using namespace std; 19 #endif 20 21 #if !defined (STLPORT) && defined(__GNUC__) 22 using namespace __gnu_cxx; 23 #endif 24 25 // 26 // TestCase class 27 // 28 class SlistTest : public CPPUNIT_NS::TestCase 29 { 30 CPPUNIT_TEST_SUITE(SlistTest); 31 #if !defined (STLPORT) || defined (_STLP_NO_EXTENSIONS) || defined (_STLP_USE_NO_IOSTREAMS) 32 CPPUNIT_IGNORE; 33 #endif 34 CPPUNIT_TEST(slist1); 35 #if defined (STLPORT) && defined (_STLP_USE_NO_IOSTREAMS) 36 CPPUNIT_STOP_IGNORE; 37 #endif 38 CPPUNIT_TEST(erase); 39 CPPUNIT_TEST(insert); 40 CPPUNIT_TEST(splice); 41 CPPUNIT_TEST(allocator_with_state); 42 CPPUNIT_TEST_SUITE_END(); 43 44 protected: 45 void slist1(); 46 void erase(); 47 void insert(); 48 void splice(); 49 void allocator_with_state(); 50 }; 51 52 CPPUNIT_TEST_SUITE_REGISTRATION(SlistTest); 53 54 // 55 // tests implementation 56 // 57 void SlistTest::slist1() 58 { 59 #if defined (STLPORT) && !defined (_STLP_USE_NO_IOSTREAMS) && !defined (_STLP_NO_EXTENSIONS) 60 /* 61 original: xlxtss 62 reversed: sstxlx 63 removed: sstl 64 uniqued: stl 65 sorted: lst 66 */ 67 68 char array [] = { 'x', 'l', 'x', 't', 's', 's' }; 69 ostringstream os; 70 ostream_iterator<char> o(os,""); 71 slist<char> str(array+0, array + 6); 72 slist<char>::iterator i; 73 //Check const_iterator construction from iterator 74 slist<char>::const_iterator ci(i); 75 slist<char>::const_iterator ci2(ci); 76 // cout << "reversed: "; 77 str.reverse(); 78 for(i = str.begin(); i != str.end(); i++) 79 os << *i; 80 stringbuf* buff=os.rdbuf(); 81 string result=buff->str(); 82 CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstxlx")); 83 84 //cout << "removed: "; 85 str.remove('x'); 86 ostringstream os2; 87 for(i = str.begin(); i != str.end(); i++) 88 os2 << *i; 89 buff=os2.rdbuf(); 90 result=buff->str(); 91 CPPUNIT_ASSERT(!strcmp(result.c_str(),"sstl")); 92 93 94 //cout << "uniqued: "; 95 str.unique(); 96 ostringstream os3; 97 for(i = str.begin(); i != str.end(); i++) 98 os3 << *i; 99 buff=os3.rdbuf(); 100 result=buff->str(); 101 CPPUNIT_ASSERT(!strcmp(result.c_str(),"stl")); 102 103 //cout << "sorted: "; 104 str.sort(); 105 ostringstream os4; 106 for(i = str.begin(); i != str.end(); i++) 107 os4 << *i; 108 buff = os4.rdbuf(); 109 result = buff->str(); 110 CPPUNIT_ASSERT(!strcmp(result.c_str(),"lst")); 111 112 //A small compilation time check to be activated from time to time: 113 # if 0 114 { 115 slist<char>::iterator sl_char_ite; 116 slist<int>::iterator sl_int_ite; 117 CPPUNIT_ASSERT( sl_char_ite != sl_int_ite ); 118 } 119 # endif 120 #endif 121 } 122 123 void SlistTest::erase() 124 { 125 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 126 int array[] = { 0, 1, 2, 3, 4 }; 127 slist<int> sl(array, array + 5); 128 slist<int>::iterator slit; 129 130 slit = sl.erase(sl.begin()); 131 CPPUNIT_ASSERT( *slit == 1); 132 133 ++slit++; ++slit; 134 slit = sl.erase(sl.begin(), slit); 135 CPPUNIT_ASSERT( *slit == 3 ); 136 137 sl.assign(array, array + 5); 138 139 slit = sl.erase_after(sl.begin()); 140 CPPUNIT_ASSERT( *slit == 2 ); 141 142 slit = sl.begin(); ++slit; ++slit; 143 slit = sl.erase_after(sl.begin(), slit); 144 CPPUNIT_ASSERT( *slit == 3 ); 145 146 sl.erase_after(sl.before_begin()); 147 CPPUNIT_ASSERT( sl.front() == 3 ); 148 #endif 149 } 150 151 void SlistTest::insert() 152 { 153 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 154 int array[] = { 0, 1, 2, 3, 4 }; 155 156 //insert 157 { 158 slist<int> sl; 159 160 sl.insert(sl.begin(), 5); 161 CPPUNIT_ASSERT( sl.front() == 5 ); 162 CPPUNIT_ASSERT( sl.size() == 1 ); 163 164 //debug mode check: 165 //sl.insert(sl.before_begin(), array, array + 5); 166 167 sl.insert(sl.begin(), array, array + 5); 168 CPPUNIT_ASSERT( sl.size() == 6 ); 169 int i; 170 slist<int>::iterator slit(sl.begin()); 171 for (i = 0; slit != sl.end(); ++slit, ++i) { 172 CPPUNIT_ASSERT( *slit == i ); 173 } 174 } 175 176 //insert_after 177 { 178 slist<int> sl; 179 180 //debug check: 181 //sl.insert_after(sl.begin(), 5); 182 183 sl.insert_after(sl.before_begin(), 5); 184 CPPUNIT_ASSERT( sl.front() == 5 ); 185 CPPUNIT_ASSERT( sl.size() == 1 ); 186 187 sl.insert_after(sl.before_begin(), array, array + 5); 188 CPPUNIT_ASSERT( sl.size() == 6 ); 189 int i; 190 slist<int>::iterator slit(sl.begin()); 191 for (i = 0; slit != sl.end(); ++slit, ++i) { 192 CPPUNIT_ASSERT( *slit == i ); 193 } 194 } 195 #endif 196 } 197 198 void SlistTest::splice() 199 { 200 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 201 int array[] = { 0, 1, 2, 3, 4 }; 202 203 //splice 204 { 205 slist<int> sl1(array, array + 5); 206 slist<int> sl2(array, array + 5); 207 slist<int>::iterator slit; 208 209 //a no op: 210 sl1.splice(sl1.begin(), sl1, sl1.begin()); 211 CPPUNIT_ASSERT( sl1 == sl2 ); 212 213 slit = sl1.begin(); ++slit; 214 //a no op: 215 sl1.splice(slit, sl1, sl1.begin()); 216 CPPUNIT_ASSERT( sl1 == sl2 ); 217 218 sl1.splice(sl1.end(), sl1, sl1.begin()); 219 slit = sl1.begin(); 220 CPPUNIT_ASSERT( *(slit++) == 1 ); 221 CPPUNIT_ASSERT( *(slit++) == 2 ); 222 CPPUNIT_ASSERT( *(slit++) == 3 ); 223 CPPUNIT_ASSERT( *(slit++) == 4 ); 224 CPPUNIT_ASSERT( *slit == 0 ); 225 sl1.splice(sl1.begin(), sl1, slit); 226 CPPUNIT_ASSERT( sl1 == sl2 ); 227 228 sl1.splice(sl1.begin(), sl2); 229 size_t i; 230 for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) { 231 if (i == 5) i = 0; 232 CPPUNIT_ASSERT( *slit == array[i] ); 233 } 234 235 slit = sl1.begin(); 236 advance(slit, 5); 237 CPPUNIT_ASSERT( *slit == 0 ); 238 sl2.splice(sl2.begin(), sl1, sl1.begin(), slit); 239 CPPUNIT_ASSERT( sl1 == sl2 ); 240 241 slit = sl1.begin(); ++slit; 242 sl1.splice(sl1.begin(), sl1, slit, sl1.end()); 243 slit = sl1.begin(); 244 CPPUNIT_ASSERT( *(slit++) == 1 ); 245 CPPUNIT_ASSERT( *(slit++) == 2 ); 246 CPPUNIT_ASSERT( *(slit++) == 3 ); 247 CPPUNIT_ASSERT( *(slit++) == 4 ); 248 CPPUNIT_ASSERT( *slit == 0 ); 249 250 // a no op 251 sl2.splice(sl2.end(), sl2, sl2.begin(), sl2.end()); 252 for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) { 253 CPPUNIT_ASSERT( i < 5 ); 254 CPPUNIT_ASSERT( *slit == array[i] ); 255 } 256 257 slit = sl2.begin(); 258 advance(slit, 3); 259 sl2.splice(sl2.end(), sl2, sl2.begin(), slit); 260 slit = sl2.begin(); 261 CPPUNIT_ASSERT( *(slit++) == 3 ); 262 CPPUNIT_ASSERT( *(slit++) == 4 ); 263 CPPUNIT_ASSERT( *(slit++) == 0 ); 264 CPPUNIT_ASSERT( *(slit++) == 1 ); 265 CPPUNIT_ASSERT( *slit == 2 ); 266 } 267 268 //splice_after 269 { 270 slist<int> sl1(array, array + 5); 271 slist<int> sl2(array, array + 5); 272 slist<int>::iterator slit; 273 274 //a no op: 275 sl1.splice_after(sl1.begin(), sl1, sl1.begin()); 276 CPPUNIT_ASSERT( sl1 == sl2 ); 277 278 sl1.splice_after(sl1.before_begin(), sl1, sl1.begin()); 279 slit = sl1.begin(); 280 CPPUNIT_ASSERT( *(slit++) == 1 ); 281 CPPUNIT_ASSERT( *(slit++) == 0 ); 282 CPPUNIT_ASSERT( *(slit++) == 2 ); 283 CPPUNIT_ASSERT( *(slit++) == 3 ); 284 CPPUNIT_ASSERT( *slit == 4 ); 285 sl1.splice_after(sl1.before_begin(), sl1, sl1.begin()); 286 CPPUNIT_ASSERT( sl1 == sl2 ); 287 288 sl1.splice_after(sl1.before_begin(), sl2); 289 size_t i; 290 for (i = 0, slit = sl1.begin(); slit != sl1.end(); ++slit, ++i) { 291 if (i == 5) i = 0; 292 CPPUNIT_ASSERT( *slit == array[i] ); 293 } 294 295 slit = sl1.begin(); 296 advance(slit, 4); 297 CPPUNIT_ASSERT( *slit == 4 ); 298 sl2.splice_after(sl2.before_begin(), sl1, sl1.before_begin(), slit); 299 CPPUNIT_ASSERT( sl1 == sl2 ); 300 301 sl1.splice_after(sl1.before_begin(), sl1, sl1.begin(), sl1.previous(sl1.end())); 302 slit = sl1.begin(); 303 CPPUNIT_ASSERT( *(slit++) == 1 ); 304 CPPUNIT_ASSERT( *(slit++) == 2 ); 305 CPPUNIT_ASSERT( *(slit++) == 3 ); 306 CPPUNIT_ASSERT( *(slit++) == 4 ); 307 CPPUNIT_ASSERT( *slit == 0 ); 308 309 // a no op 310 sl2.splice_after(sl2.before_begin(), sl2, sl2.before_begin(), sl2.previous(sl2.end())); 311 for (i = 0, slit = sl2.begin(); slit != sl2.end(); ++slit, ++i) { 312 CPPUNIT_ASSERT( i < 5 ); 313 CPPUNIT_ASSERT( *slit == array[i] ); 314 } 315 316 slit = sl2.begin(); 317 advance(slit, 2); 318 sl2.splice_after(sl2.previous(sl2.end()), sl2, sl2.before_begin(), slit); 319 slit = sl2.begin(); 320 CPPUNIT_ASSERT( *(slit++) == 3 ); 321 CPPUNIT_ASSERT( *(slit++) == 4 ); 322 CPPUNIT_ASSERT( *(slit++) == 0 ); 323 CPPUNIT_ASSERT( *(slit++) == 1 ); 324 CPPUNIT_ASSERT( *slit == 2 ); 325 } 326 #endif 327 } 328 329 330 void SlistTest::allocator_with_state() 331 { 332 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) 333 char buf1[1024]; 334 StackAllocator<int> stack1(buf1, buf1 + sizeof(buf1)); 335 336 char buf2[1024]; 337 StackAllocator<int> stack2(buf2, buf2 + sizeof(buf2)); 338 339 typedef slist<int, StackAllocator<int> > SlistInt; 340 { 341 SlistInt slint1(10, 0, stack1); 342 SlistInt slint1Cpy(slint1); 343 344 SlistInt slint2(10, 1, stack2); 345 SlistInt slint2Cpy(slint2); 346 347 slint1.swap(slint2); 348 349 CPPUNIT_ASSERT( slint1.get_allocator().swaped() ); 350 CPPUNIT_ASSERT( slint2.get_allocator().swaped() ); 351 352 CPPUNIT_ASSERT( slint1 == slint2Cpy ); 353 CPPUNIT_ASSERT( slint2 == slint1Cpy ); 354 CPPUNIT_ASSERT( slint1.get_allocator() == stack2 ); 355 CPPUNIT_ASSERT( slint2.get_allocator() == stack1 ); 356 } 357 CPPUNIT_CHECK( stack1.ok() ); 358 CPPUNIT_CHECK( stack2.ok() ); 359 stack1.reset(); stack2.reset(); 360 361 { 362 SlistInt slint1(stack1); 363 SlistInt slint1Cpy(slint1); 364 365 SlistInt slint2(10, 1, stack2); 366 SlistInt slint2Cpy(slint2); 367 368 slint1.swap(slint2); 369 370 CPPUNIT_ASSERT( slint1.get_allocator().swaped() ); 371 CPPUNIT_ASSERT( slint2.get_allocator().swaped() ); 372 373 CPPUNIT_ASSERT( slint1 == slint2Cpy ); 374 CPPUNIT_ASSERT( slint2 == slint1Cpy ); 375 CPPUNIT_ASSERT( slint1.get_allocator() == stack2 ); 376 CPPUNIT_ASSERT( slint2.get_allocator() == stack1 ); 377 } 378 CPPUNIT_CHECK( stack1.ok() ); 379 CPPUNIT_CHECK( stack2.ok() ); 380 stack1.reset(); stack2.reset(); 381 382 { 383 SlistInt slint1(10, 0, stack1); 384 SlistInt slint1Cpy(slint1); 385 386 SlistInt slint2(stack2); 387 SlistInt slint2Cpy(slint2); 388 389 slint1.swap(slint2); 390 391 CPPUNIT_ASSERT( slint1.get_allocator().swaped() ); 392 CPPUNIT_ASSERT( slint2.get_allocator().swaped() ); 393 394 CPPUNIT_ASSERT( slint1 == slint2Cpy ); 395 CPPUNIT_ASSERT( slint2 == slint1Cpy ); 396 CPPUNIT_ASSERT( slint1.get_allocator() == stack2 ); 397 CPPUNIT_ASSERT( slint2.get_allocator() == stack1 ); 398 } 399 CPPUNIT_CHECK( stack1.ok() ); 400 CPPUNIT_CHECK( stack2.ok() ); 401 stack1.reset(); stack2.reset(); 402 403 //splice(iterator, slist) 404 { 405 SlistInt slint1(10, 0, stack1); 406 SlistInt slint2(10, 1, stack2); 407 408 slint1.splice(slint1.begin(), slint2); 409 CPPUNIT_ASSERT( slint1.size() == 20 ); 410 CPPUNIT_ASSERT( slint2.empty() ); 411 } 412 CPPUNIT_CHECK( stack1.ok() ); 413 CPPUNIT_CHECK( stack2.ok() ); 414 stack1.reset(); stack2.reset(); 415 416 //splice(iterator, slist, iterator) 417 { 418 SlistInt slint1(10, 0, stack1); 419 SlistInt slint2(10, 1, stack2); 420 421 slint1.splice(slint1.begin(), slint2, slint2.begin()); 422 CPPUNIT_ASSERT( slint1.size() == 11 ); 423 CPPUNIT_ASSERT( slint2.size() == 9 ); 424 } 425 CPPUNIT_CHECK( stack1.ok() ); 426 CPPUNIT_CHECK( stack2.ok() ); 427 stack1.reset(); stack2.reset(); 428 429 //splice(iterator, slist, iterator, iterator) 430 { 431 SlistInt slint1(10, 0, stack1); 432 SlistInt slint2(10, 1, stack2); 433 434 SlistInt::iterator lit(slint2.begin()); 435 advance(lit, 5); 436 slint1.splice(slint1.begin(), slint2, slint2.begin(), lit); 437 CPPUNIT_ASSERT( slint1.size() == 15 ); 438 CPPUNIT_ASSERT( slint2.size() == 5 ); 439 } 440 CPPUNIT_CHECK( stack1.ok() ); 441 CPPUNIT_CHECK( stack2.ok() ); 442 stack1.reset(); stack2.reset(); 443 444 //splice_after(iterator, slist) 445 { 446 SlistInt slint1(10, 0, stack1); 447 SlistInt slint2(10, 1, stack2); 448 449 slint1.splice_after(slint1.before_begin(), slint2); 450 CPPUNIT_ASSERT( slint1.size() == 20 ); 451 CPPUNIT_ASSERT( slint2.empty() ); 452 } 453 CPPUNIT_CHECK( stack1.ok() ); 454 CPPUNIT_CHECK( stack2.ok() ); 455 stack1.reset(); stack2.reset(); 456 457 //splice_after(iterator, slist, iterator) 458 { 459 SlistInt slint1(10, 0, stack1); 460 SlistInt slint2(10, 1, stack2); 461 462 slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin()); 463 CPPUNIT_ASSERT( slint1.size() == 11 ); 464 CPPUNIT_ASSERT( slint2.size() == 9 ); 465 } 466 CPPUNIT_CHECK( stack1.ok() ); 467 CPPUNIT_CHECK( stack2.ok() ); 468 stack1.reset(); stack2.reset(); 469 470 //splice_after(iterator, slist, iterator, iterator) 471 { 472 SlistInt slint1(10, 0, stack1); 473 SlistInt slint2(10, 1, stack2); 474 475 SlistInt::iterator lit(slint2.begin()); 476 advance(lit, 4); 477 slint1.splice_after(slint1.before_begin(), slint2, slint2.before_begin(), lit); 478 CPPUNIT_ASSERT( slint1.size() == 15 ); 479 CPPUNIT_ASSERT( slint2.size() == 5 ); 480 } 481 CPPUNIT_CHECK( stack1.ok() ); 482 CPPUNIT_CHECK( stack2.ok() ); 483 stack1.reset(); stack2.reset(); 484 485 //merge(slist) 486 { 487 SlistInt slint1(10, 0, stack1); 488 SlistInt slint2(10, 1, stack2); 489 490 SlistInt slintref(stack2); 491 slintref.insert_after(slintref.before_begin(), 10, 1); 492 slintref.insert_after(slintref.before_begin(), 10, 0); 493 494 slint1.merge(slint2); 495 CPPUNIT_ASSERT( slint1.size() == 20 ); 496 CPPUNIT_ASSERT( slint1 == slintref ); 497 CPPUNIT_ASSERT( slint2.empty() ); 498 } 499 CPPUNIT_CHECK( stack1.ok() ); 500 CPPUNIT_CHECK( stack2.ok() ); 501 502 //merge(slist, predicate) 503 # if (!defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)) && \ 504 (!defined (_MSC_VER) || (_MSC_VER >= 1300)) 505 { 506 SlistInt slint1(10, 0, stack1); 507 SlistInt slint2(10, 1, stack2); 508 509 SlistInt slintref(stack2); 510 slintref.insert_after(slintref.before_begin(), 10, 0); 511 slintref.insert_after(slintref.before_begin(), 10, 1); 512 513 slint1.merge(slint2, greater<int>()); 514 CPPUNIT_ASSERT( slint1.size() == 20 ); 515 CPPUNIT_ASSERT( slint1 == slintref ); 516 CPPUNIT_ASSERT( slint2.empty() ); 517 } 518 CPPUNIT_CHECK( stack1.ok() ); 519 CPPUNIT_CHECK( stack2.ok() ); 520 521 //sort 522 { 523 //This is rather a compile time test. 524 //We check that sort implementation is correct when list is instanciated 525 //with an allocator that do not have a default constructor. 526 SlistInt slint1(stack1); 527 slint1.push_front(1); 528 slint1.insert_after(slint1.before_begin(), 10, 0); 529 greater<int> gt; 530 slint1.sort(gt); 531 CPPUNIT_ASSERT( slint1.front() == 1 ); 532 slint1.sort(); 533 SlistInt::iterator slit(slint1.begin()); 534 advance(slit, 10); 535 CPPUNIT_ASSERT( *slit == 1 ); 536 } 537 # endif 538 #endif 539 } 540 541 #if defined (STLPORT) && !defined (_STLP_NO_EXTENSIONS) && \ 542 (!defined (_STLP_USE_PTR_SPECIALIZATIONS) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)) 543 # if !defined (__DMC__) 544 /* Simple compilation test: Check that nested types like iterator 545 * can be access even if type used to instanciate container is not 546 * yet completely defined. 547 */ 548 class IncompleteClass 549 { 550 slist<IncompleteClass> instances; 551 typedef slist<IncompleteClass>::iterator it; 552 }; 553 # endif 554 #endif 555