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