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 #include "cc/base/list_container.h" | 5 #include "cc/base/list_container_helper.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "cc/base/scoped_ptr_vector.h" | 10 #include "cc/base/scoped_ptr_vector.h" |
11 | 11 |
12 namespace { | 12 namespace { |
13 const size_t kDefaultNumElementTypesToReserve = 32; | 13 const size_t kDefaultNumElementTypesToReserve = 32; |
14 } // namespace | 14 } // namespace |
15 | 15 |
16 namespace cc { | 16 namespace cc { |
17 | 17 |
18 // ListContainerCharAllocator | 18 // CharAllocator |
19 //////////////////////////////////////////////////// | 19 //////////////////////////////////////////////////// |
20 // This class deals only with char* and void*. It does allocation and passing | 20 // This class deals only with char* and void*. It does allocation and passing |
21 // out raw pointers, as well as memory deallocation when being destroyed. | 21 // out raw pointers, as well as memory deallocation when being destroyed. |
22 class ListContainerBase::ListContainerCharAllocator { | 22 class ListContainerHelper::CharAllocator { |
23 public: | 23 public: |
24 // ListContainerCharAllocator::InnerList | 24 // CharAllocator::InnerList |
25 ///////////////////////////////////////////// | 25 ///////////////////////////////////////////// |
26 // This class holds the raw memory chunk, as well as information about its | 26 // This class holds the raw memory chunk, as well as information about its |
27 // size and availability. | 27 // size and availability. |
28 struct InnerList { | 28 struct InnerList { |
29 scoped_ptr<char[]> data; | 29 scoped_ptr<char[]> data; |
30 // The number of elements in total the memory can hold. The difference | 30 // The number of elements in total the memory can hold. The difference |
31 // between capacity and size is the how many more elements this list can | 31 // between capacity and size is the how many more elements this list can |
32 // hold. | 32 // hold. |
33 size_t capacity; | 33 size_t capacity; |
34 // The number of elements have been put into this list. | 34 // The number of elements have been put into this list. |
35 size_t size; | 35 size_t size; |
36 // The size of each element is in bytes. This is used to move from between | 36 // The size of each element is in bytes. This is used to move from between |
37 // elements' memory locations. | 37 // elements' memory locations. |
38 size_t step; | 38 size_t step; |
39 | 39 |
40 InnerList() : capacity(0), size(0), step(0) {} | 40 InnerList() : capacity(0), size(0), step(0) {} |
41 | 41 |
42 void Erase(char* position) { | 42 void Erase(char* position) { |
43 // Confident that destructor is called by caller of this function. Since | 43 // Confident that destructor is called by caller of this function. Since |
44 // ListContainerCharAllocator does not handle construction after | 44 // CharAllocator does not handle construction after |
45 // allocation, it doesn't handle desctrution before deallocation. | 45 // allocation, it doesn't handle desctrution before deallocation. |
46 DCHECK_LE(position, LastElement()); | 46 DCHECK_LE(position, LastElement()); |
47 DCHECK_GE(position, Begin()); | 47 DCHECK_GE(position, Begin()); |
48 char* start = position + step; | 48 char* start = position + step; |
49 std::copy(start, End(), position); | 49 std::copy(start, End(), position); |
50 | 50 |
51 --size; | 51 --size; |
52 // Decrease capacity to avoid creating not full not last InnerList. | 52 // Decrease capacity to avoid creating not full not last InnerList. |
53 --capacity; | 53 --capacity; |
54 } | 54 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 | 92 |
93 char* Begin() const { return data.get(); } | 93 char* Begin() const { return data.get(); } |
94 char* End() const { return data.get() + size * step; } | 94 char* End() const { return data.get() + size * step; } |
95 char* LastElement() const { return data.get() + (size - 1) * step; } | 95 char* LastElement() const { return data.get() + (size - 1) * step; } |
96 char* ElementAt(size_t index) const { return data.get() + index * step; } | 96 char* ElementAt(size_t index) const { return data.get() + index * step; } |
97 | 97 |
98 private: | 98 private: |
99 DISALLOW_COPY_AND_ASSIGN(InnerList); | 99 DISALLOW_COPY_AND_ASSIGN(InnerList); |
100 }; | 100 }; |
101 | 101 |
102 explicit ListContainerCharAllocator(size_t element_size) | 102 explicit CharAllocator(size_t element_size) |
103 : element_size_(element_size), | 103 : element_size_(element_size), |
104 size_(0), | 104 size_(0), |
105 last_list_index_(0), | 105 last_list_index_(0), |
106 last_list_(NULL) { | 106 last_list_(NULL) { |
107 AllocateNewList(kDefaultNumElementTypesToReserve); | 107 AllocateNewList(kDefaultNumElementTypesToReserve); |
108 last_list_ = storage_[last_list_index_]; | 108 last_list_ = storage_[last_list_index_]; |
109 } | 109 } |
110 | 110 |
111 ListContainerCharAllocator(size_t element_size, size_t element_count) | 111 CharAllocator(size_t element_size, size_t element_count) |
112 : element_size_(element_size), | 112 : element_size_(element_size), |
113 size_(0), | 113 size_(0), |
114 last_list_index_(0), | 114 last_list_index_(0), |
115 last_list_(NULL) { | 115 last_list_(NULL) { |
116 AllocateNewList(element_count > 0 ? element_count | 116 AllocateNewList(element_count > 0 ? element_count |
117 : kDefaultNumElementTypesToReserve); | 117 : kDefaultNumElementTypesToReserve); |
118 last_list_ = storage_[last_list_index_]; | 118 last_list_ = storage_[last_list_index_]; |
119 } | 119 } |
120 | 120 |
121 ~ListContainerCharAllocator() {} | 121 ~CharAllocator() {} |
122 | 122 |
123 void* Allocate() { | 123 void* Allocate() { |
124 if (last_list_->IsFull()) { | 124 if (last_list_->IsFull()) { |
125 // Only allocate a new list if there isn't a spare one still there from | 125 // Only allocate a new list if there isn't a spare one still there from |
126 // previous usage. | 126 // previous usage. |
127 if (last_list_index_ + 1 >= storage_.size()) | 127 if (last_list_index_ + 1 >= storage_.size()) |
128 AllocateNewList(last_list_->capacity * 2); | 128 AllocateNewList(last_list_->capacity * 2); |
129 | 129 |
130 ++last_list_index_; | 130 ++last_list_index_; |
131 last_list_ = storage_[last_list_index_]; | 131 last_list_ = storage_[last_list_index_]; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 --last_list_index_; | 164 --last_list_index_; |
165 last_list_ = storage_[last_list_index_]; | 165 last_list_ = storage_[last_list_index_]; |
166 | 166 |
167 // If there are now two empty inner lists, free one of them. | 167 // If there are now two empty inner lists, free one of them. |
168 if (last_list_index_ + 2 < storage_.size()) | 168 if (last_list_index_ + 2 < storage_.size()) |
169 storage_.pop_back(); | 169 storage_.pop_back(); |
170 } | 170 } |
171 --size_; | 171 --size_; |
172 } | 172 } |
173 | 173 |
174 void Erase(PositionInListContainerCharAllocator* position) { | 174 void Erase(PositionInCharAllocator* position) { |
175 DCHECK_EQ(this, position->ptr_to_container); | 175 DCHECK_EQ(this, position->ptr_to_container); |
176 | 176 |
177 // Update |position| to point to the element after the erased element. | 177 // Update |position| to point to the element after the erased element. |
178 InnerList* list = storage_[position->vector_index]; | 178 InnerList* list = storage_[position->vector_index]; |
179 char* item_iterator = position->item_iterator; | 179 char* item_iterator = position->item_iterator; |
180 if (item_iterator == list->LastElement()) | 180 if (item_iterator == list->LastElement()) |
181 position->Increment(); | 181 position->Increment(); |
182 | 182 |
183 list->Erase(item_iterator); | 183 list->Erase(item_iterator); |
184 // TODO(weiliangc): Free the InnerList if it is empty. | 184 // TODO(weiliangc): Free the InnerList if it is empty. |
185 --size_; | 185 --size_; |
186 } | 186 } |
187 | 187 |
188 void InsertBefore(ListContainerBase::Iterator* position, size_t count) { | 188 void InsertBefore(ListContainerHelper::Iterator* position, size_t count) { |
189 if (!count) | 189 if (!count) |
190 return; | 190 return; |
191 | 191 |
192 // If |position| is End(), then append |count| elements at the end. This | 192 // If |position| is End(), then append |count| elements at the end. This |
193 // will happen to not invalidate any iterators or memory. | 193 // will happen to not invalidate any iterators or memory. |
194 if (!position->item_iterator) { | 194 if (!position->item_iterator) { |
195 // Set |position| to be the first inserted element. | 195 // Set |position| to be the first inserted element. |
196 Allocate(); | 196 Allocate(); |
197 position->vector_index = storage_.size() - 1; | 197 position->vector_index = storage_.size() - 1; |
198 position->item_iterator = storage_[position->vector_index]->LastElement(); | 198 position->item_iterator = storage_[position->vector_index]->LastElement(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 // The number of elements in the list. | 251 // The number of elements in the list. |
252 size_t size_; | 252 size_t size_; |
253 | 253 |
254 // The index of the last list to have had elements added to it, or the only | 254 // The index of the last list to have had elements added to it, or the only |
255 // list if the container has not had elements added since being cleared. | 255 // list if the container has not had elements added since being cleared. |
256 size_t last_list_index_; | 256 size_t last_list_index_; |
257 | 257 |
258 // This is equivalent to |storage_[last_list_index_]|. | 258 // This is equivalent to |storage_[last_list_index_]|. |
259 InnerList* last_list_; | 259 InnerList* last_list_; |
260 | 260 |
261 DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator); | 261 DISALLOW_COPY_AND_ASSIGN(CharAllocator); |
262 }; | 262 }; |
263 | 263 |
264 // PositionInListContainerCharAllocator | 264 // PositionInCharAllocator |
265 ////////////////////////////////////////////////////// | 265 ////////////////////////////////////////////////////// |
266 ListContainerBase::PositionInListContainerCharAllocator:: | 266 ListContainerHelper::PositionInCharAllocator::PositionInCharAllocator( |
267 PositionInListContainerCharAllocator( | 267 const ListContainerHelper::PositionInCharAllocator& other) |
268 const ListContainerBase::PositionInListContainerCharAllocator& other) | |
269 : ptr_to_container(other.ptr_to_container), | 268 : ptr_to_container(other.ptr_to_container), |
270 vector_index(other.vector_index), | 269 vector_index(other.vector_index), |
271 item_iterator(other.item_iterator) { | 270 item_iterator(other.item_iterator) {} |
272 } | |
273 | 271 |
274 ListContainerBase::PositionInListContainerCharAllocator:: | 272 ListContainerHelper::PositionInCharAllocator::PositionInCharAllocator( |
275 PositionInListContainerCharAllocator( | 273 ListContainerHelper::CharAllocator* container, |
276 ListContainerBase::ListContainerCharAllocator* container, | 274 size_t vector_ind, |
277 size_t vector_ind, | 275 char* item_iter) |
278 char* item_iter) | |
279 : ptr_to_container(container), | 276 : ptr_to_container(container), |
280 vector_index(vector_ind), | 277 vector_index(vector_ind), |
281 item_iterator(item_iter) { | 278 item_iterator(item_iter) {} |
282 } | |
283 | 279 |
284 bool ListContainerBase::PositionInListContainerCharAllocator::operator==( | 280 bool ListContainerHelper::PositionInCharAllocator::operator==( |
285 const ListContainerBase::PositionInListContainerCharAllocator& other) | 281 const ListContainerHelper::PositionInCharAllocator& other) const { |
286 const { | |
287 DCHECK_EQ(ptr_to_container, other.ptr_to_container); | 282 DCHECK_EQ(ptr_to_container, other.ptr_to_container); |
288 return vector_index == other.vector_index && | 283 return vector_index == other.vector_index && |
289 item_iterator == other.item_iterator; | 284 item_iterator == other.item_iterator; |
290 } | 285 } |
291 | 286 |
292 bool ListContainerBase::PositionInListContainerCharAllocator::operator!=( | 287 bool ListContainerHelper::PositionInCharAllocator::operator!=( |
293 const ListContainerBase::PositionInListContainerCharAllocator& other) | 288 const ListContainerHelper::PositionInCharAllocator& other) const { |
294 const { | |
295 return !(*this == other); | 289 return !(*this == other); |
296 } | 290 } |
297 | 291 |
298 ListContainerBase::PositionInListContainerCharAllocator | 292 ListContainerHelper::PositionInCharAllocator |
299 ListContainerBase::PositionInListContainerCharAllocator::Increment() { | 293 ListContainerHelper::PositionInCharAllocator::Increment() { |
300 ListContainerCharAllocator::InnerList* list = | 294 CharAllocator::InnerList* list = |
301 ptr_to_container->InnerListById(vector_index); | 295 ptr_to_container->InnerListById(vector_index); |
302 if (item_iterator == list->LastElement()) { | 296 if (item_iterator == list->LastElement()) { |
303 ++vector_index; | 297 ++vector_index; |
304 while (vector_index < ptr_to_container->list_count()) { | 298 while (vector_index < ptr_to_container->list_count()) { |
305 if (ptr_to_container->InnerListById(vector_index)->size != 0) | 299 if (ptr_to_container->InnerListById(vector_index)->size != 0) |
306 break; | 300 break; |
307 ++vector_index; | 301 ++vector_index; |
308 } | 302 } |
309 if (vector_index < ptr_to_container->list_count()) | 303 if (vector_index < ptr_to_container->list_count()) |
310 item_iterator = ptr_to_container->InnerListById(vector_index)->Begin(); | 304 item_iterator = ptr_to_container->InnerListById(vector_index)->Begin(); |
311 else | 305 else |
312 item_iterator = NULL; | 306 item_iterator = NULL; |
313 } else { | 307 } else { |
314 item_iterator += list->step; | 308 item_iterator += list->step; |
315 } | 309 } |
316 return *this; | 310 return *this; |
317 } | 311 } |
318 | 312 |
319 ListContainerBase::PositionInListContainerCharAllocator | 313 ListContainerHelper::PositionInCharAllocator |
320 ListContainerBase::PositionInListContainerCharAllocator::ReverseIncrement() { | 314 ListContainerHelper::PositionInCharAllocator::ReverseIncrement() { |
321 ListContainerCharAllocator::InnerList* list = | 315 CharAllocator::InnerList* list = |
322 ptr_to_container->InnerListById(vector_index); | 316 ptr_to_container->InnerListById(vector_index); |
323 if (item_iterator == list->Begin()) { | 317 if (item_iterator == list->Begin()) { |
324 --vector_index; | 318 --vector_index; |
325 // Since |vector_index| is unsigned, we compare < list_count() instead of | 319 // Since |vector_index| is unsigned, we compare < list_count() instead of |
326 // comparing >= 0, as the variable will wrap around when it goes out of | 320 // comparing >= 0, as the variable will wrap around when it goes out of |
327 // range (below 0). | 321 // range (below 0). |
328 while (vector_index < ptr_to_container->list_count()) { | 322 while (vector_index < ptr_to_container->list_count()) { |
329 if (ptr_to_container->InnerListById(vector_index)->size != 0) | 323 if (ptr_to_container->InnerListById(vector_index)->size != 0) |
330 break; | 324 break; |
331 --vector_index; | 325 --vector_index; |
332 } | 326 } |
333 if (vector_index < ptr_to_container->list_count()) { | 327 if (vector_index < ptr_to_container->list_count()) { |
334 item_iterator = | 328 item_iterator = |
335 ptr_to_container->InnerListById(vector_index)->LastElement(); | 329 ptr_to_container->InnerListById(vector_index)->LastElement(); |
336 } else { | 330 } else { |
337 item_iterator = NULL; | 331 item_iterator = NULL; |
338 } | 332 } |
339 } else { | 333 } else { |
340 item_iterator -= list->step; | 334 item_iterator -= list->step; |
341 } | 335 } |
342 return *this; | 336 return *this; |
343 } | 337 } |
344 | 338 |
345 // ListContainerBase | 339 // ListContainerHelper |
346 //////////////////////////////////////////// | 340 //////////////////////////////////////////// |
347 ListContainerBase::ListContainerBase(size_t max_size_for_derived_class) | 341 ListContainerHelper::ListContainerHelper(size_t max_size_for_derived_class) |
348 : data_(new ListContainerCharAllocator(max_size_for_derived_class)) { | 342 : data_(new CharAllocator(max_size_for_derived_class)) {} |
349 } | |
350 | 343 |
351 ListContainerBase::ListContainerBase(size_t max_size_for_derived_class, | 344 ListContainerHelper::ListContainerHelper(size_t max_size_for_derived_class, |
352 size_t num_of_elements_to_reserve_for) | 345 size_t num_of_elements_to_reserve_for) |
353 : data_(new ListContainerCharAllocator(max_size_for_derived_class, | 346 : data_(new CharAllocator(max_size_for_derived_class, |
354 num_of_elements_to_reserve_for)) { | 347 num_of_elements_to_reserve_for)) {} |
355 } | |
356 | 348 |
357 ListContainerBase::~ListContainerBase() { | 349 ListContainerHelper::~ListContainerHelper() {} |
358 } | |
359 | 350 |
360 void ListContainerBase::RemoveLast() { | 351 void ListContainerHelper::RemoveLast() { |
361 data_->RemoveLast(); | 352 data_->RemoveLast(); |
362 } | 353 } |
363 | 354 |
364 void ListContainerBase::EraseAndInvalidateAllPointers( | 355 void ListContainerHelper::EraseAndInvalidateAllPointers( |
365 ListContainerBase::Iterator* position) { | 356 ListContainerHelper::Iterator* position) { |
366 data_->Erase(position); | 357 data_->Erase(position); |
367 } | 358 } |
368 | 359 |
369 void ListContainerBase::InsertBeforeAndInvalidateAllPointers( | 360 void ListContainerHelper::InsertBeforeAndInvalidateAllPointers( |
370 ListContainerBase::Iterator* position, | 361 ListContainerHelper::Iterator* position, |
371 size_t count) { | 362 size_t count) { |
372 data_->InsertBefore(position, count); | 363 data_->InsertBefore(position, count); |
373 } | 364 } |
374 | 365 |
375 ListContainerBase::ConstReverseIterator ListContainerBase::crbegin() const { | 366 ListContainerHelper::ConstReverseIterator ListContainerHelper::crbegin() const { |
376 if (data_->IsEmpty()) | 367 if (data_->IsEmpty()) |
377 return crend(); | 368 return crend(); |
378 | 369 |
379 size_t id = data_->LastInnerListId(); | 370 size_t id = data_->LastInnerListId(); |
380 return ConstReverseIterator(data_.get(), id, | 371 return ConstReverseIterator(data_.get(), id, |
381 data_->InnerListById(id)->LastElement(), 0); | 372 data_->InnerListById(id)->LastElement(), 0); |
382 } | 373 } |
383 | 374 |
384 ListContainerBase::ConstReverseIterator ListContainerBase::crend() const { | 375 ListContainerHelper::ConstReverseIterator ListContainerHelper::crend() const { |
385 return ConstReverseIterator(data_.get(), static_cast<size_t>(-1), NULL, | 376 return ConstReverseIterator(data_.get(), static_cast<size_t>(-1), NULL, |
386 size()); | 377 size()); |
387 } | 378 } |
388 | 379 |
389 ListContainerBase::ReverseIterator ListContainerBase::rbegin() { | 380 ListContainerHelper::ReverseIterator ListContainerHelper::rbegin() { |
390 if (data_->IsEmpty()) | 381 if (data_->IsEmpty()) |
391 return rend(); | 382 return rend(); |
392 | 383 |
393 size_t id = data_->LastInnerListId(); | 384 size_t id = data_->LastInnerListId(); |
394 return ReverseIterator(data_.get(), id, | 385 return ReverseIterator(data_.get(), id, |
395 data_->InnerListById(id)->LastElement(), 0); | 386 data_->InnerListById(id)->LastElement(), 0); |
396 } | 387 } |
397 | 388 |
398 ListContainerBase::ReverseIterator ListContainerBase::rend() { | 389 ListContainerHelper::ReverseIterator ListContainerHelper::rend() { |
399 return ReverseIterator(data_.get(), static_cast<size_t>(-1), NULL, size()); | 390 return ReverseIterator(data_.get(), static_cast<size_t>(-1), NULL, size()); |
400 } | 391 } |
401 | 392 |
402 ListContainerBase::ConstIterator ListContainerBase::cbegin() const { | 393 ListContainerHelper::ConstIterator ListContainerHelper::cbegin() const { |
403 if (data_->IsEmpty()) | 394 if (data_->IsEmpty()) |
404 return cend(); | 395 return cend(); |
405 | 396 |
406 size_t id = data_->FirstInnerListId(); | 397 size_t id = data_->FirstInnerListId(); |
407 return ConstIterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0); | 398 return ConstIterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0); |
408 } | 399 } |
409 | 400 |
410 ListContainerBase::ConstIterator ListContainerBase::cend() const { | 401 ListContainerHelper::ConstIterator ListContainerHelper::cend() const { |
411 if (data_->IsEmpty()) | 402 if (data_->IsEmpty()) |
412 return ConstIterator(data_.get(), 0, NULL, size()); | 403 return ConstIterator(data_.get(), 0, NULL, size()); |
413 | 404 |
414 size_t id = data_->list_count(); | 405 size_t id = data_->list_count(); |
415 return ConstIterator(data_.get(), id, NULL, size()); | 406 return ConstIterator(data_.get(), id, NULL, size()); |
416 } | 407 } |
417 | 408 |
418 ListContainerBase::Iterator ListContainerBase::begin() { | 409 ListContainerHelper::Iterator ListContainerHelper::begin() { |
419 if (data_->IsEmpty()) | 410 if (data_->IsEmpty()) |
420 return end(); | 411 return end(); |
421 | 412 |
422 size_t id = data_->FirstInnerListId(); | 413 size_t id = data_->FirstInnerListId(); |
423 return Iterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0); | 414 return Iterator(data_.get(), id, data_->InnerListById(id)->Begin(), 0); |
424 } | 415 } |
425 | 416 |
426 ListContainerBase::Iterator ListContainerBase::end() { | 417 ListContainerHelper::Iterator ListContainerHelper::end() { |
427 if (data_->IsEmpty()) | 418 if (data_->IsEmpty()) |
428 return Iterator(data_.get(), 0, NULL, size()); | 419 return Iterator(data_.get(), 0, NULL, size()); |
429 | 420 |
430 size_t id = data_->list_count(); | 421 size_t id = data_->list_count(); |
431 return Iterator(data_.get(), id, NULL, size()); | 422 return Iterator(data_.get(), id, NULL, size()); |
432 } | 423 } |
433 | 424 |
434 ListContainerBase::ConstIterator ListContainerBase::IteratorAt( | 425 ListContainerHelper::ConstIterator ListContainerHelper::IteratorAt( |
435 size_t index) const { | 426 size_t index) const { |
436 DCHECK_LT(index, size()); | 427 DCHECK_LT(index, size()); |
437 size_t original_index = index; | 428 size_t original_index = index; |
438 size_t list_index; | 429 size_t list_index; |
439 for (list_index = 0; list_index < data_->list_count(); ++list_index) { | 430 for (list_index = 0; list_index < data_->list_count(); ++list_index) { |
440 size_t current_size = data_->InnerListById(list_index)->size; | 431 size_t current_size = data_->InnerListById(list_index)->size; |
441 if (index < current_size) | 432 if (index < current_size) |
442 break; | 433 break; |
443 index -= current_size; | 434 index -= current_size; |
444 } | 435 } |
445 return ConstIterator(data_.get(), list_index, | 436 return ConstIterator(data_.get(), list_index, |
446 data_->InnerListById(list_index)->ElementAt(index), | 437 data_->InnerListById(list_index)->ElementAt(index), |
447 original_index); | 438 original_index); |
448 } | 439 } |
449 | 440 |
450 ListContainerBase::Iterator ListContainerBase::IteratorAt(size_t index) { | 441 ListContainerHelper::Iterator ListContainerHelper::IteratorAt(size_t index) { |
451 DCHECK_LT(index, size()); | 442 DCHECK_LT(index, size()); |
452 size_t original_index = index; | 443 size_t original_index = index; |
453 size_t list_index; | 444 size_t list_index; |
454 for (list_index = 0; list_index < data_->list_count(); ++list_index) { | 445 for (list_index = 0; list_index < data_->list_count(); ++list_index) { |
455 size_t current_size = data_->InnerListById(list_index)->size; | 446 size_t current_size = data_->InnerListById(list_index)->size; |
456 if (index < current_size) | 447 if (index < current_size) |
457 break; | 448 break; |
458 index -= current_size; | 449 index -= current_size; |
459 } | 450 } |
460 return Iterator(data_.get(), list_index, | 451 return Iterator(data_.get(), list_index, |
461 data_->InnerListById(list_index)->ElementAt(index), | 452 data_->InnerListById(list_index)->ElementAt(index), |
462 original_index); | 453 original_index); |
463 } | 454 } |
464 | 455 |
465 void* ListContainerBase::Allocate(size_t size_of_actual_element_in_bytes) { | 456 void* ListContainerHelper::Allocate(size_t size_of_actual_element_in_bytes) { |
466 DCHECK_LE(size_of_actual_element_in_bytes, data_->element_size()); | 457 DCHECK_LE(size_of_actual_element_in_bytes, data_->element_size()); |
467 return data_->Allocate(); | 458 return data_->Allocate(); |
468 } | 459 } |
469 | 460 |
470 size_t ListContainerBase::size() const { | 461 size_t ListContainerHelper::size() const { |
471 return data_->size(); | 462 return data_->size(); |
472 } | 463 } |
473 | 464 |
474 bool ListContainerBase::empty() const { | 465 bool ListContainerHelper::empty() const { |
475 return data_->IsEmpty(); | 466 return data_->IsEmpty(); |
476 } | 467 } |
477 | 468 |
478 size_t ListContainerBase::MaxSizeForDerivedClass() const { | 469 size_t ListContainerHelper::MaxSizeForDerivedClass() const { |
479 return data_->element_size(); | 470 return data_->element_size(); |
480 } | 471 } |
481 | 472 |
482 size_t ListContainerBase::GetCapacityInBytes() const { | 473 size_t ListContainerHelper::GetCapacityInBytes() const { |
483 return data_->Capacity() * data_->element_size(); | 474 return data_->Capacity() * data_->element_size(); |
484 } | 475 } |
485 | 476 |
486 void ListContainerBase::clear() { | 477 void ListContainerHelper::clear() { |
487 data_->Clear(); | 478 data_->Clear(); |
488 } | 479 } |
489 | 480 |
490 size_t ListContainerBase::AvailableSizeWithoutAnotherAllocationForTesting() | 481 size_t ListContainerHelper::AvailableSizeWithoutAnotherAllocationForTesting() |
491 const { | 482 const { |
492 return data_->NumAvailableElementsInLastList(); | 483 return data_->NumAvailableElementsInLastList(); |
493 } | 484 } |
494 | 485 |
495 // ListContainerBase::Iterator | 486 // ListContainerHelper::Iterator |
496 ///////////////////////////////////////////////// | 487 ///////////////////////////////////////////////// |
497 ListContainerBase::Iterator::Iterator(ListContainerCharAllocator* container, | 488 ListContainerHelper::Iterator::Iterator(CharAllocator* container, |
498 size_t vector_ind, | 489 size_t vector_ind, |
499 char* item_iter, | 490 char* item_iter, |
500 size_t index) | 491 size_t index) |
501 : PositionInListContainerCharAllocator(container, vector_ind, item_iter), | 492 : PositionInCharAllocator(container, vector_ind, item_iter), |
502 index_(index) { | 493 index_(index) {} |
503 } | |
504 | 494 |
505 ListContainerBase::Iterator::~Iterator() { | 495 ListContainerHelper::Iterator::~Iterator() {} |
506 } | |
507 | 496 |
508 size_t ListContainerBase::Iterator::index() const { | 497 size_t ListContainerHelper::Iterator::index() const { |
509 return index_; | 498 return index_; |
510 } | 499 } |
511 | 500 |
512 // ListContainerBase::ConstIterator | 501 // ListContainerHelper::ConstIterator |
513 ///////////////////////////////////////////////// | 502 ///////////////////////////////////////////////// |
514 ListContainerBase::ConstIterator::ConstIterator( | 503 ListContainerHelper::ConstIterator::ConstIterator( |
515 const ListContainerBase::Iterator& other) | 504 const ListContainerHelper::Iterator& other) |
516 : PositionInListContainerCharAllocator(other), index_(other.index()) { | 505 : PositionInCharAllocator(other), index_(other.index()) {} |
| 506 |
| 507 ListContainerHelper::ConstIterator::ConstIterator(CharAllocator* container, |
| 508 size_t vector_ind, |
| 509 char* item_iter, |
| 510 size_t index) |
| 511 : PositionInCharAllocator(container, vector_ind, item_iter), |
| 512 index_(index) {} |
| 513 |
| 514 ListContainerHelper::ConstIterator::~ConstIterator() {} |
| 515 |
| 516 size_t ListContainerHelper::ConstIterator::index() const { |
| 517 return index_; |
517 } | 518 } |
518 | 519 |
519 ListContainerBase::ConstIterator::ConstIterator( | 520 // ListContainerHelper::ReverseIterator |
520 ListContainerCharAllocator* container, | 521 ///////////////////////////////////////////////// |
| 522 ListContainerHelper::ReverseIterator::ReverseIterator(CharAllocator* container, |
| 523 size_t vector_ind, |
| 524 char* item_iter, |
| 525 size_t index) |
| 526 : PositionInCharAllocator(container, vector_ind, item_iter), |
| 527 index_(index) {} |
| 528 |
| 529 ListContainerHelper::ReverseIterator::~ReverseIterator() {} |
| 530 |
| 531 size_t ListContainerHelper::ReverseIterator::index() const { |
| 532 return index_; |
| 533 } |
| 534 |
| 535 // ListContainerHelper::ConstReverseIterator |
| 536 ///////////////////////////////////////////////// |
| 537 ListContainerHelper::ConstReverseIterator::ConstReverseIterator( |
| 538 const ListContainerHelper::ReverseIterator& other) |
| 539 : PositionInCharAllocator(other), index_(other.index()) {} |
| 540 |
| 541 ListContainerHelper::ConstReverseIterator::ConstReverseIterator( |
| 542 CharAllocator* container, |
521 size_t vector_ind, | 543 size_t vector_ind, |
522 char* item_iter, | 544 char* item_iter, |
523 size_t index) | 545 size_t index) |
524 : PositionInListContainerCharAllocator(container, vector_ind, item_iter), | 546 : PositionInCharAllocator(container, vector_ind, item_iter), |
525 index_(index) { | 547 index_(index) {} |
526 } | |
527 | 548 |
528 ListContainerBase::ConstIterator::~ConstIterator() { | 549 ListContainerHelper::ConstReverseIterator::~ConstReverseIterator() {} |
529 } | |
530 | 550 |
531 size_t ListContainerBase::ConstIterator::index() const { | 551 size_t ListContainerHelper::ConstReverseIterator::index() const { |
532 return index_; | 552 return index_; |
533 } | 553 } |
534 | 554 |
535 // ListContainerBase::ReverseIterator | |
536 ///////////////////////////////////////////////// | |
537 ListContainerBase::ReverseIterator::ReverseIterator( | |
538 ListContainerCharAllocator* container, | |
539 size_t vector_ind, | |
540 char* item_iter, | |
541 size_t index) | |
542 : PositionInListContainerCharAllocator(container, vector_ind, item_iter), | |
543 index_(index) { | |
544 } | |
545 | |
546 ListContainerBase::ReverseIterator::~ReverseIterator() { | |
547 } | |
548 | |
549 size_t ListContainerBase::ReverseIterator::index() const { | |
550 return index_; | |
551 } | |
552 | |
553 // ListContainerBase::ConstReverseIterator | |
554 ///////////////////////////////////////////////// | |
555 ListContainerBase::ConstReverseIterator::ConstReverseIterator( | |
556 const ListContainerBase::ReverseIterator& other) | |
557 : PositionInListContainerCharAllocator(other), index_(other.index()) { | |
558 } | |
559 | |
560 ListContainerBase::ConstReverseIterator::ConstReverseIterator( | |
561 ListContainerCharAllocator* container, | |
562 size_t vector_ind, | |
563 char* item_iter, | |
564 size_t index) | |
565 : PositionInListContainerCharAllocator(container, vector_ind, item_iter), | |
566 index_(index) { | |
567 } | |
568 | |
569 ListContainerBase::ConstReverseIterator::~ConstReverseIterator() { | |
570 } | |
571 | |
572 size_t ListContainerBase::ConstReverseIterator::index() const { | |
573 return index_; | |
574 } | |
575 | |
576 } // namespace cc | 555 } // namespace cc |
OLD | NEW |