1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/stack_container.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "base/ref_counted.h"
14 class Dummy
: public base::RefCounted
<Dummy
> {
16 explicit Dummy(int* alive
) : alive_(alive
) {
21 friend class base::RefCounted
<Dummy
>;
32 TEST(StackContainer
, Vector
) {
33 const int stack_size
= 3;
34 StackVector
<int, stack_size
> vect
;
35 const int* stack_buffer
= &vect
.stack_data().stack_buffer()[0];
37 // The initial |stack_size| elements should appear in the stack buffer.
38 EXPECT_EQ(static_cast<size_t>(stack_size
), vect
.container().capacity());
39 for (int i
= 0; i
< stack_size
; i
++) {
40 vect
.container().push_back(i
);
41 EXPECT_EQ(stack_buffer
, &vect
.container()[0]);
42 EXPECT_TRUE(vect
.stack_data().used_stack_buffer_
);
45 // Adding more elements should push the array onto the heap.
46 for (int i
= 0; i
< stack_size
; i
++) {
47 vect
.container().push_back(i
+ stack_size
);
48 EXPECT_NE(stack_buffer
, &vect
.container()[0]);
49 EXPECT_FALSE(vect
.stack_data().used_stack_buffer_
);
52 // The array should still be in order.
53 for (int i
= 0; i
< stack_size
* 2; i
++)
54 EXPECT_EQ(i
, vect
.container()[i
]);
56 // Resize to smaller. Our STL implementation won't reallocate in this case,
57 // otherwise it might use our stack buffer. We reserve right after the resize
58 // to guarantee it isn't using the stack buffer, even though it doesn't have
60 vect
.container().resize(stack_size
);
61 vect
.container().reserve(stack_size
* 2);
62 EXPECT_FALSE(vect
.stack_data().used_stack_buffer_
);
64 // Copying the small vector to another should use the same allocator and use
65 // the now-unused stack buffer. GENERALLY CALLERS SHOULD NOT DO THIS since
66 // they have to get the template types just right and it can cause errors.
67 std::vector
<int, StackAllocator
<int, stack_size
> > other(vect
.container());
68 EXPECT_EQ(stack_buffer
, &other
.front());
69 EXPECT_TRUE(vect
.stack_data().used_stack_buffer_
);
70 for (int i
= 0; i
< stack_size
; i
++)
71 EXPECT_EQ(i
, other
[i
]);
74 TEST(StackContainer
, VectorDoubleDelete
) {
75 // Regression testing for double-delete.
76 typedef StackVector
<scoped_refptr
<Dummy
>, 2> Vector
;
77 typedef Vector::ContainerType Container
;
81 scoped_refptr
<Dummy
> dummy(new Dummy(&alive
));
84 vect
->push_back(dummy
);
87 Dummy
* dummy_unref
= dummy
.get();
91 Container::iterator itr
= std::find(vect
->begin(), vect
->end(), dummy_unref
);
92 EXPECT_EQ(itr
->get(), dummy_unref
);
96 // Shouldn't crash at exit.
99 TEST(StackContainer
, BufferAlignment
) {
100 StackVector
<wchar_t, 16> text
;
101 text
->push_back(L
'A');
102 text
->push_back(L
'B');
103 text
->push_back(L
'C');
104 text
->push_back(L
'D');
105 text
->push_back(L
'E');
106 text
->push_back(L
'F');
109 const wchar_t* buffer
= &text
[1];
110 bool even_aligned
= (0 == (((size_t)buffer
) & 0x1));
111 EXPECT_EQ(even_aligned
, true);
115 // Make sure all the class compiles correctly.
116 // TODO(pinkerton): i'm not sure why this doesn't compile on GCC, but
118 template StackVector
<int, 2>;
119 template StackVector
<scoped_refptr
<Dummy
>, 2>;