OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_CONTAINERS_STACK_CONTAINER_H_ | 5 #ifndef BASE_CONTAINERS_STACK_CONTAINER_H_ |
6 #define BASE_CONTAINERS_STACK_CONTAINER_H_ | 6 #define BASE_CONTAINERS_STACK_CONTAINER_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 | 9 |
10 #include <string> | |
11 #include <vector> | 10 #include <vector> |
12 | 11 |
13 #include "base/macros.h" | 12 #include "base/macros.h" |
14 #include "base/memory/aligned_memory.h" | 13 #include "base/memory/aligned_memory.h" |
15 #include "base/strings/string16.h" | |
16 #include "build/build_config.h" | 14 #include "build/build_config.h" |
17 | 15 |
18 namespace base { | 16 namespace base { |
19 | 17 |
20 // This allocator can be used with STL containers to provide a stack buffer | 18 // This allocator can be used with STL containers to provide a stack buffer |
21 // from which to allocate memory and overflows onto the heap. This stack buffer | 19 // from which to allocate memory and overflows onto the heap. This stack buffer |
22 // would be allocated on the stack and allows us to avoid heap operations in | 20 // would be allocated on the stack and allows us to avoid heap operations in |
23 // some situations. | 21 // some situations. |
24 // | 22 // |
25 // STL likes to make copies of allocators, so the allocator itself can't hold | 23 // STL likes to make copies of allocators, so the allocator itself can't hold |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 | 124 |
127 private: | 125 private: |
128 Source* source_; | 126 Source* source_; |
129 }; | 127 }; |
130 | 128 |
131 // A wrapper around STL containers that maintains a stack-sized buffer that the | 129 // A wrapper around STL containers that maintains a stack-sized buffer that the |
132 // initial capacity of the vector is based on. Growing the container beyond the | 130 // initial capacity of the vector is based on. Growing the container beyond the |
133 // stack capacity will transparently overflow onto the heap. The container must | 131 // stack capacity will transparently overflow onto the heap. The container must |
134 // support reserve(). | 132 // support reserve(). |
135 // | 133 // |
| 134 // This will not work with std::string since some implementations allocate |
| 135 // more bytes than requested in calls to reserve(), forcing the allocation onto |
| 136 // the heap. http://crbug.com/709273 |
| 137 // |
136 // WATCH OUT: the ContainerType MUST use the proper StackAllocator for this | 138 // WATCH OUT: the ContainerType MUST use the proper StackAllocator for this |
137 // type. This object is really intended to be used only internally. You'll want | 139 // type. This object is really intended to be used only internally. You'll want |
138 // to use the wrappers below for different types. | 140 // to use the wrappers below for different types. |
139 template<typename TContainerType, int stack_capacity> | 141 template<typename TContainerType, int stack_capacity> |
140 class StackContainer { | 142 class StackContainer { |
141 public: | 143 public: |
142 typedef TContainerType ContainerType; | 144 typedef TContainerType ContainerType; |
143 typedef typename ContainerType::value_type ContainedType; | 145 typedef typename ContainerType::value_type ContainedType; |
144 typedef StackAllocator<ContainedType, stack_capacity> Allocator; | 146 typedef StackAllocator<ContainedType, stack_capacity> Allocator; |
145 | 147 |
(...skipping 29 matching lines...) Expand all Loading... |
175 | 177 |
176 protected: | 178 protected: |
177 typename Allocator::Source stack_data_; | 179 typename Allocator::Source stack_data_; |
178 Allocator allocator_; | 180 Allocator allocator_; |
179 ContainerType container_; | 181 ContainerType container_; |
180 | 182 |
181 private: | 183 private: |
182 DISALLOW_COPY_AND_ASSIGN(StackContainer); | 184 DISALLOW_COPY_AND_ASSIGN(StackContainer); |
183 }; | 185 }; |
184 | 186 |
185 // StackString ----------------------------------------------------------------- | |
186 | |
187 template<size_t stack_capacity> | |
188 class StackString : public StackContainer< | |
189 std::basic_string<char, | |
190 std::char_traits<char>, | |
191 StackAllocator<char, stack_capacity> >, | |
192 stack_capacity> { | |
193 public: | |
194 StackString() : StackContainer< | |
195 std::basic_string<char, | |
196 std::char_traits<char>, | |
197 StackAllocator<char, stack_capacity> >, | |
198 stack_capacity>() { | |
199 } | |
200 | |
201 private: | |
202 DISALLOW_COPY_AND_ASSIGN(StackString); | |
203 }; | |
204 | |
205 // StackStrin16 ---------------------------------------------------------------- | |
206 | |
207 template<size_t stack_capacity> | |
208 class StackString16 : public StackContainer< | |
209 std::basic_string<char16, | |
210 base::string16_char_traits, | |
211 StackAllocator<char16, stack_capacity> >, | |
212 stack_capacity> { | |
213 public: | |
214 StackString16() : StackContainer< | |
215 std::basic_string<char16, | |
216 base::string16_char_traits, | |
217 StackAllocator<char16, stack_capacity> >, | |
218 stack_capacity>() { | |
219 } | |
220 | |
221 private: | |
222 DISALLOW_COPY_AND_ASSIGN(StackString16); | |
223 }; | |
224 | |
225 // StackVector ----------------------------------------------------------------- | 187 // StackVector ----------------------------------------------------------------- |
226 | 188 |
227 // Example: | 189 // Example: |
228 // StackVector<int, 16> foo; | 190 // StackVector<int, 16> foo; |
229 // foo->push_back(22); // we have overloaded operator-> | 191 // foo->push_back(22); // we have overloaded operator-> |
230 // foo[0] = 10; // as well as operator[] | 192 // foo[0] = 10; // as well as operator[] |
231 template<typename T, size_t stack_capacity> | 193 template<typename T, size_t stack_capacity> |
232 class StackVector : public StackContainer< | 194 class StackVector : public StackContainer< |
233 std::vector<T, StackAllocator<T, stack_capacity> >, | 195 std::vector<T, StackAllocator<T, stack_capacity> >, |
234 stack_capacity> { | 196 stack_capacity> { |
(...skipping 24 matching lines...) Expand all Loading... |
259 // operator-> (using "->at()" does exception stuff we don't want). | 221 // operator-> (using "->at()" does exception stuff we don't want). |
260 T& operator[](size_t i) { return this->container().operator[](i); } | 222 T& operator[](size_t i) { return this->container().operator[](i); } |
261 const T& operator[](size_t i) const { | 223 const T& operator[](size_t i) const { |
262 return this->container().operator[](i); | 224 return this->container().operator[](i); |
263 } | 225 } |
264 }; | 226 }; |
265 | 227 |
266 } // namespace base | 228 } // namespace base |
267 | 229 |
268 #endif // BASE_CONTAINERS_STACK_CONTAINER_H_ | 230 #endif // BASE_CONTAINERS_STACK_CONTAINER_H_ |
OLD | NEW |