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