Chromium Code Reviews| 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 |