OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 CC_BASE_LIST_CONTAINER_H_ | 5 #ifndef CC_BASE_LIST_CONTAINER_H_ |
6 #define CC_BASE_LIST_CONTAINER_H_ | 6 #define CC_BASE_LIST_CONTAINER_H_ |
7 | 7 |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "cc/base/cc_export.h" | 11 #include "cc/base/cc_export.h" |
| 12 #include "cc/base/list_container_helper.h" |
12 | 13 |
13 namespace cc { | 14 namespace cc { |
14 | 15 |
15 // ListContainer is a container type that handles allocating contiguous memory | 16 // ListContainer is a container type that handles allocating contiguous memory |
16 // for new elements and traversing through elements with either iterator or | 17 // for new elements and traversing through elements with either iterator or |
17 // reverse iterator. Since this container hands out raw pointers of its | 18 // reverse iterator. Since this container hands out raw pointers of its |
18 // elements, it is very important that this container never reallocate its | 19 // elements, it is very important that this container never reallocate its |
19 // memory so those raw pointer will continue to be valid. This class is used to | 20 // memory so those raw pointer will continue to be valid. This class is used to |
20 // contain SharedQuadState or DrawQuad. Since the size of each DrawQuad varies, | 21 // contain SharedQuadState or DrawQuad. Since the size of each DrawQuad varies, |
21 // to hold DrawQuads, the allocations size of each element in this class is | 22 // to hold DrawQuads, the allocations size of each element in this class is |
22 // LargestDrawQuadSize while BaseElementType is DrawQuad. | 23 // LargestDrawQuadSize while BaseElementType is DrawQuad. |
23 | |
24 // Base class for non-templated logic. All methods are protected, and only | |
25 // exposed by ListContainer<BaseElementType>. | |
26 // For usage, see comments in ListContainer. | |
27 class CC_EXPORT ListContainerBase { | |
28 protected: | |
29 explicit ListContainerBase(size_t max_size_for_derived_class); | |
30 ListContainerBase(size_t max_size_for_derived_class, | |
31 size_t num_of_elements_to_reserve_for); | |
32 ~ListContainerBase(); | |
33 | |
34 // This class deals only with char* and void*. It does allocation and passing | |
35 // out raw pointers, as well as memory deallocation when being destroyed. | |
36 class ListContainerCharAllocator; | |
37 | |
38 // This class points to a certain position inside memory of | |
39 // ListContainerCharAllocator. It is a base class for ListContainer iterators. | |
40 struct CC_EXPORT PositionInListContainerCharAllocator { | |
41 ListContainerCharAllocator* ptr_to_container; | |
42 size_t vector_index; | |
43 char* item_iterator; | |
44 | |
45 PositionInListContainerCharAllocator( | |
46 const PositionInListContainerCharAllocator& other); | |
47 | |
48 PositionInListContainerCharAllocator(ListContainerCharAllocator* container, | |
49 size_t vector_ind, | |
50 char* item_iter); | |
51 | |
52 bool operator==(const PositionInListContainerCharAllocator& other) const; | |
53 bool operator!=(const PositionInListContainerCharAllocator& other) const; | |
54 | |
55 PositionInListContainerCharAllocator Increment(); | |
56 PositionInListContainerCharAllocator ReverseIncrement(); | |
57 }; | |
58 | |
59 // Iterator classes that can be used to access data. | |
60 ///////////////////////////////////////////////////////////////// | |
61 class CC_EXPORT Iterator : public PositionInListContainerCharAllocator { | |
62 // This class is only defined to forward iterate through | |
63 // ListContainerCharAllocator. | |
64 public: | |
65 Iterator(ListContainerCharAllocator* container, | |
66 size_t vector_ind, | |
67 char* item_iter, | |
68 size_t index); | |
69 ~Iterator(); | |
70 | |
71 size_t index() const; | |
72 | |
73 protected: | |
74 // This is used to track how many increment has happened since begin(). It | |
75 // is used to avoid double increment at places an index reference is | |
76 // needed. For iterator this means begin() corresponds to index 0 and end() | |
77 // corresponds to index |size|. | |
78 size_t index_; | |
79 }; | |
80 | |
81 class CC_EXPORT ConstIterator : public PositionInListContainerCharAllocator { | |
82 // This class is only defined to forward iterate through | |
83 // ListContainerCharAllocator. | |
84 public: | |
85 ConstIterator(ListContainerCharAllocator* container, | |
86 size_t vector_ind, | |
87 char* item_iter, | |
88 size_t index); | |
89 ConstIterator(const Iterator& other); // NOLINT | |
90 ~ConstIterator(); | |
91 | |
92 size_t index() const; | |
93 | |
94 protected: | |
95 // This is used to track how many increment has happened since begin(). It | |
96 // is used to avoid double increment at places an index reference is | |
97 // needed. For iterator this means begin() corresponds to index 0 and end() | |
98 // corresponds to index |size|. | |
99 size_t index_; | |
100 }; | |
101 | |
102 class CC_EXPORT ReverseIterator | |
103 : public PositionInListContainerCharAllocator { | |
104 // This class is only defined to reverse iterate through | |
105 // ListContainerCharAllocator. | |
106 public: | |
107 ReverseIterator(ListContainerCharAllocator* container, | |
108 size_t vector_ind, | |
109 char* item_iter, | |
110 size_t index); | |
111 ~ReverseIterator(); | |
112 | |
113 size_t index() const; | |
114 | |
115 protected: | |
116 // This is used to track how many increment has happened since rbegin(). It | |
117 // is used to avoid double increment at places an index reference is | |
118 // needed. For reverse iterator this means rbegin() corresponds to index 0 | |
119 // and rend() corresponds to index |size|. | |
120 size_t index_; | |
121 }; | |
122 | |
123 class CC_EXPORT ConstReverseIterator | |
124 : public PositionInListContainerCharAllocator { | |
125 // This class is only defined to reverse iterate through | |
126 // ListContainerCharAllocator. | |
127 public: | |
128 ConstReverseIterator(ListContainerCharAllocator* container, | |
129 size_t vector_ind, | |
130 char* item_iter, | |
131 size_t index); | |
132 ConstReverseIterator(const ReverseIterator& other); // NOLINT | |
133 ~ConstReverseIterator(); | |
134 | |
135 size_t index() const; | |
136 | |
137 protected: | |
138 // This is used to track how many increment has happened since rbegin(). It | |
139 // is used to avoid double increment at places an index reference is | |
140 // needed. For reverse iterator this means rbegin() corresponds to index 0 | |
141 // and rend() corresponds to index |size|. | |
142 size_t index_; | |
143 }; | |
144 | |
145 // Unlike the ListContainer methods, these do not invoke element destructors. | |
146 void RemoveLast(); | |
147 void EraseAndInvalidateAllPointers(Iterator* position); | |
148 void InsertBeforeAndInvalidateAllPointers(Iterator* position, | |
149 size_t number_of_elements); | |
150 | |
151 ConstReverseIterator crbegin() const; | |
152 ConstReverseIterator crend() const; | |
153 ReverseIterator rbegin(); | |
154 ReverseIterator rend(); | |
155 ConstIterator cbegin() const; | |
156 ConstIterator cend() const; | |
157 Iterator begin(); | |
158 Iterator end(); | |
159 | |
160 Iterator IteratorAt(size_t index); | |
161 ConstIterator IteratorAt(size_t index) const; | |
162 | |
163 size_t size() const; | |
164 bool empty() const; | |
165 | |
166 size_t MaxSizeForDerivedClass() const; | |
167 | |
168 size_t GetCapacityInBytes() const; | |
169 | |
170 // Unlike the ListContainer method, this one does not invoke element | |
171 // destructors. | |
172 void clear(); | |
173 | |
174 size_t AvailableSizeWithoutAnotherAllocationForTesting() const; | |
175 | |
176 // Hands out memory location for an element at the end of data structure. | |
177 void* Allocate(size_t size_of_actual_element_in_bytes); | |
178 | |
179 scoped_ptr<ListContainerCharAllocator> data_; | |
180 | |
181 private: | |
182 DISALLOW_COPY_AND_ASSIGN(ListContainerBase); | |
183 }; | |
184 | |
185 template <class BaseElementType> | 24 template <class BaseElementType> |
186 class ListContainer : public ListContainerBase { | 25 class ListContainer { |
187 public: | 26 public: |
188 // BaseElementType is the type of raw pointers this class hands out; however, | 27 // BaseElementType is the type of raw pointers this class hands out; however, |
189 // its derived classes might require different memory sizes. | 28 // its derived classes might require different memory sizes. |
190 // max_size_for_derived_class the largest memory size required for all the | 29 // max_size_for_derived_class the largest memory size required for all the |
191 // derived classes to use for allocation. | 30 // derived classes to use for allocation. |
192 explicit ListContainer(size_t max_size_for_derived_class) | 31 explicit ListContainer(size_t max_size_for_derived_class) |
193 : ListContainerBase(max_size_for_derived_class) {} | 32 : helper_(max_size_for_derived_class) {} |
194 | 33 |
195 // This constructor omits input variable for max_size_for_derived_class. This | 34 // This constructor omits input variable for max_size_for_derived_class. This |
196 // is used when there is no derived classes from BaseElementType we need to | 35 // is used when there is no derived classes from BaseElementType we need to |
197 // worry about, and allocation size is just sizeof(BaseElementType). | 36 // worry about, and allocation size is just sizeof(BaseElementType). |
198 ListContainer() : ListContainerBase(sizeof(BaseElementType)) {} | 37 ListContainer() : helper_(sizeof(BaseElementType)) {} |
199 | 38 |
200 // This constructor reserves the requested memory up front so only single | 39 // This constructor reserves the requested memory up front so only single |
201 // allocation is needed. When num_of_elements_to_reserve_for is zero, use the | 40 // allocation is needed. When num_of_elements_to_reserve_for is zero, use the |
202 // default size. | 41 // default size. |
203 ListContainer(size_t max_size_for_derived_class, | 42 ListContainer(size_t max_size_for_derived_class, |
204 size_t num_of_elements_to_reserve_for) | 43 size_t num_of_elements_to_reserve_for) |
205 : ListContainerBase(max_size_for_derived_class, | 44 : helper_(max_size_for_derived_class, num_of_elements_to_reserve_for) {} |
206 num_of_elements_to_reserve_for) {} | |
207 | 45 |
208 ~ListContainer() { | 46 ~ListContainer() { |
209 for (Iterator i = begin(); i != end(); ++i) { | 47 for (Iterator i = begin(); i != end(); ++i) { |
210 i->~BaseElementType(); | 48 i->~BaseElementType(); |
211 } | 49 } |
212 } | 50 } |
213 | 51 |
214 class Iterator; | 52 class Iterator; |
215 class ConstIterator; | 53 class ConstIterator; |
216 class ReverseIterator; | 54 class ReverseIterator; |
217 class ConstReverseIterator; | 55 class ConstReverseIterator; |
218 | 56 |
219 // Removes the last element of the list and makes its space available for | 57 // Removes the last element of the list and makes its space available for |
220 // allocation. | 58 // allocation. |
221 void RemoveLast() { | 59 void RemoveLast() { |
222 DCHECK(!empty()); | 60 DCHECK(!empty()); |
223 back()->~BaseElementType(); | 61 back()->~BaseElementType(); |
224 ListContainerBase::RemoveLast(); | 62 helper_.RemoveLast(); |
225 } | 63 } |
226 | 64 |
227 // When called, all raw pointers that have been handed out are no longer | 65 // When called, all raw pointers that have been handed out are no longer |
228 // valid. Use with caution. | 66 // valid. Use with caution. |
229 // Returns a valid Iterator pointing to the element after the erased element. | 67 // Returns a valid Iterator pointing to the element after the erased element. |
230 // This function does not deallocate memory. | 68 // This function does not deallocate memory. |
231 Iterator EraseAndInvalidateAllPointers(Iterator position) { | 69 Iterator EraseAndInvalidateAllPointers(Iterator position) { |
232 BaseElementType* item = *position; | 70 BaseElementType* item = *position; |
233 item->~BaseElementType(); | 71 item->~BaseElementType(); |
234 ListContainerBase::EraseAndInvalidateAllPointers(&position); | 72 helper_.EraseAndInvalidateAllPointers(&position); |
235 return empty() ? end() : position; | 73 return empty() ? end() : position; |
236 } | 74 } |
237 | 75 |
238 ConstReverseIterator crbegin() const { | 76 ConstReverseIterator crbegin() const { |
239 return ConstReverseIterator(ListContainerBase::crbegin()); | 77 return ConstReverseIterator(helper_.crbegin()); |
240 } | 78 } |
241 ConstReverseIterator crend() const { | 79 ConstReverseIterator crend() const { |
242 return ConstReverseIterator(ListContainerBase::crend()); | 80 return ConstReverseIterator(helper_.crend()); |
243 } | 81 } |
244 ConstReverseIterator rbegin() const { return crbegin(); } | 82 ConstReverseIterator rbegin() const { return crbegin(); } |
245 ConstReverseIterator rend() const { return crend(); } | 83 ConstReverseIterator rend() const { return crend(); } |
246 ReverseIterator rbegin() { | 84 ReverseIterator rbegin() { return ReverseIterator(helper_.rbegin()); } |
247 return ReverseIterator(ListContainerBase::rbegin()); | 85 ReverseIterator rend() { return ReverseIterator(helper_.rend()); } |
248 } | 86 ConstIterator cbegin() const { return ConstIterator(helper_.cbegin()); } |
249 ReverseIterator rend() { return ReverseIterator(ListContainerBase::rend()); } | 87 ConstIterator cend() const { return ConstIterator(helper_.cend()); } |
250 ConstIterator cbegin() const { | |
251 return ConstIterator(ListContainerBase::cbegin()); | |
252 } | |
253 ConstIterator cend() const { | |
254 return ConstIterator(ListContainerBase::cend()); | |
255 } | |
256 ConstIterator begin() const { return cbegin(); } | 88 ConstIterator begin() const { return cbegin(); } |
257 ConstIterator end() const { return cend(); } | 89 ConstIterator end() const { return cend(); } |
258 Iterator begin() { return Iterator(ListContainerBase::begin()); } | 90 Iterator begin() { return Iterator(helper_.begin()); } |
259 Iterator end() { return Iterator(ListContainerBase::end()); } | 91 Iterator end() { return Iterator(helper_.end()); } |
260 | 92 |
261 // TODO(weiliangc): front(), back() and ElementAt() function should return | 93 // TODO(weiliangc): front(), back() and ElementAt() function should return |
262 // reference, consistent with container-of-object. | 94 // reference, consistent with container-of-object. |
263 BaseElementType* front() { return *begin(); } | 95 BaseElementType* front() { return *begin(); } |
264 BaseElementType* back() { return *rbegin(); } | 96 BaseElementType* back() { return *rbegin(); } |
265 const BaseElementType* front() const { return *begin(); } | 97 const BaseElementType* front() const { return *begin(); } |
266 const BaseElementType* back() const { return *rbegin(); } | 98 const BaseElementType* back() const { return *rbegin(); } |
267 | 99 |
268 BaseElementType* ElementAt(size_t index) { | 100 BaseElementType* ElementAt(size_t index) { |
269 return *Iterator(IteratorAt(index)); | 101 return *Iterator(helper_.IteratorAt(index)); |
270 } | 102 } |
271 const BaseElementType* ElementAt(size_t index) const { | 103 const BaseElementType* ElementAt(size_t index) const { |
272 return *ConstIterator(IteratorAt(index)); | 104 return *ConstIterator(helper_.IteratorAt(index)); |
273 } | 105 } |
274 | 106 |
275 // Take in derived element type and construct it at location generated by | 107 // Take in derived element type and construct it at location generated by |
276 // Allocate(). | 108 // Allocate(). |
277 template <typename DerivedElementType> | 109 template <typename DerivedElementType> |
278 DerivedElementType* AllocateAndConstruct() { | 110 DerivedElementType* AllocateAndConstruct() { |
279 return new (Allocate(sizeof(DerivedElementType))) DerivedElementType; | 111 return new (helper_.Allocate(sizeof(DerivedElementType))) |
| 112 DerivedElementType; |
280 } | 113 } |
281 | 114 |
282 // Take in derived element type and copy construct it at location generated by | 115 // Take in derived element type and copy construct it at location generated by |
283 // Allocate(). | 116 // Allocate(). |
284 template <typename DerivedElementType> | 117 template <typename DerivedElementType> |
285 DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) { | 118 DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) { |
286 return new (Allocate(sizeof(DerivedElementType))) | 119 return new (helper_.Allocate(sizeof(DerivedElementType))) |
287 DerivedElementType(*source); | 120 DerivedElementType(*source); |
288 } | 121 } |
289 | 122 |
290 // Construct a new element on top of an existing one. | 123 // Construct a new element on top of an existing one. |
291 template <typename DerivedElementType> | 124 template <typename DerivedElementType> |
292 DerivedElementType* ReplaceExistingElement(Iterator at) { | 125 DerivedElementType* ReplaceExistingElement(Iterator at) { |
293 at->~BaseElementType(); | 126 at->~BaseElementType(); |
294 return new (*at) DerivedElementType(); | 127 return new (*at) DerivedElementType(); |
295 } | 128 } |
296 | 129 |
297 // Insert |count| new elements of |DerivedElementType| before |at|. This will | 130 // Insert |count| new elements of |DerivedElementType| before |at|. This will |
298 // invalidate all outstanding pointers and iterators. Return a valid iterator | 131 // invalidate all outstanding pointers and iterators. Return a valid iterator |
299 // for the beginning of the newly inserted segment. | 132 // for the beginning of the newly inserted segment. |
300 template <typename DerivedElementType> | 133 template <typename DerivedElementType> |
301 Iterator InsertBeforeAndInvalidateAllPointers(Iterator at, size_t count) { | 134 Iterator InsertBeforeAndInvalidateAllPointers(Iterator at, size_t count) { |
302 ListContainerBase::InsertBeforeAndInvalidateAllPointers(&at, count); | 135 helper_.InsertBeforeAndInvalidateAllPointers(&at, count); |
303 Iterator result = at; | 136 Iterator result = at; |
304 for (size_t i = 0; i < count; ++i) { | 137 for (size_t i = 0; i < count; ++i) { |
305 new (*at) DerivedElementType(); | 138 new (*at) DerivedElementType(); |
306 ++at; | 139 ++at; |
307 } | 140 } |
308 return result; | 141 return result; |
309 } | 142 } |
310 | 143 |
311 template <typename DerivedElementType> | 144 template <typename DerivedElementType> |
312 void swap(ListContainer<DerivedElementType>& other) { | 145 void swap(ListContainer<DerivedElementType>& other) { |
313 data_.swap(other.data_); | 146 helper_.data_.swap(other.helper_.data_); |
314 } | 147 } |
315 | 148 |
316 // Appends a new item without copying. The original item will not be | 149 // Appends a new item without copying. The original item will not be |
317 // destructed and will be replaced with a new DerivedElementType. The | 150 // destructed and will be replaced with a new DerivedElementType. The |
318 // DerivedElementType does not have to match the moved type as a full block | 151 // DerivedElementType does not have to match the moved type as a full block |
319 // of memory will be moved (up to MaxSizeForDerivedClass()). A pointer to | 152 // of memory will be moved (up to MaxSizeForDerivedClass()). A pointer to |
320 // the moved element is returned. | 153 // the moved element is returned. |
321 template <typename DerivedElementType> | 154 template <typename DerivedElementType> |
322 DerivedElementType* AppendByMoving(DerivedElementType* item) { | 155 DerivedElementType* AppendByMoving(DerivedElementType* item) { |
323 size_t max_size_for_derived_class = MaxSizeForDerivedClass(); | 156 size_t max_size_for_derived_class = helper_.MaxSizeForDerivedClass(); |
324 void* new_item = Allocate(max_size_for_derived_class); | 157 void* new_item = helper_.Allocate(max_size_for_derived_class); |
325 memcpy(new_item, static_cast<void*>(item), max_size_for_derived_class); | 158 memcpy(new_item, static_cast<void*>(item), max_size_for_derived_class); |
326 // Construct a new element in-place so it can be destructed safely. | 159 // Construct a new element in-place so it can be destructed safely. |
327 new (item) DerivedElementType; | 160 new (item) DerivedElementType; |
328 return static_cast<DerivedElementType*>(new_item); | 161 return static_cast<DerivedElementType*>(new_item); |
329 } | 162 } |
330 | 163 |
331 using ListContainerBase::size; | 164 size_t size() const { return helper_.size(); } |
332 using ListContainerBase::empty; | 165 bool empty() const { return helper_.empty(); } |
333 using ListContainerBase::GetCapacityInBytes; | 166 size_t GetCapacityInBytes() const { return helper_.GetCapacityInBytes(); } |
334 | 167 |
335 void clear() { | 168 void clear() { |
336 for (Iterator i = begin(); i != end(); ++i) { | 169 for (Iterator i = begin(); i != end(); ++i) { |
337 i->~BaseElementType(); | 170 i->~BaseElementType(); |
338 } | 171 } |
339 ListContainerBase::clear(); | 172 helper_.clear(); |
340 } | 173 } |
341 | 174 |
342 using ListContainerBase::AvailableSizeWithoutAnotherAllocationForTesting; | 175 size_t AvailableSizeWithoutAnotherAllocationForTesting() const { |
| 176 return helper_.AvailableSizeWithoutAnotherAllocationForTesting(); |
| 177 } |
343 | 178 |
344 // Iterator classes that can be used to access data. | 179 // Iterator classes that can be used to access data. |
345 ///////////////////////////////////////////////////////////////// | 180 ///////////////////////////////////////////////////////////////// |
346 class Iterator : public ListContainerBase::Iterator { | 181 class Iterator : public ListContainerHelper::Iterator { |
347 // This class is only defined to forward iterate through | 182 // This class is only defined to forward iterate through |
348 // ListContainerCharAllocator. | 183 // CharAllocator. |
349 public: | 184 public: |
350 Iterator(ListContainerCharAllocator* container, | 185 Iterator(ListContainerHelper::CharAllocator* container, |
351 size_t vector_ind, | 186 size_t vector_ind, |
352 char* item_iter, | 187 char* item_iter, |
353 size_t index) | 188 size_t index) |
354 : ListContainerBase::Iterator(container, vector_ind, item_iter, index) { | 189 : ListContainerHelper::Iterator(container, |
355 } | 190 vector_ind, |
| 191 item_iter, |
| 192 index) {} |
356 BaseElementType* operator->() const { | 193 BaseElementType* operator->() const { |
357 return reinterpret_cast<BaseElementType*>(item_iterator); | 194 return reinterpret_cast<BaseElementType*>(item_iterator); |
358 } | 195 } |
359 BaseElementType* operator*() const { | 196 BaseElementType* operator*() const { |
360 return reinterpret_cast<BaseElementType*>(item_iterator); | 197 return reinterpret_cast<BaseElementType*>(item_iterator); |
361 } | 198 } |
362 Iterator operator++(int unused_post_increment) { | 199 Iterator operator++(int unused_post_increment) { |
363 Iterator tmp = *this; | 200 Iterator tmp = *this; |
364 operator++(); | 201 operator++(); |
365 return tmp; | 202 return tmp; |
366 } | 203 } |
367 Iterator& operator++() { | 204 Iterator& operator++() { |
368 Increment(); | 205 Increment(); |
369 ++index_; | 206 ++index_; |
370 return *this; | 207 return *this; |
371 } | 208 } |
372 | 209 |
373 private: | 210 private: |
374 explicit Iterator(const ListContainerBase::Iterator& base_iterator) | 211 explicit Iterator(const ListContainerHelper::Iterator& base_iterator) |
375 : ListContainerBase::Iterator(base_iterator) {} | 212 : ListContainerHelper::Iterator(base_iterator) {} |
376 friend Iterator ListContainer<BaseElementType>::begin(); | 213 friend Iterator ListContainer<BaseElementType>::begin(); |
377 friend Iterator ListContainer<BaseElementType>::end(); | 214 friend Iterator ListContainer<BaseElementType>::end(); |
378 friend BaseElementType* ListContainer<BaseElementType>::ElementAt( | 215 friend BaseElementType* ListContainer<BaseElementType>::ElementAt( |
379 size_t index); | 216 size_t index); |
380 }; | 217 }; |
381 | 218 |
382 class ConstIterator : public ListContainerBase::ConstIterator { | 219 class ConstIterator : public ListContainerHelper::ConstIterator { |
383 // This class is only defined to forward iterate through | 220 // This class is only defined to forward iterate through |
384 // ListContainerCharAllocator. | 221 // CharAllocator. |
385 public: | 222 public: |
386 ConstIterator(ListContainerCharAllocator* container, | 223 ConstIterator(ListContainerHelper::CharAllocator* container, |
387 size_t vector_ind, | 224 size_t vector_ind, |
388 char* item_iter, | 225 char* item_iter, |
389 size_t index) | 226 size_t index) |
390 : ListContainerBase::ConstIterator(container, | 227 : ListContainerHelper::ConstIterator(container, |
391 vector_ind, | 228 vector_ind, |
392 item_iter, | 229 item_iter, |
393 index) {} | 230 index) {} |
394 ConstIterator(const Iterator& other) // NOLINT | 231 ConstIterator(const Iterator& other) // NOLINT |
395 : ListContainerBase::ConstIterator(other) {} | 232 : ListContainerHelper::ConstIterator(other) {} |
396 const BaseElementType* operator->() const { | 233 const BaseElementType* operator->() const { |
397 return reinterpret_cast<const BaseElementType*>(item_iterator); | 234 return reinterpret_cast<const BaseElementType*>(item_iterator); |
398 } | 235 } |
399 const BaseElementType* operator*() const { | 236 const BaseElementType* operator*() const { |
400 return reinterpret_cast<const BaseElementType*>(item_iterator); | 237 return reinterpret_cast<const BaseElementType*>(item_iterator); |
401 } | 238 } |
402 ConstIterator operator++(int unused_post_increment) { | 239 ConstIterator operator++(int unused_post_increment) { |
403 ConstIterator tmp = *this; | 240 ConstIterator tmp = *this; |
404 operator++(); | 241 operator++(); |
405 return tmp; | 242 return tmp; |
406 } | 243 } |
407 ConstIterator& operator++() { | 244 ConstIterator& operator++() { |
408 Increment(); | 245 Increment(); |
409 ++index_; | 246 ++index_; |
410 return *this; | 247 return *this; |
411 } | 248 } |
412 | 249 |
413 private: | 250 private: |
414 explicit ConstIterator( | 251 explicit ConstIterator( |
415 const ListContainerBase::ConstIterator& base_iterator) | 252 const ListContainerHelper::ConstIterator& base_iterator) |
416 : ListContainerBase::ConstIterator(base_iterator) {} | 253 : ListContainerHelper::ConstIterator(base_iterator) {} |
417 friend ConstIterator ListContainer<BaseElementType>::cbegin() const; | 254 friend ConstIterator ListContainer<BaseElementType>::cbegin() const; |
418 friend ConstIterator ListContainer<BaseElementType>::cend() const; | 255 friend ConstIterator ListContainer<BaseElementType>::cend() const; |
419 friend const BaseElementType* ListContainer<BaseElementType>::ElementAt( | 256 friend const BaseElementType* ListContainer<BaseElementType>::ElementAt( |
420 size_t index) const; | 257 size_t index) const; |
421 }; | 258 }; |
422 | 259 |
423 class ReverseIterator : public ListContainerBase::ReverseIterator { | 260 class ReverseIterator : public ListContainerHelper::ReverseIterator { |
424 // This class is only defined to reverse iterate through | 261 // This class is only defined to reverse iterate through |
425 // ListContainerCharAllocator. | 262 // CharAllocator. |
426 public: | 263 public: |
427 ReverseIterator(ListContainerCharAllocator* container, | 264 ReverseIterator(ListContainerHelper::CharAllocator* container, |
428 size_t vector_ind, | 265 size_t vector_ind, |
429 char* item_iter, | 266 char* item_iter, |
430 size_t index) | 267 size_t index) |
431 : ListContainerBase::ReverseIterator(container, | 268 : ListContainerHelper::ReverseIterator(container, |
432 vector_ind, | 269 vector_ind, |
433 item_iter, | 270 item_iter, |
434 index) {} | 271 index) {} |
435 BaseElementType* operator->() const { | 272 BaseElementType* operator->() const { |
436 return reinterpret_cast<BaseElementType*>(item_iterator); | 273 return reinterpret_cast<BaseElementType*>(item_iterator); |
437 } | 274 } |
438 BaseElementType* operator*() const { | 275 BaseElementType* operator*() const { |
439 return reinterpret_cast<BaseElementType*>(item_iterator); | 276 return reinterpret_cast<BaseElementType*>(item_iterator); |
440 } | 277 } |
441 ReverseIterator operator++(int unused_post_increment) { | 278 ReverseIterator operator++(int unused_post_increment) { |
442 ReverseIterator tmp = *this; | 279 ReverseIterator tmp = *this; |
443 operator++(); | 280 operator++(); |
444 return tmp; | 281 return tmp; |
445 } | 282 } |
446 ReverseIterator& operator++() { | 283 ReverseIterator& operator++() { |
447 ReverseIncrement(); | 284 ReverseIncrement(); |
448 ++index_; | 285 ++index_; |
449 return *this; | 286 return *this; |
450 } | 287 } |
451 | 288 |
452 private: | 289 private: |
453 explicit ReverseIterator(ListContainerBase::ReverseIterator base_iterator) | 290 explicit ReverseIterator(ListContainerHelper::ReverseIterator base_iterator) |
454 : ListContainerBase::ReverseIterator(base_iterator) {} | 291 : ListContainerHelper::ReverseIterator(base_iterator) {} |
455 friend ReverseIterator ListContainer<BaseElementType>::rbegin(); | 292 friend ReverseIterator ListContainer<BaseElementType>::rbegin(); |
456 friend ReverseIterator ListContainer<BaseElementType>::rend(); | 293 friend ReverseIterator ListContainer<BaseElementType>::rend(); |
457 }; | 294 }; |
458 | 295 |
459 class ConstReverseIterator : public ListContainerBase::ConstReverseIterator { | 296 class ConstReverseIterator |
| 297 : public ListContainerHelper::ConstReverseIterator { |
460 // This class is only defined to reverse iterate through | 298 // This class is only defined to reverse iterate through |
461 // ListContainerCharAllocator. | 299 // CharAllocator. |
462 public: | 300 public: |
463 ConstReverseIterator(ListContainerCharAllocator* container, | 301 ConstReverseIterator(ListContainerHelper::CharAllocator* container, |
464 size_t vector_ind, | 302 size_t vector_ind, |
465 char* item_iter, | 303 char* item_iter, |
466 size_t index) | 304 size_t index) |
467 : ListContainerBase::ConstReverseIterator(container, | 305 : ListContainerHelper::ConstReverseIterator(container, |
468 vector_ind, | 306 vector_ind, |
469 item_iter, | 307 item_iter, |
470 index) {} | 308 index) {} |
471 ConstReverseIterator(const ReverseIterator& other) // NOLINT | 309 ConstReverseIterator(const ReverseIterator& other) // NOLINT |
472 : ListContainerBase::ConstReverseIterator(other) {} | 310 : ListContainerHelper::ConstReverseIterator(other) {} |
473 const BaseElementType* operator->() const { | 311 const BaseElementType* operator->() const { |
474 return reinterpret_cast<const BaseElementType*>(item_iterator); | 312 return reinterpret_cast<const BaseElementType*>(item_iterator); |
475 } | 313 } |
476 const BaseElementType* operator*() const { | 314 const BaseElementType* operator*() const { |
477 return reinterpret_cast<const BaseElementType*>(item_iterator); | 315 return reinterpret_cast<const BaseElementType*>(item_iterator); |
478 } | 316 } |
479 ConstReverseIterator operator++(int unused_post_increment) { | 317 ConstReverseIterator operator++(int unused_post_increment) { |
480 ConstReverseIterator tmp = *this; | 318 ConstReverseIterator tmp = *this; |
481 operator++(); | 319 operator++(); |
482 return tmp; | 320 return tmp; |
483 } | 321 } |
484 ConstReverseIterator& operator++() { | 322 ConstReverseIterator& operator++() { |
485 ReverseIncrement(); | 323 ReverseIncrement(); |
486 ++index_; | 324 ++index_; |
487 return *this; | 325 return *this; |
488 } | 326 } |
489 | 327 |
490 private: | 328 private: |
491 explicit ConstReverseIterator( | 329 explicit ConstReverseIterator( |
492 ListContainerBase::ConstReverseIterator base_iterator) | 330 ListContainerHelper::ConstReverseIterator base_iterator) |
493 : ListContainerBase::ConstReverseIterator(base_iterator) {} | 331 : ListContainerHelper::ConstReverseIterator(base_iterator) {} |
494 friend ConstReverseIterator ListContainer<BaseElementType>::crbegin() const; | 332 friend ConstReverseIterator ListContainer<BaseElementType>::crbegin() const; |
495 friend ConstReverseIterator ListContainer<BaseElementType>::crend() const; | 333 friend ConstReverseIterator ListContainer<BaseElementType>::crend() const; |
496 }; | 334 }; |
| 335 |
| 336 private: |
| 337 ListContainerHelper helper_; |
| 338 |
| 339 DISALLOW_COPY_AND_ASSIGN(ListContainer); |
497 }; | 340 }; |
498 | 341 |
499 } // namespace cc | 342 } // namespace cc |
500 | 343 |
501 #endif // CC_BASE_LIST_CONTAINER_H_ | 344 #endif // CC_BASE_LIST_CONTAINER_H_ |
OLD | NEW |