test_vector.cpp revision 2f8be091d59666a33e3fd11fca1ce71f0a90edbc
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include "../include/vector" 30#ifndef ANDROID_ASTL_VECTOR__ 31#error "Wrong header included!!" 32#endif 33#include <climits> 34#include <cstring> 35#include <string> 36#include "common.h" 37 38namespace android { 39using std::string; 40using std::vector; 41static const size_t kExponentialFactor = 2; 42bool testConstructorInt() 43{ 44 { 45 vector<int> vec1; 46 EXPECT_TRUE(vec1.empty()); 47 EXPECT_TRUE(vec1.size() == 0); 48 EXPECT_TRUE(vec1.capacity() == 0); 49 } 50 { 51 vector<int> vec2(100); 52 EXPECT_TRUE(!vec2.empty()); 53 EXPECT_TRUE(vec2.size() == 100); 54 EXPECT_TRUE(vec2.capacity() == 100); 55 for (size_t i = 0; i < 100; ++i) 56 { 57 EXPECT_TRUE(vec2[i] == 0); 58 } 59 } 60 { 61 vector<int> vec3(200, 0xaa); 62 EXPECT_TRUE(!vec3.empty()); 63 EXPECT_TRUE(vec3.size() == 200); 64 EXPECT_TRUE(vec3.capacity() == 200); 65 for (size_t i = 0; i < 200; ++i) 66 { 67 EXPECT_TRUE(vec3[i] == 0xaa); 68 } 69 } 70 return true; 71} 72 73bool testConstructorString() 74{ 75 { 76 vector<string> vec1; 77 EXPECT_TRUE(vec1.empty()); 78 EXPECT_TRUE(vec1.size() == 0); 79 EXPECT_TRUE(vec1.capacity() == 0); 80 } 81 return true; 82} 83 84typedef enum { ONE = 10, TWO} TestEnum; 85// These class allocate chunks to detect memory leaks. 86template<typename T> struct A { 87 public: 88 A() {mChunk = new T[2046];} 89 A(const A<T>& a) {mChunk = new T[2046];} 90 virtual ~A() {delete [] mChunk;} 91 T *mChunk; 92}; 93 94struct B { 95 public: 96 B() {mChunk = new char[2046];} 97 B(const B& b) {mChunk = new char[2046];} 98 virtual ~B() {delete [] mChunk;} 99 char *mChunk; 100}; 101 102bool testConstructorClass() 103{ 104 { 105 vector<B> vec1; 106 EXPECT_TRUE(vec1.empty()); 107 EXPECT_TRUE(vec1.size() == 0); 108 EXPECT_TRUE(vec1.capacity() == 0); 109 } 110 { 111 vector<B> vec1(100); 112 EXPECT_TRUE(!vec1.empty()); 113 EXPECT_TRUE(vec1.size() == 100); 114 EXPECT_TRUE(vec1.capacity() == 100); 115 } 116 return true; 117} 118 119bool testConstructorRepeat() 120{ 121 { 122 const vector<int> vec1(100, 10); 123 124 for (int i = 0; i < 100; ++i) 125 { 126 EXPECT_TRUE(vec1[i] == 10); 127 } 128 } 129 { 130 const vector<float> vec2(100, 10.0f); 131 132 for (int i = 0; i < 100; ++i) 133 { 134 EXPECT_TRUE(vec2[i] == 10.0f); 135 } 136 } 137 { 138 const vector<TestEnum> vec3(100, ONE); 139 140 for (int i = 0; i < 100; ++i) 141 { 142 EXPECT_TRUE(vec3[i] == ONE); 143 } 144 } 145 { 146 const vector< A<B> > vec4; 147 const vector< A<B> > vec5(10, A<B>()); 148 149 EXPECT_TRUE(vec4.size() == 0); 150 EXPECT_TRUE(vec5.size() == 10); 151 } 152 return true; 153} 154 155bool testConstructorIterator() 156{ 157 { 158 vector<string> src; 159 EXPECT_TRUE(src.empty()); 160 vector<string> dst(src.begin(), src.end()); 161 EXPECT_TRUE(dst.empty()); 162 } 163 { 164 vector<int> src; 165 EXPECT_TRUE(src.empty()); 166 vector<int> dst(src.begin(), src.end()); 167 EXPECT_TRUE(dst.empty()); 168 } 169 { 170 vector<int> src; 171 src.push_back(10); 172 src.push_back(20); 173 src.push_back(30); 174 vector<int> dst(src.begin(), src.end()); 175 EXPECT_TRUE(dst.size() == 3); 176 EXPECT_TRUE(dst[0] == 10); 177 EXPECT_TRUE(dst[1] == 20); 178 EXPECT_TRUE(dst[2] == 30); 179 } 180 { 181 vector<string> src; 182 src.push_back("str1"); 183 src.push_back("str2"); 184 src.push_back("str3"); 185 vector<string> dst(src.begin(), src.end()); 186 EXPECT_TRUE(dst.size() == 3); 187 EXPECT_TRUE(dst[0] == "str1"); 188 EXPECT_TRUE(dst[1] == "str2"); 189 EXPECT_TRUE(dst[2] == "str3"); 190 } 191 return true; 192} 193 194bool testReserve() 195{ 196 { // basic reserve + shrink. 197 vector<int> vec1(100, 10); 198 199 EXPECT_TRUE(vec1.capacity() == 100); 200 EXPECT_TRUE(vec1.reserve(200)); 201 EXPECT_TRUE(vec1.capacity() == 200); 202 EXPECT_TRUE(vec1.size() == 100); 203 204 EXPECT_TRUE(vec1.reserve()); 205 EXPECT_TRUE(vec1.capacity() == 100); 206 EXPECT_TRUE(vec1.size() == 100); 207 } 208 { 209 vector<int> vec2; 210 211 EXPECT_TRUE(vec2.capacity() == 0); 212 EXPECT_TRUE(vec2.reserve()); 213 EXPECT_TRUE(vec2.capacity() == 0); 214 215 vec2.reserve(200); 216 EXPECT_TRUE(vec2.capacity() == 200); 217 vec2.reserve(); 218 EXPECT_TRUE(vec2.capacity() == 0); 219 vec2.push_back(3); 220 vec2.reserve(); 221 EXPECT_TRUE(vec2.capacity() == 1); 222 } 223 { 224 vector<int> vec3; 225 226 vec3.push_back(5); 227 vec3.reserve(); 228 EXPECT_TRUE(vec3.capacity() == 1); 229 vec3.push_back(3); 230 EXPECT_TRUE(vec3.capacity() == kExponentialFactor); 231 while (vec3.size() < kExponentialFactor) 232 vec3.push_back(3); 233 234 EXPECT_TRUE(vec3.size() == kExponentialFactor); 235 EXPECT_TRUE(vec3.capacity() == kExponentialFactor); 236 237 // exp increment. 238 vec3.push_back(10); 239 EXPECT_TRUE(vec3.capacity() == kExponentialFactor * kExponentialFactor); 240 } 241 { 242 CopyCounter c; 243 244 c.mCount = 0; 245 vector<CopyCounter> vec4(100, c); 246 EXPECT_TRUE(c.mCount == 100); 247 // Growing does not do any copy via the copy assignement op. 248 vec4.reserve(1000); 249 EXPECT_TRUE(c.mCount == 200); 250 vec4.reserve(50); // reserving less than length is a nop. 251 EXPECT_TRUE(c.mCount == 200); 252 } 253 { 254 vector<unsigned short> vec5; 255 256 EXPECT_TRUE(!vec5.reserve(vec5.max_size() + 1)); 257 EXPECT_TRUE(vec5.capacity() == 0); 258 } 259 return true; 260} 261 262 263bool testPushBack() 264{ 265 { 266 vector<CtorDtorCounter> vec1; 267 CtorDtorCounter c; 268 269 c.reset(); 270 for (int i = 0; i < 1000; ++i) 271 { 272 vec1.push_back(c); 273 } 274 EXPECT_TRUE(vec1.capacity() == 1024); 275 EXPECT_TRUE(vec1.size() == 1000); 276 // Assignment should not be used, but the constructor should. 277 EXPECT_TRUE(c.mAssignCount == 0); 278 // Copy constructor was been invoked for each new element 279 // pushed and when the capacity was increased. 280 EXPECT_TRUE(c.mCopyCtorCount > 1000); 281 EXPECT_TRUE(c.mCtorCount == 0); 282 } 283 { 284 vector<int> vec2; 285 286 vec2.push_back(10); 287 EXPECT_TRUE(vec2.front() == 10); 288 EXPECT_TRUE(vec2.back() == 10); 289 EXPECT_TRUE(vec2.size() == 1); 290 vec2.push_back(20); 291 EXPECT_TRUE(vec2.front() == 10); 292 EXPECT_TRUE(vec2.back() == 20); 293 EXPECT_TRUE(vec2.size() == 2); 294 } 295 // Push back an non-pod object. 296 { 297 string str = "a string"; 298 vector<string> vec3; 299 300 vec3.push_back(str); 301 EXPECT_TRUE(vec3.size() == 1); 302 EXPECT_TRUE(vec3.front() == "a string"); 303 EXPECT_TRUE(vec3.back() == "a string"); 304 } 305 return true; 306} 307 308 309bool testPopBack() 310{ 311 vector<int> vec1(10, 0xdeadbeef);; 312 313 EXPECT_TRUE(vec1.capacity() == 10); 314 EXPECT_TRUE(vec1.size() == 10); 315 316 for(size_t i = 10; i > 0; --i) 317 { 318 EXPECT_TRUE(vec1.capacity() == 10); 319 EXPECT_TRUE(vec1.size() == i); 320 vec1.pop_back(); 321 } 322 EXPECT_TRUE(vec1.empty()); 323 EXPECT_TRUE(vec1.begin() == vec1.end()); 324 vec1.pop_back(); // pop_back on empty vector 325 EXPECT_TRUE(vec1.size() == 0); 326 EXPECT_TRUE(vec1.capacity() == 10); 327 328 vec1.clear(); 329 vec1.pop_back(); // pop_back on empty vector 330 EXPECT_TRUE(vec1.size() == 0); 331 EXPECT_TRUE(vec1.capacity() == 0); 332 EXPECT_TRUE(vec1.begin() == vec1.end()); 333 EXPECT_TRUE(vec1.begin().base() == NULL); 334 335 CtorDtorCounter instance; 336 vector<CtorDtorCounter> vec2(10, instance); 337 338 CtorDtorCounter::reset(); 339 for (int i = 0; i < 10; ++i) 340 { 341 vec2.pop_back(); 342 } 343 EXPECT_TRUE(vec2.size() == 0); 344 EXPECT_TRUE(CtorDtorCounter::mDtorCount == 10); 345 return true; 346} 347 348 349bool testResize() 350{ 351 { 352 vector<int> vec1(10, 0xdeadbeef); 353 vec1.resize(0); 354 EXPECT_TRUE(vec1.capacity() == 10); 355 vec1.resize(5); 356 EXPECT_TRUE(vec1.capacity() == 10); 357 vec1.resize(10); 358 EXPECT_TRUE(vec1.capacity() == 10); 359 vec1.resize(11); 360 EXPECT_TRUE(vec1.capacity() == 11); 361 vec1.resize(100); 362 EXPECT_TRUE(vec1.capacity() == 100); 363 vec1.resize(10); 364 EXPECT_TRUE(vec1.capacity() == 100); 365 } 366 { 367 vector<B> vec1(10); 368 vec1.resize(0); 369 EXPECT_TRUE(vec1.capacity() == 10); 370 vec1.resize(5); 371 EXPECT_TRUE(vec1.capacity() == 10); 372 vec1.resize(10); 373 EXPECT_TRUE(vec1.capacity() == 10); 374 vec1.resize(11); 375 EXPECT_TRUE(vec1.capacity() == 11); 376 vec1.resize(100); 377 EXPECT_TRUE(vec1.capacity() == 100); 378 vec1.resize(10); 379 EXPECT_TRUE(vec1.capacity() == 100); 380 } 381 { 382 vector<CtorDtorCounter> vec; 383 CtorDtorCounter::reset(); 384 vec.resize(10); 385 EXPECT_TRUE(CtorDtorCounter::mCtorCount == 1); // default arg. 386 EXPECT_TRUE(CtorDtorCounter::mCopyCtorCount == 10); // copied 10 times. 387 388 CtorDtorCounter::reset(); 389 vec.resize(200); 390 EXPECT_TRUE(CtorDtorCounter::mCtorCount == 1); // default arg. 391 EXPECT_TRUE(CtorDtorCounter::mCopyCtorCount == 200); 392 393 CtorDtorCounter::reset(); 394 vec.resize(199); 395 // the copy constructor should have been called once and the 396 // destructor twice (1 temp + 1 elt). 397 EXPECT_TRUE(CtorDtorCounter::mCtorCount == 1); // default arg. 398 EXPECT_TRUE(CtorDtorCounter::mDtorCount == 2); 399 400 CtorDtorCounter::reset(); 401 vec.resize(0); 402 // the copy constructor should have been called once and the 403 // destructor twice (1 temp + 199 elts). 404 EXPECT_TRUE(CtorDtorCounter::mCtorCount == 1); // default arg. 405 EXPECT_TRUE(CtorDtorCounter::mDtorCount == 200); 406 } 407 return true; 408} 409 410bool testSwap() 411{ 412 vector<int> vec1(100, 10); 413 vector<int> vec2; 414 415 vec1.swap(vec2); 416 417 EXPECT_TRUE(vec1.capacity() == 0); 418 EXPECT_TRUE(vec2.capacity() == 100); 419 420 EXPECT_TRUE(vec1.size() == 0); 421 EXPECT_TRUE(vec2.size() == 100); 422 423 EXPECT_TRUE(vec1.begin() == vec1.end()); 424 EXPECT_TRUE(vec2.begin() != vec2.end()); 425 return true; 426} 427 428 429bool testIterators() 430{ 431 vector<int> vec1(10); 432 433 for (size_t i = 0; i < 10; ++i) 434 { 435 vec1[i] = i; 436 } 437 438 vector<int>::iterator i = vec1.begin(); 439 for (int c = 0; i != vec1.end(); ++i, ++c) 440 { 441 EXPECT_TRUE(c == *i); 442 } 443 444 vector<int>::const_iterator j = vec1.begin(); 445 for (int c = 0; j != vec1.end(); ++j, ++c) 446 { 447 EXPECT_TRUE(c == *j); 448 } 449 450 { 451 const vector<int> vec1(100, 10); 452 453 EXPECT_TRUE(vec1.end().operator-(100) == vec1.begin()); 454 EXPECT_TRUE(vec1.end() - 100 == vec1.begin()); 455 456 EXPECT_TRUE(100 + vec1.begin() == vec1.end()); 457 EXPECT_TRUE(vec1.begin() + 100 == vec1.end()); 458 459 EXPECT_TRUE(vec1.end() - vec1.begin() == 100); 460 EXPECT_TRUE(std::distance(vec1.begin(), vec1.end()) == 100); 461 EXPECT_TRUE(std::distance(vec1.end(), vec1.begin()) == -100); 462 463 for (vector<int>::const_iterator i = vec1.begin(); 464 i != vec1.end(); ++i) { 465 EXPECT_TRUE(*i == 10); 466 } 467 } 468 469 { 470 const vector<int> vec2; 471 EXPECT_TRUE(vec2.begin() == vec2.end()); 472 } 473 return true; 474} 475 476bool testCtorDtorForNonPod() 477{ 478 { // empty vector, no construction should happen. 479 CtorDtorCounter::reset(); 480 vector<CtorDtorCounter> vec1; 481 482 EXPECT_TRUE(CtorDtorCounter::mCtorCount == 0); 483 EXPECT_TRUE(CtorDtorCounter::mCopyCtorCount == 0); 484 } 485 EXPECT_TRUE(CtorDtorCounter::mDtorCount == 0); 486 487 { 488 CtorDtorCounter instance; 489 EXPECT_TRUE(CtorDtorCounter::mCtorCount == 1); 490 CtorDtorCounter::reset(); 491 492 vector<CtorDtorCounter> vec2(200, instance); 493 494 // 200 copies by assignement of the sample instance 495 EXPECT_TRUE(CtorDtorCounter::mAssignCount == 0); 496 EXPECT_TRUE(CtorDtorCounter::mCtorCount == 0); 497 EXPECT_TRUE(CtorDtorCounter::mCopyCtorCount == 200); 498 EXPECT_TRUE(CtorDtorCounter::mDtorCount == 0); 499 500 CtorDtorCounter::reset(); 501 vec2.reserve(400); 502 503 // 200 moves: 200 copies by copy constructor and 200 destructions. 504 EXPECT_TRUE(CtorDtorCounter::mCopyCtorCount == 200); 505 EXPECT_TRUE(CtorDtorCounter::mDtorCount == 200); 506 EXPECT_TRUE(CtorDtorCounter::mCtorCount == 0); 507 EXPECT_TRUE(CtorDtorCounter::mAssignCount == 0); 508 509 CtorDtorCounter::reset(); 510 } 511 // 200 + 1 for the instance 512 EXPECT_TRUE(CtorDtorCounter::mDtorCount == 201); 513 return true; 514} 515} // namespace android 516 517int main(int argc, char **argv) 518{ 519 FAIL_UNLESS(testConstructorInt); 520 FAIL_UNLESS(testConstructorString); 521 FAIL_UNLESS(testConstructorClass); 522 523 FAIL_UNLESS(testConstructorRepeat); 524 FAIL_UNLESS(testConstructorIterator); 525 FAIL_UNLESS(testReserve); 526 FAIL_UNLESS(testPushBack); 527 FAIL_UNLESS(testPopBack); 528 FAIL_UNLESS(testResize); 529#if(0) 530 FAIL_UNLESS(testSwap); 531 FAIL_UNLESS(testIterators); 532 FAIL_UNLESS(testCtorDtorForNonPod); 533#endif 534 return kPassed; 535} 536