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 | 12 |
13 namespace cc { | 13 namespace cc { |
14 | 14 |
15 // ListContainer is a container type that handles allocating contiguous memory | 15 // ListContainer is a container type that handles allocating contiguous memory |
16 // for new elements and traversing through elements with either iterator or | 16 // for new elements and traversing through elements with either iterator or |
17 // reverse iterator. Since this container hands out raw pointers of its | 17 // reverse iterator. Since this container hands out raw pointers of its |
18 // elements, it is very important that this container never reallocate its | 18 // 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 | 19 // 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, | 20 // 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 | 21 // to hold DrawQuads, the allocations size of each element in this class is |
22 // LargestDrawQuadSize while BaseElementType is DrawQuad. | 22 // LargestDrawQuadSize while BaseElementType is DrawQuad. |
23 | 23 |
24 // Base class for non-templated logic. All methods are protected, and only | 24 // Helper class for non-templated logic. All methods are private, and only |
25 // exposed by ListContainer<BaseElementType>. | 25 // exposed to friend classes. |
26 // For usage, see comments in ListContainer. | 26 // For usage, see comments in ListContainer. |
27 class CC_EXPORT ListContainerBase { | 27 class CC_EXPORT ListContainerHelper { |
28 protected: | 28 private: |
29 explicit ListContainerBase(size_t max_size_for_derived_class); | 29 template <typename T> |
30 ListContainerBase(size_t max_size_for_derived_class, | 30 friend class CC_EXPORT ListContainer; |
weiliangc
2015/09/14 19:57:13
I'm kinda torn on the friend idea. Maybe stop CC_E
vmpstr
2015/09/14 20:05:07
I'm not really sure. Wouldn't that still allow any
| |
31 size_t num_of_elements_to_reserve_for); | 31 |
32 ~ListContainerBase(); | 32 explicit ListContainerHelper(size_t max_size_for_derived_class); |
33 ListContainerHelper(size_t max_size_for_derived_class, | |
34 size_t num_of_elements_to_reserve_for); | |
35 ~ListContainerHelper(); | |
33 | 36 |
34 // This class deals only with char* and void*. It does allocation and passing | 37 // 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. | 38 // out raw pointers, as well as memory deallocation when being destroyed. |
36 class ListContainerCharAllocator; | 39 class ListContainerCharAllocator; |
37 | 40 |
38 // This class points to a certain position inside memory of | 41 // This class points to a certain position inside memory of |
39 // ListContainerCharAllocator. It is a base class for ListContainer iterators. | 42 // ListContainerCharAllocator. It is a base class for ListContainer iterators. |
40 struct CC_EXPORT PositionInListContainerCharAllocator { | 43 struct CC_EXPORT PositionInListContainerCharAllocator { |
41 ListContainerCharAllocator* ptr_to_container; | 44 ListContainerCharAllocator* ptr_to_container; |
42 size_t vector_index; | 45 size_t vector_index; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 // destructors. | 174 // destructors. |
172 void clear(); | 175 void clear(); |
173 | 176 |
174 size_t AvailableSizeWithoutAnotherAllocationForTesting() const; | 177 size_t AvailableSizeWithoutAnotherAllocationForTesting() const; |
175 | 178 |
176 // Hands out memory location for an element at the end of data structure. | 179 // Hands out memory location for an element at the end of data structure. |
177 void* Allocate(size_t size_of_actual_element_in_bytes); | 180 void* Allocate(size_t size_of_actual_element_in_bytes); |
178 | 181 |
179 scoped_ptr<ListContainerCharAllocator> data_; | 182 scoped_ptr<ListContainerCharAllocator> data_; |
180 | 183 |
181 private: | 184 DISALLOW_COPY_AND_ASSIGN(ListContainerHelper); |
182 DISALLOW_COPY_AND_ASSIGN(ListContainerBase); | |
183 }; | 185 }; |
184 | 186 |
185 template <class BaseElementType> | 187 template <class BaseElementType> |
186 class ListContainer : public ListContainerBase { | 188 class CC_EXPORT ListContainer { |
187 public: | 189 public: |
188 // BaseElementType is the type of raw pointers this class hands out; however, | 190 // BaseElementType is the type of raw pointers this class hands out; however, |
189 // its derived classes might require different memory sizes. | 191 // its derived classes might require different memory sizes. |
190 // max_size_for_derived_class the largest memory size required for all the | 192 // max_size_for_derived_class the largest memory size required for all the |
191 // derived classes to use for allocation. | 193 // derived classes to use for allocation. |
192 explicit ListContainer(size_t max_size_for_derived_class) | 194 explicit ListContainer(size_t max_size_for_derived_class) |
193 : ListContainerBase(max_size_for_derived_class) {} | 195 : helper_(max_size_for_derived_class) {} |
194 | 196 |
195 // This constructor omits input variable for max_size_for_derived_class. This | 197 // 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 | 198 // is used when there is no derived classes from BaseElementType we need to |
197 // worry about, and allocation size is just sizeof(BaseElementType). | 199 // worry about, and allocation size is just sizeof(BaseElementType). |
198 ListContainer() : ListContainerBase(sizeof(BaseElementType)) {} | 200 ListContainer() : helper_(sizeof(BaseElementType)) {} |
199 | 201 |
200 // This constructor reserves the requested memory up front so only single | 202 // 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 | 203 // allocation is needed. When num_of_elements_to_reserve_for is zero, use the |
202 // default size. | 204 // default size. |
203 ListContainer(size_t max_size_for_derived_class, | 205 ListContainer(size_t max_size_for_derived_class, |
204 size_t num_of_elements_to_reserve_for) | 206 size_t num_of_elements_to_reserve_for) |
205 : ListContainerBase(max_size_for_derived_class, | 207 : helper_(max_size_for_derived_class, num_of_elements_to_reserve_for) {} |
206 num_of_elements_to_reserve_for) {} | |
207 | 208 |
208 ~ListContainer() { | 209 ~ListContainer() { |
209 for (Iterator i = begin(); i != end(); ++i) { | 210 for (Iterator i = begin(); i != end(); ++i) { |
210 i->~BaseElementType(); | 211 i->~BaseElementType(); |
211 } | 212 } |
212 } | 213 } |
213 | 214 |
214 class Iterator; | 215 class Iterator; |
215 class ConstIterator; | 216 class ConstIterator; |
216 class ReverseIterator; | 217 class ReverseIterator; |
217 class ConstReverseIterator; | 218 class ConstReverseIterator; |
218 | 219 |
219 // Removes the last element of the list and makes its space available for | 220 // Removes the last element of the list and makes its space available for |
220 // allocation. | 221 // allocation. |
221 void RemoveLast() { | 222 void RemoveLast() { |
222 DCHECK(!empty()); | 223 DCHECK(!empty()); |
223 back()->~BaseElementType(); | 224 back()->~BaseElementType(); |
224 ListContainerBase::RemoveLast(); | 225 helper_.RemoveLast(); |
225 } | 226 } |
226 | 227 |
227 // When called, all raw pointers that have been handed out are no longer | 228 // When called, all raw pointers that have been handed out are no longer |
228 // valid. Use with caution. | 229 // valid. Use with caution. |
229 // Returns a valid Iterator pointing to the element after the erased element. | 230 // Returns a valid Iterator pointing to the element after the erased element. |
230 // This function does not deallocate memory. | 231 // This function does not deallocate memory. |
231 Iterator EraseAndInvalidateAllPointers(Iterator position) { | 232 Iterator EraseAndInvalidateAllPointers(Iterator position) { |
232 BaseElementType* item = *position; | 233 BaseElementType* item = *position; |
233 item->~BaseElementType(); | 234 item->~BaseElementType(); |
234 ListContainerBase::EraseAndInvalidateAllPointers(&position); | 235 helper_.EraseAndInvalidateAllPointers(&position); |
235 return empty() ? end() : position; | 236 return empty() ? end() : position; |
236 } | 237 } |
237 | 238 |
238 ConstReverseIterator crbegin() const { | 239 ConstReverseIterator crbegin() const { |
239 return ConstReverseIterator(ListContainerBase::crbegin()); | 240 return ConstReverseIterator(helper_.crbegin()); |
240 } | 241 } |
241 ConstReverseIterator crend() const { | 242 ConstReverseIterator crend() const { |
242 return ConstReverseIterator(ListContainerBase::crend()); | 243 return ConstReverseIterator(helper_.crend()); |
243 } | 244 } |
244 ConstReverseIterator rbegin() const { return crbegin(); } | 245 ConstReverseIterator rbegin() const { return crbegin(); } |
245 ConstReverseIterator rend() const { return crend(); } | 246 ConstReverseIterator rend() const { return crend(); } |
246 ReverseIterator rbegin() { | 247 ReverseIterator rbegin() { return ReverseIterator(helper_.rbegin()); } |
247 return ReverseIterator(ListContainerBase::rbegin()); | 248 ReverseIterator rend() { return ReverseIterator(helper_.rend()); } |
248 } | 249 ConstIterator cbegin() const { return ConstIterator(helper_.cbegin()); } |
249 ReverseIterator rend() { return ReverseIterator(ListContainerBase::rend()); } | 250 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(); } | 251 ConstIterator begin() const { return cbegin(); } |
257 ConstIterator end() const { return cend(); } | 252 ConstIterator end() const { return cend(); } |
258 Iterator begin() { return Iterator(ListContainerBase::begin()); } | 253 Iterator begin() { return Iterator(helper_.begin()); } |
259 Iterator end() { return Iterator(ListContainerBase::end()); } | 254 Iterator end() { return Iterator(helper_.end()); } |
260 | 255 |
261 // TODO(weiliangc): front(), back() and ElementAt() function should return | 256 // TODO(weiliangc): front(), back() and ElementAt() function should return |
262 // reference, consistent with container-of-object. | 257 // reference, consistent with container-of-object. |
263 BaseElementType* front() { return *begin(); } | 258 BaseElementType* front() { return *begin(); } |
264 BaseElementType* back() { return *rbegin(); } | 259 BaseElementType* back() { return *rbegin(); } |
265 const BaseElementType* front() const { return *begin(); } | 260 const BaseElementType* front() const { return *begin(); } |
266 const BaseElementType* back() const { return *rbegin(); } | 261 const BaseElementType* back() const { return *rbegin(); } |
267 | 262 |
268 BaseElementType* ElementAt(size_t index) { | 263 BaseElementType* ElementAt(size_t index) { |
269 return *Iterator(IteratorAt(index)); | 264 return *Iterator(helper_.IteratorAt(index)); |
270 } | 265 } |
271 const BaseElementType* ElementAt(size_t index) const { | 266 const BaseElementType* ElementAt(size_t index) const { |
272 return *ConstIterator(IteratorAt(index)); | 267 return *ConstIterator(helper_.IteratorAt(index)); |
273 } | 268 } |
274 | 269 |
275 // Take in derived element type and construct it at location generated by | 270 // Take in derived element type and construct it at location generated by |
276 // Allocate(). | 271 // Allocate(). |
277 template <typename DerivedElementType> | 272 template <typename DerivedElementType> |
278 DerivedElementType* AllocateAndConstruct() { | 273 DerivedElementType* AllocateAndConstruct() { |
279 return new (Allocate(sizeof(DerivedElementType))) DerivedElementType; | 274 return new (helper_.Allocate(sizeof(DerivedElementType))) |
275 DerivedElementType; | |
280 } | 276 } |
281 | 277 |
282 // Take in derived element type and copy construct it at location generated by | 278 // Take in derived element type and copy construct it at location generated by |
283 // Allocate(). | 279 // Allocate(). |
284 template <typename DerivedElementType> | 280 template <typename DerivedElementType> |
285 DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) { | 281 DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) { |
286 return new (Allocate(sizeof(DerivedElementType))) | 282 return new (helper_.Allocate(sizeof(DerivedElementType))) |
287 DerivedElementType(*source); | 283 DerivedElementType(*source); |
288 } | 284 } |
289 | 285 |
290 // Construct a new element on top of an existing one. | 286 // Construct a new element on top of an existing one. |
291 template <typename DerivedElementType> | 287 template <typename DerivedElementType> |
292 DerivedElementType* ReplaceExistingElement(Iterator at) { | 288 DerivedElementType* ReplaceExistingElement(Iterator at) { |
293 at->~BaseElementType(); | 289 at->~BaseElementType(); |
294 return new (*at) DerivedElementType(); | 290 return new (*at) DerivedElementType(); |
295 } | 291 } |
296 | 292 |
297 // Insert |count| new elements of |DerivedElementType| before |at|. This will | 293 // Insert |count| new elements of |DerivedElementType| before |at|. This will |
298 // invalidate all outstanding pointers and iterators. Return a valid iterator | 294 // invalidate all outstanding pointers and iterators. Return a valid iterator |
299 // for the beginning of the newly inserted segment. | 295 // for the beginning of the newly inserted segment. |
300 template <typename DerivedElementType> | 296 template <typename DerivedElementType> |
301 Iterator InsertBeforeAndInvalidateAllPointers(Iterator at, size_t count) { | 297 Iterator InsertBeforeAndInvalidateAllPointers(Iterator at, size_t count) { |
302 ListContainerBase::InsertBeforeAndInvalidateAllPointers(&at, count); | 298 helper_.InsertBeforeAndInvalidateAllPointers(&at, count); |
303 Iterator result = at; | 299 Iterator result = at; |
304 for (size_t i = 0; i < count; ++i) { | 300 for (size_t i = 0; i < count; ++i) { |
305 new (*at) DerivedElementType(); | 301 new (*at) DerivedElementType(); |
306 ++at; | 302 ++at; |
307 } | 303 } |
308 return result; | 304 return result; |
309 } | 305 } |
310 | 306 |
311 template <typename DerivedElementType> | 307 template <typename DerivedElementType> |
312 void swap(ListContainer<DerivedElementType>& other) { | 308 void swap(ListContainer<DerivedElementType>& other) { |
313 data_.swap(other.data_); | 309 helper_.data_.swap(other.helper_.data_); |
314 } | 310 } |
315 | 311 |
316 // Appends a new item without copying. The original item will not be | 312 // Appends a new item without copying. The original item will not be |
317 // destructed and will be replaced with a new DerivedElementType. The | 313 // destructed and will be replaced with a new DerivedElementType. The |
318 // DerivedElementType does not have to match the moved type as a full block | 314 // 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 | 315 // of memory will be moved (up to MaxSizeForDerivedClass()). A pointer to |
320 // the moved element is returned. | 316 // the moved element is returned. |
321 template <typename DerivedElementType> | 317 template <typename DerivedElementType> |
322 DerivedElementType* AppendByMoving(DerivedElementType* item) { | 318 DerivedElementType* AppendByMoving(DerivedElementType* item) { |
323 size_t max_size_for_derived_class = MaxSizeForDerivedClass(); | 319 size_t max_size_for_derived_class = helper_.MaxSizeForDerivedClass(); |
324 void* new_item = Allocate(max_size_for_derived_class); | 320 void* new_item = helper_.Allocate(max_size_for_derived_class); |
325 memcpy(new_item, static_cast<void*>(item), max_size_for_derived_class); | 321 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. | 322 // Construct a new element in-place so it can be destructed safely. |
327 new (item) DerivedElementType; | 323 new (item) DerivedElementType; |
328 return static_cast<DerivedElementType*>(new_item); | 324 return static_cast<DerivedElementType*>(new_item); |
329 } | 325 } |
330 | 326 |
331 using ListContainerBase::size; | 327 size_t size() const { return helper_.size(); } |
332 using ListContainerBase::empty; | 328 bool empty() const { return helper_.empty(); } |
333 using ListContainerBase::GetCapacityInBytes; | 329 size_t GetCapacityInBytes() const { return helper_.GetCapacityInBytes(); } |
334 | 330 |
335 void clear() { | 331 void clear() { |
336 for (Iterator i = begin(); i != end(); ++i) { | 332 for (Iterator i = begin(); i != end(); ++i) { |
337 i->~BaseElementType(); | 333 i->~BaseElementType(); |
338 } | 334 } |
339 ListContainerBase::clear(); | 335 helper_.clear(); |
340 } | 336 } |
341 | 337 |
342 using ListContainerBase::AvailableSizeWithoutAnotherAllocationForTesting; | 338 size_t AvailableSizeWithoutAnotherAllocationForTesting() const { |
339 return helper_.AvailableSizeWithoutAnotherAllocationForTesting(); | |
340 } | |
343 | 341 |
344 // Iterator classes that can be used to access data. | 342 // Iterator classes that can be used to access data. |
345 ///////////////////////////////////////////////////////////////// | 343 ///////////////////////////////////////////////////////////////// |
346 class Iterator : public ListContainerBase::Iterator { | 344 class Iterator : public ListContainerHelper::Iterator { |
347 // This class is only defined to forward iterate through | 345 // This class is only defined to forward iterate through |
348 // ListContainerCharAllocator. | 346 // ListContainerCharAllocator. |
349 public: | 347 public: |
350 Iterator(ListContainerCharAllocator* container, | 348 Iterator(ListContainerHelper::ListContainerCharAllocator* container, |
351 size_t vector_ind, | 349 size_t vector_ind, |
352 char* item_iter, | 350 char* item_iter, |
353 size_t index) | 351 size_t index) |
354 : ListContainerBase::Iterator(container, vector_ind, item_iter, index) { | 352 : ListContainerHelper::Iterator(container, |
355 } | 353 vector_ind, |
354 item_iter, | |
355 index) {} | |
356 BaseElementType* operator->() const { | 356 BaseElementType* operator->() const { |
357 return reinterpret_cast<BaseElementType*>(item_iterator); | 357 return reinterpret_cast<BaseElementType*>(item_iterator); |
358 } | 358 } |
359 BaseElementType* operator*() const { | 359 BaseElementType* operator*() const { |
360 return reinterpret_cast<BaseElementType*>(item_iterator); | 360 return reinterpret_cast<BaseElementType*>(item_iterator); |
361 } | 361 } |
362 Iterator operator++(int unused_post_increment) { | 362 Iterator operator++(int unused_post_increment) { |
363 Iterator tmp = *this; | 363 Iterator tmp = *this; |
364 operator++(); | 364 operator++(); |
365 return tmp; | 365 return tmp; |
366 } | 366 } |
367 Iterator& operator++() { | 367 Iterator& operator++() { |
368 Increment(); | 368 Increment(); |
369 ++index_; | 369 ++index_; |
370 return *this; | 370 return *this; |
371 } | 371 } |
372 | 372 |
373 private: | 373 private: |
374 explicit Iterator(const ListContainerBase::Iterator& base_iterator) | 374 explicit Iterator(const ListContainerHelper::Iterator& base_iterator) |
375 : ListContainerBase::Iterator(base_iterator) {} | 375 : ListContainerHelper::Iterator(base_iterator) {} |
376 friend Iterator ListContainer<BaseElementType>::begin(); | 376 friend Iterator ListContainer<BaseElementType>::begin(); |
377 friend Iterator ListContainer<BaseElementType>::end(); | 377 friend Iterator ListContainer<BaseElementType>::end(); |
378 friend BaseElementType* ListContainer<BaseElementType>::ElementAt( | 378 friend BaseElementType* ListContainer<BaseElementType>::ElementAt( |
379 size_t index); | 379 size_t index); |
380 }; | 380 }; |
381 | 381 |
382 class ConstIterator : public ListContainerBase::ConstIterator { | 382 class ConstIterator : public ListContainerHelper::ConstIterator { |
383 // This class is only defined to forward iterate through | 383 // This class is only defined to forward iterate through |
384 // ListContainerCharAllocator. | 384 // ListContainerCharAllocator. |
385 public: | 385 public: |
386 ConstIterator(ListContainerCharAllocator* container, | 386 ConstIterator(ListContainerHelper::ListContainerCharAllocator* container, |
387 size_t vector_ind, | 387 size_t vector_ind, |
388 char* item_iter, | 388 char* item_iter, |
389 size_t index) | 389 size_t index) |
390 : ListContainerBase::ConstIterator(container, | 390 : ListContainerHelper::ConstIterator(container, |
391 vector_ind, | 391 vector_ind, |
392 item_iter, | 392 item_iter, |
393 index) {} | 393 index) {} |
394 ConstIterator(const Iterator& other) // NOLINT | 394 ConstIterator(const Iterator& other) // NOLINT |
395 : ListContainerBase::ConstIterator(other) {} | 395 : ListContainerHelper::ConstIterator(other) {} |
396 const BaseElementType* operator->() const { | 396 const BaseElementType* operator->() const { |
397 return reinterpret_cast<const BaseElementType*>(item_iterator); | 397 return reinterpret_cast<const BaseElementType*>(item_iterator); |
398 } | 398 } |
399 const BaseElementType* operator*() const { | 399 const BaseElementType* operator*() const { |
400 return reinterpret_cast<const BaseElementType*>(item_iterator); | 400 return reinterpret_cast<const BaseElementType*>(item_iterator); |
401 } | 401 } |
402 ConstIterator operator++(int unused_post_increment) { | 402 ConstIterator operator++(int unused_post_increment) { |
403 ConstIterator tmp = *this; | 403 ConstIterator tmp = *this; |
404 operator++(); | 404 operator++(); |
405 return tmp; | 405 return tmp; |
406 } | 406 } |
407 ConstIterator& operator++() { | 407 ConstIterator& operator++() { |
408 Increment(); | 408 Increment(); |
409 ++index_; | 409 ++index_; |
410 return *this; | 410 return *this; |
411 } | 411 } |
412 | 412 |
413 private: | 413 private: |
414 explicit ConstIterator( | 414 explicit ConstIterator( |
415 const ListContainerBase::ConstIterator& base_iterator) | 415 const ListContainerHelper::ConstIterator& base_iterator) |
416 : ListContainerBase::ConstIterator(base_iterator) {} | 416 : ListContainerHelper::ConstIterator(base_iterator) {} |
417 friend ConstIterator ListContainer<BaseElementType>::cbegin() const; | 417 friend ConstIterator ListContainer<BaseElementType>::cbegin() const; |
418 friend ConstIterator ListContainer<BaseElementType>::cend() const; | 418 friend ConstIterator ListContainer<BaseElementType>::cend() const; |
419 friend const BaseElementType* ListContainer<BaseElementType>::ElementAt( | 419 friend const BaseElementType* ListContainer<BaseElementType>::ElementAt( |
420 size_t index) const; | 420 size_t index) const; |
421 }; | 421 }; |
422 | 422 |
423 class ReverseIterator : public ListContainerBase::ReverseIterator { | 423 class ReverseIterator : public ListContainerHelper::ReverseIterator { |
424 // This class is only defined to reverse iterate through | 424 // This class is only defined to reverse iterate through |
425 // ListContainerCharAllocator. | 425 // ListContainerCharAllocator. |
426 public: | 426 public: |
427 ReverseIterator(ListContainerCharAllocator* container, | 427 ReverseIterator(ListContainerHelper::ListContainerCharAllocator* container, |
428 size_t vector_ind, | 428 size_t vector_ind, |
429 char* item_iter, | 429 char* item_iter, |
430 size_t index) | 430 size_t index) |
431 : ListContainerBase::ReverseIterator(container, | 431 : ListContainerHelper::ReverseIterator(container, |
432 vector_ind, | 432 vector_ind, |
433 item_iter, | 433 item_iter, |
434 index) {} | 434 index) {} |
435 BaseElementType* operator->() const { | 435 BaseElementType* operator->() const { |
436 return reinterpret_cast<BaseElementType*>(item_iterator); | 436 return reinterpret_cast<BaseElementType*>(item_iterator); |
437 } | 437 } |
438 BaseElementType* operator*() const { | 438 BaseElementType* operator*() const { |
439 return reinterpret_cast<BaseElementType*>(item_iterator); | 439 return reinterpret_cast<BaseElementType*>(item_iterator); |
440 } | 440 } |
441 ReverseIterator operator++(int unused_post_increment) { | 441 ReverseIterator operator++(int unused_post_increment) { |
442 ReverseIterator tmp = *this; | 442 ReverseIterator tmp = *this; |
443 operator++(); | 443 operator++(); |
444 return tmp; | 444 return tmp; |
445 } | 445 } |
446 ReverseIterator& operator++() { | 446 ReverseIterator& operator++() { |
447 ReverseIncrement(); | 447 ReverseIncrement(); |
448 ++index_; | 448 ++index_; |
449 return *this; | 449 return *this; |
450 } | 450 } |
451 | 451 |
452 private: | 452 private: |
453 explicit ReverseIterator(ListContainerBase::ReverseIterator base_iterator) | 453 explicit ReverseIterator(ListContainerHelper::ReverseIterator base_iterator) |
454 : ListContainerBase::ReverseIterator(base_iterator) {} | 454 : ListContainerHelper::ReverseIterator(base_iterator) {} |
455 friend ReverseIterator ListContainer<BaseElementType>::rbegin(); | 455 friend ReverseIterator ListContainer<BaseElementType>::rbegin(); |
456 friend ReverseIterator ListContainer<BaseElementType>::rend(); | 456 friend ReverseIterator ListContainer<BaseElementType>::rend(); |
457 }; | 457 }; |
458 | 458 |
459 class ConstReverseIterator : public ListContainerBase::ConstReverseIterator { | 459 class ConstReverseIterator |
460 : public ListContainerHelper::ConstReverseIterator { | |
460 // This class is only defined to reverse iterate through | 461 // This class is only defined to reverse iterate through |
461 // ListContainerCharAllocator. | 462 // ListContainerCharAllocator. |
462 public: | 463 public: |
463 ConstReverseIterator(ListContainerCharAllocator* container, | 464 ConstReverseIterator( |
464 size_t vector_ind, | 465 ListContainerHelper::ListContainerCharAllocator* container, |
465 char* item_iter, | 466 size_t vector_ind, |
466 size_t index) | 467 char* item_iter, |
467 : ListContainerBase::ConstReverseIterator(container, | 468 size_t index) |
468 vector_ind, | 469 : ListContainerHelper::ConstReverseIterator(container, |
469 item_iter, | 470 vector_ind, |
470 index) {} | 471 item_iter, |
472 index) {} | |
471 ConstReverseIterator(const ReverseIterator& other) // NOLINT | 473 ConstReverseIterator(const ReverseIterator& other) // NOLINT |
472 : ListContainerBase::ConstReverseIterator(other) {} | 474 : ListContainerHelper::ConstReverseIterator(other) {} |
473 const BaseElementType* operator->() const { | 475 const BaseElementType* operator->() const { |
474 return reinterpret_cast<const BaseElementType*>(item_iterator); | 476 return reinterpret_cast<const BaseElementType*>(item_iterator); |
475 } | 477 } |
476 const BaseElementType* operator*() const { | 478 const BaseElementType* operator*() const { |
477 return reinterpret_cast<const BaseElementType*>(item_iterator); | 479 return reinterpret_cast<const BaseElementType*>(item_iterator); |
478 } | 480 } |
479 ConstReverseIterator operator++(int unused_post_increment) { | 481 ConstReverseIterator operator++(int unused_post_increment) { |
480 ConstReverseIterator tmp = *this; | 482 ConstReverseIterator tmp = *this; |
481 operator++(); | 483 operator++(); |
482 return tmp; | 484 return tmp; |
483 } | 485 } |
484 ConstReverseIterator& operator++() { | 486 ConstReverseIterator& operator++() { |
485 ReverseIncrement(); | 487 ReverseIncrement(); |
486 ++index_; | 488 ++index_; |
487 return *this; | 489 return *this; |
488 } | 490 } |
489 | 491 |
490 private: | 492 private: |
491 explicit ConstReverseIterator( | 493 explicit ConstReverseIterator( |
492 ListContainerBase::ConstReverseIterator base_iterator) | 494 ListContainerHelper::ConstReverseIterator base_iterator) |
493 : ListContainerBase::ConstReverseIterator(base_iterator) {} | 495 : ListContainerHelper::ConstReverseIterator(base_iterator) {} |
494 friend ConstReverseIterator ListContainer<BaseElementType>::crbegin() const; | 496 friend ConstReverseIterator ListContainer<BaseElementType>::crbegin() const; |
495 friend ConstReverseIterator ListContainer<BaseElementType>::crend() const; | 497 friend ConstReverseIterator ListContainer<BaseElementType>::crend() const; |
496 }; | 498 }; |
499 | |
500 private: | |
501 ListContainerHelper helper_; | |
497 }; | 502 }; |
498 | 503 |
499 } // namespace cc | 504 } // namespace cc |
500 | 505 |
501 #endif // CC_BASE_LIST_CONTAINER_H_ | 506 #endif // CC_BASE_LIST_CONTAINER_H_ |
OLD | NEW |