| 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 |