Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(358)

Side by Side Diff: Source/wtf/Vector.h

Issue 390983010: Fix Deque.swap for deques with inline capacity Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Use more fullnesses in test to improve coverage Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public 5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version. 7 * version 2 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 T* buffer() { return m_buffer; } 304 T* buffer() { return m_buffer; }
305 const T* buffer() const { return m_buffer; } 305 const T* buffer() const { return m_buffer; }
306 size_t capacity() const { return m_capacity; } 306 size_t capacity() const { return m_capacity; }
307 307
308 void clearUnusedSlots(T* from, T* to) 308 void clearUnusedSlots(T* from, T* to)
309 { 309 {
310 VectorUnusedSlotClearer<Allocator::isGarbageCollected && (VectorTrai ts<T>::needsDestruction || ShouldBeTraced<VectorTraits<T> >::value), T>::clear(f rom, to); 310 VectorUnusedSlotClearer<Allocator::isGarbageCollected && (VectorTrai ts<T>::needsDestruction || ShouldBeTraced<VectorTraits<T> >::value), T>::clear(f rom, to);
311 } 311 }
312 312
313 protected: 313 protected:
314 static const size_t sizeFieldSize = sizeof(unsigned) * 2 > sizeof(double ) ? sizeof(unsigned) * 2 : sizeof(double);
Mads Ager (chromium) 2014/07/18 11:03:14 I can't find any usages of this?
Erik Corry 2014/07/22 15:49:26 Removed.
315
314 VectorBufferBase() 316 VectorBufferBase()
315 : m_buffer(0) 317 : m_buffer(0)
316 , m_capacity(0) 318 , m_capacity(0)
317 { 319 {
318 } 320 }
319 321
320 VectorBufferBase(T* buffer, size_t capacity) 322 VectorBufferBase(T* buffer, size_t capacity)
321 : m_buffer(buffer) 323 : m_buffer(buffer)
322 , m_capacity(capacity) 324 , m_capacity(capacity)
323 { 325 {
324 } 326 }
325 327
328 // Ends are exclusive and if they point at the same element as their
329 // start then the range is empty. The end can point one above the last
330 // element in the capacity (this only happens for Vector, not for
331 // Deque).
332 struct Range {
333 Range(unsigned s = 0, unsigned e = 0)
334 : start(s)
335 , end(e)
336 {
337 }
338
339 bool IsEmpty() { return start == end; }
340
341 unsigned start;
342 unsigned end;
343 };
344
345 // Takes a range, which may wrap around at capacity and
346 // decomposes it into 0, 1, or 2 ranges, returning a pointer to the
347 // element past the last one.
348 Range* findRanges(Range* buffer, const Range in, unsigned capacity)
349 {
350 if (in.end > in.start) {
351 *buffer++ = in;
352 } else if (in.end < in.start) {
353 if (in.end)
354 *buffer++ = Range(0, in.end);
355 ASSERT(in.start != capacity);
356 *buffer++ = Range(in.start, capacity);
357 }
358 return buffer;
359 }
360
326 T* m_buffer; 361 T* m_buffer;
327 unsigned m_capacity; 362 unsigned m_capacity;
328 unsigned m_size;
329 }; 363 };
330 364
331 template<typename T, size_t inlineCapacity, typename Allocator = DefaultAllo cator> 365 template<typename T, size_t inlineCapacity, typename Allocator = DefaultAllo cator>
332 class VectorBuffer; 366 class VectorBuffer;
333 367
334 template<typename T, typename Allocator> 368 template<typename T, typename Allocator>
335 class VectorBuffer<T, 0, Allocator> : protected VectorBufferBase<T, Allocato r> { 369 class VectorBuffer<T, 0, Allocator> : protected VectorBufferBase<T, Allocato r> {
336 private: 370 private:
337 typedef VectorBufferBase<T, Allocator> Base; 371 typedef VectorBufferBase<T, Allocator> Base;
372
373 protected:
374 typedef typename Base::Range Range;
375
338 public: 376 public:
339 VectorBuffer() 377 VectorBuffer()
340 { 378 {
341 } 379 }
342 380
343 VectorBuffer(size_t capacity) 381 VectorBuffer(size_t capacity)
344 { 382 {
345 // Calling malloc(0) might take a lock and may actually do an 383 // Calling malloc(0) might take a lock and may actually do an
346 // allocation on some systems. 384 // allocation on some systems.
347 if (capacity) 385 if (capacity)
(...skipping 10 matching lines...) Expand all
358 { 396 {
359 Allocator::backingFree(bufferToDeallocate); 397 Allocator::backingFree(bufferToDeallocate);
360 } 398 }
361 399
362 void resetBufferPointer() 400 void resetBufferPointer()
363 { 401 {
364 m_buffer = 0; 402 m_buffer = 0;
365 m_capacity = 0; 403 m_capacity = 0;
366 } 404 }
367 405
368 void swapVectorBuffer(VectorBuffer<T, 0, Allocator>& other) 406 void swapVectorBuffer(VectorBuffer<T, 0, Allocator>& other, Range, Range )
369 { 407 {
370 std::swap(m_buffer, other.m_buffer); 408 std::swap(m_buffer, other.m_buffer);
371 std::swap(m_capacity, other.m_capacity); 409 std::swap(m_capacity, other.m_capacity);
372 } 410 }
373 411
374 using Base::allocateBuffer; 412 using Base::allocateBuffer;
375 using Base::allocationSize; 413 using Base::allocationSize;
376 414
377 using Base::buffer; 415 using Base::buffer;
378 using Base::capacity; 416 using Base::capacity;
417 using Base::findRanges;
379 418
380 using Base::clearUnusedSlots; 419 using Base::clearUnusedSlots;
381 420
382 bool hasOutOfLineBuffer() const 421 bool hasOutOfLineBuffer() const
383 { 422 {
384 // When inlineCapacity is 0 we have an out of line buffer if we have a buffer. 423 // When inlineCapacity is 0 we have an out of line buffer if we have a buffer.
385 return buffer(); 424 return buffer();
386 } 425 }
387 426
388 protected:
389 using Base::m_size;
390
391 private: 427 private:
392 using Base::m_buffer; 428 using Base::m_buffer;
393 using Base::m_capacity; 429 using Base::m_capacity;
394 }; 430 };
395 431
396 template<typename T, size_t inlineCapacity, typename Allocator> 432 template<typename T, size_t inlineCapacity, typename Allocator>
397 class VectorBuffer : protected VectorBufferBase<T, Allocator> { 433 class VectorBuffer : protected VectorBufferBase<T, Allocator> {
398 WTF_MAKE_NONCOPYABLE(VectorBuffer); 434 WTF_MAKE_NONCOPYABLE(VectorBuffer);
399 private: 435 private:
400 typedef VectorBufferBase<T, Allocator> Base; 436 typedef VectorBufferBase<T, Allocator> Base;
437
438 protected:
439 typedef typename Base::Range Range;
440
401 public: 441 public:
402 VectorBuffer() 442 VectorBuffer()
403 : Base(inlineBuffer(), inlineCapacity) 443 : Base(inlineBuffer(), inlineCapacity)
404 { 444 {
405 } 445 }
406 446
407 VectorBuffer(size_t capacity) 447 VectorBuffer(size_t capacity)
408 : Base(inlineBuffer(), inlineCapacity) 448 : Base(inlineBuffer(), inlineCapacity)
409 { 449 {
410 if (capacity > inlineCapacity) 450 if (capacity > inlineCapacity)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 resetBufferPointer(); 483 resetBufferPointer();
444 } 484 }
445 485
446 size_t allocationSize(size_t capacity) const 486 size_t allocationSize(size_t capacity) const
447 { 487 {
448 if (capacity <= inlineCapacity) 488 if (capacity <= inlineCapacity)
449 return m_inlineBufferSize; 489 return m_inlineBufferSize;
450 return Base::allocationSize(capacity); 490 return Base::allocationSize(capacity);
451 } 491 }
452 492
453 void swapVectorBuffer(VectorBuffer<T, inlineCapacity, Allocator>& other) 493 void swapVectorBuffer(VectorBuffer<T, inlineCapacity, Allocator>& other, Range thisRange, Range otherRange)
Ken Russell (switch to Gerrit) 2014/07/21 20:44:09 What are the invariants of this method? What does
Erik Corry 2014/07/22 15:49:26 There's no problem with the ranges having a differ
454 { 494 {
455 typedef VectorTypeOperations<T> TypeOperations; 495 typedef VectorTypeOperations<T> TypeOperations;
456 496
457 if (buffer() == inlineBuffer() && other.buffer() == other.inlineBuff er()) { 497 Range thisRanges[2];
458 ASSERT(m_capacity == other.m_capacity); 498 Range otherRanges[2];
459 if (m_size > other.m_size) { 499 Range* thisRangePtr = thisRanges;
460 TypeOperations::swap(inlineBuffer(), inlineBuffer() + other. m_size, other.inlineBuffer()); 500 Range* otherRangePtr = otherRanges;
461 TypeOperations::move(inlineBuffer() + other.m_size, inlineBu ffer() + m_size, other.inlineBuffer() + other.m_size); 501
502 std::swap(m_capacity, other.m_capacity);
503 if (buffer() != inlineBuffer() && other.buffer() != other.inlineBuff er()) {
504 std::swap(m_buffer, other.m_buffer);
505 } else {
Ken Russell (switch to Gerrit) 2014/07/21 20:44:09 I can't in good faith review this method. It isn't
Erik Corry 2014/07/22 15:49:26 I managed to simplify this function quite a bit, w
506 T* otherBuffer = other.m_buffer;
507 if (buffer() == inlineBuffer()) {
508 thisRangePtr = findRanges(thisRanges, thisRange, inlineCapac ity);
462 } else { 509 } else {
463 TypeOperations::swap(inlineBuffer(), inlineBuffer() + m_size , other.inlineBuffer()); 510 other.m_buffer = m_buffer;
464 TypeOperations::move(other.inlineBuffer() + m_size, other.in lineBuffer() + other.m_size, inlineBuffer() + m_size); 511 m_buffer = inlineBuffer();
465 } 512 }
466 } else if (buffer() == inlineBuffer()) { 513 if (otherBuffer == other.inlineBuffer()) {
467 m_buffer = other.m_buffer; 514 otherRangePtr = findRanges(otherRanges, otherRange, inlineCa pacity);
468 other.m_buffer = other.inlineBuffer(); 515 } else {
469 TypeOperations::move(inlineBuffer(), inlineBuffer() + m_size, ot her.inlineBuffer()); 516 m_buffer = otherBuffer;
470 std::swap(m_capacity, other.m_capacity); 517 other.m_buffer = other.inlineBuffer();
471 } else if (other.buffer() == other.inlineBuffer()) { 518 }
472 other.m_buffer = m_buffer; 519 }
473 m_buffer = inlineBuffer(); 520
474 TypeOperations::move(other.inlineBuffer(), other.inlineBuffer() + other.m_size, inlineBuffer()); 521 while (thisRangePtr != thisRanges || otherRangePtr != otherRanges) {
475 std::swap(m_capacity, other.m_capacity); 522 if (thisRangePtr == thisRanges) {
476 } else { 523 // Ran out of ranges in this: process a range in the other.
477 std::swap(m_buffer, other.m_buffer); 524 Range otherRange = *--otherRangePtr;
478 std::swap(m_capacity, other.m_capacity); 525 TypeOperations::move(other.inlineBuffer() + otherRange.start , other.inlineBuffer() + otherRange.end, inlineBuffer() + otherRange.start);
526 continue;
527 }
528 if (otherRangePtr == otherRanges) {
529 // Ran out of ranges in the other: process a range in this.
530 Range thisRange = *--thisRangePtr;
531 TypeOperations::move(inlineBuffer() + thisRange.start, inlin eBuffer() + thisRange.end, other.inlineBuffer() + thisRange.start);
532 continue;
533 }
534 // We have a rightmost range in both. Find out which extends fur thest to the right.
535 Range otherRange = *--otherRangePtr;
536 Range thisRange = *--thisRangePtr;
537 if (otherRange.end == thisRange.end) {
538 // They end together: Find the start of the overlap.
539 unsigned startOfOverlap = std::max(thisRange.start, otherRan ge.start);
540 TypeOperations::swap(inlineBuffer() + startOfOverlap, inline Buffer() + thisRange.end, other.inlineBuffer() + startOfOverlap);
541 if (otherRange.start == thisRange.start)
542 continue; // Common left edge - we are done with these e ntries.
543 if (otherRange.start < thisRange.start) {
544 // The other extends further to the left, make a new ran ge.
545 *otherRangePtr++ = Range(otherRange.start, thisRange.sta rt);
Ken Russell (switch to Gerrit) 2014/07/21 20:44:09 Where is the guarantee that the new range being pu
Erik Corry 2014/07/22 15:49:26 There's no restriction on the ranges pushed on the
546 continue;
547 }
548 // This extends further to the left, make a new range.
549 *thisRangePtr++ = Range(thisRange.start, otherRange.start);
550 continue;
551 }
552 if (otherRange.end > thisRange.end) {
553 // Other one hangs over the edge.
554 unsigned startOfOverhang = std::max(otherRange.start, thisRa nge.end);
555 TypeOperations::move(other.inlineBuffer() + startOfOverhang, other.inlineBuffer() + otherRange.end, inlineBuffer() + startOfOverhang);
556 if (otherRange.start != startOfOverhang)
557 *otherRangePtr++ = Range(otherRange.start, startOfOverha ng);
558 *thisRangePtr++ = thisRange;
559 continue;
560 }
561 ASSERT(thisRange.end > otherRange.end);
562 // This one hangs over the edge.
563 unsigned startOfOverhang = std::max(thisRange.start, otherRange. end);
564 TypeOperations::move(inlineBuffer() + startOfOverhang, inlineBuf fer() + thisRange.end, other.inlineBuffer() + startOfOverhang);
565 if (thisRange.start != startOfOverhang)
566 *thisRangePtr++ = Range(thisRange.start, startOfOverhang);
567 *otherRangePtr++ = otherRange;
479 } 568 }
480 } 569 }
481 570
482 using Base::buffer; 571 using Base::buffer;
483 using Base::capacity; 572 using Base::capacity;
573 using Base::findRanges;
484 574
485 bool hasOutOfLineBuffer() const 575 bool hasOutOfLineBuffer() const
486 { 576 {
487 return buffer() && buffer() != inlineBuffer(); 577 return buffer() && buffer() != inlineBuffer();
488 } 578 }
489 579
490 protected:
491 using Base::m_size;
492
493 private: 580 private:
494 using Base::m_buffer; 581 using Base::m_buffer;
495 using Base::m_capacity; 582 using Base::m_capacity;
496 583
497 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); 584 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T);
498 T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffe r); } 585 T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffe r); }
499 const T* inlineBuffer() const { return reinterpret_cast_ptr<const T*>(m_ inlineBuffer.buffer); } 586 const T* inlineBuffer() const { return reinterpret_cast_ptr<const T*>(m_ inlineBuffer.buffer); }
500 587
501 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; 588 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer;
502 template<typename U, size_t inlineBuffer, typename V> 589 template<typename U, size_t inlineBuffer, typename V>
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 630
544 template<typename Derived, typename Elements> 631 template<typename Derived, typename Elements>
545 class VectorDestructorBase<Derived, Elements, true, true> : public HeapVecto rWithInlineCapacityDestructorBase<Derived, VectorTraits<Elements>::needsDestruct ion> { }; 632 class VectorDestructorBase<Derived, Elements, true, true> : public HeapVecto rWithInlineCapacityDestructorBase<Derived, VectorTraits<Elements>::needsDestruct ion> { };
546 633
547 template<typename T, size_t inlineCapacity = 0, typename Allocator = Default Allocator> 634 template<typename T, size_t inlineCapacity = 0, typename Allocator = Default Allocator>
548 class Vector : private VectorBuffer<T, inlineCapacity, Allocator>, public Ve ctorDestructorBase<Vector<T, inlineCapacity, Allocator>, T, (inlineCapacity > 0) , Allocator::isGarbageCollected> { 635 class Vector : private VectorBuffer<T, inlineCapacity, Allocator>, public Ve ctorDestructorBase<Vector<T, inlineCapacity, Allocator>, T, (inlineCapacity > 0) , Allocator::isGarbageCollected> {
549 WTF_USE_ALLOCATOR(Vector, Allocator); 636 WTF_USE_ALLOCATOR(Vector, Allocator);
550 private: 637 private:
551 typedef VectorBuffer<T, inlineCapacity, Allocator> Base; 638 typedef VectorBuffer<T, inlineCapacity, Allocator> Base;
552 typedef VectorTypeOperations<T> TypeOperations; 639 typedef VectorTypeOperations<T> TypeOperations;
640 typedef typename Base::Range Range;
553 641
554 public: 642 public:
555 typedef T ValueType; 643 typedef T ValueType;
556 644
557 typedef T* iterator; 645 typedef T* iterator;
558 typedef const T* const_iterator; 646 typedef const T* const_iterator;
559 typedef std::reverse_iterator<iterator> reverse_iterator; 647 typedef std::reverse_iterator<iterator> reverse_iterator;
560 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 648 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
561 649
562 Vector() 650 Vector()
651 : m_size(0)
563 { 652 {
564 // Unused slots are initialized to zero so that the visitor and the 653 // Unused slots are initialized to zero so that the visitor and the
565 // finalizer can visit them safely. canInitializeWithMemset tells us 654 // finalizer can visit them safely. canInitializeWithMemset tells us
566 // that the class does not expect matching constructor and 655 // that the class does not expect matching constructor and
567 // destructor calls as long as the memory is zeroed. 656 // destructor calls as long as the memory is zeroed.
568 COMPILE_ASSERT(!Allocator::isGarbageCollected || !VectorTraits<T>::n eedsDestruction || VectorTraits<T>::canInitializeWithMemset, ClassHasProblemsWit hFinalizersCalledOnClearedMemory); 657 COMPILE_ASSERT(!Allocator::isGarbageCollected || !VectorTraits<T>::n eedsDestruction || VectorTraits<T>::canInitializeWithMemset, ClassHasProblemsWit hFinalizersCalledOnClearedMemory);
569 COMPILE_ASSERT(!WTF::IsPolymorphic<T>::value || !VectorTraits<T>::ca nInitializeWithMemset, CantInitializeWithMemsetIfThereIsAVtable); 658 COMPILE_ASSERT(!WTF::IsPolymorphic<T>::value || !VectorTraits<T>::ca nInitializeWithMemset, CantInitializeWithMemsetIfThereIsAVtable);
570 m_size = 0;
571 } 659 }
572 660
573 explicit Vector(size_t size) 661 explicit Vector(size_t size)
574 : Base(size) 662 : Base(size)
575 { 663 {
664 setSize(size);
576 // Unused slots are initialized to zero so that the visitor and the 665 // Unused slots are initialized to zero so that the visitor and the
577 // finalizer can visit them safely. canInitializeWithMemset tells us 666 // finalizer can visit them safely. canInitializeWithMemset tells us
578 // that the class does not expect matching constructor and 667 // that the class does not expect matching constructor and
579 // destructor calls as long as the memory is zeroed. 668 // destructor calls as long as the memory is zeroed.
580 COMPILE_ASSERT(!Allocator::isGarbageCollected || !VectorTraits<T>::n eedsDestruction || VectorTraits<T>::canInitializeWithMemset, ClassHasProblemsWit hFinalizersCalledOnClearedMemory); 669 COMPILE_ASSERT(!Allocator::isGarbageCollected || !VectorTraits<T>::n eedsDestruction || VectorTraits<T>::canInitializeWithMemset, ClassHasProblemsWit hFinalizersCalledOnClearedMemory);
581 m_size = size;
582 TypeOperations::initialize(begin(), end()); 670 TypeOperations::initialize(begin(), end());
583 } 671 }
584 672
585 // Off-GC-heap vectors: Destructor should be called. 673 // Off-GC-heap vectors: Destructor should be called.
586 // On-GC-heap vectors: Destructor should be called for inline buffers 674 // On-GC-heap vectors: Destructor should be called for inline buffers
587 // (if any) but destructor shouldn't be called for vector backing since 675 // (if any) but destructor shouldn't be called for vector backing since
588 // it is managed by the traced GC heap. 676 // it is managed by the traced GC heap.
589 void finalize() 677 void finalize()
590 { 678 {
591 if (!inlineCapacity) { 679 if (!inlineCapacity) {
592 if (LIKELY(!Base::buffer())) 680 if (LIKELY(!Base::buffer()))
593 return; 681 return;
594 } 682 }
595 if (LIKELY(m_size) && !(Allocator::isGarbageCollected && this->hasOu tOfLineBuffer())) { 683 if (LIKELY(size()) && !(Allocator::isGarbageCollected && this->hasOu tOfLineBuffer())) {
596 TypeOperations::destruct(begin(), end()); 684 TypeOperations::destruct(begin(), end());
597 m_size = 0; // Partial protection against use-after-free. 685 setSize(0); // Partial protection against use-after-free.
598 } 686 }
599 687
600 Base::destruct(); 688 Base::destruct();
601 } 689 }
602 690
603 void finalizeGarbageCollectedObject() 691 void finalizeGarbageCollectedObject()
604 { 692 {
605 finalize(); 693 finalize();
606 } 694 }
607 695
608 Vector(const Vector&); 696 Vector(const Vector&);
609 template<size_t otherCapacity> 697 template<size_t otherInlineCapacity>
610 explicit Vector(const Vector<T, otherCapacity, Allocator>&); 698 explicit Vector(const Vector<T, otherInlineCapacity, Allocator>&);
611 699
612 Vector& operator=(const Vector&); 700 Vector& operator=(const Vector&);
613 template<size_t otherCapacity> 701 template<size_t otherInlineCapacity>
614 Vector& operator=(const Vector<T, otherCapacity, Allocator>&); 702 Vector& operator=(const Vector<T, otherInlineCapacity, Allocator>&);
615 703
616 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 704 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
617 Vector(Vector&&); 705 Vector(Vector&&);
618 Vector& operator=(Vector&&); 706 Vector& operator=(Vector&&);
619 #endif 707 #endif
620 708
621 size_t size() const { return m_size; }
622 size_t capacity() const { return Base::capacity(); } 709 size_t capacity() const { return Base::capacity(); }
623 bool isEmpty() const { return !size(); } 710 bool isEmpty() const { return !size(); }
624 711
625 T& at(size_t i) 712 T& at(size_t i)
626 { 713 {
627 RELEASE_ASSERT(i < size()); 714 RELEASE_ASSERT(i < size());
628 return Base::buffer()[i]; 715 return Base::buffer()[i];
629 } 716 }
630 const T& at(size_t i) const 717 const T& at(size_t i) const
631 { 718 {
632 RELEASE_ASSERT(i < size()); 719 RELEASE_ASSERT(i < size());
633 return Base::buffer()[i]; 720 return Base::buffer()[i];
634 } 721 }
635 722
636 T& operator[](size_t i) { return at(i); } 723 T& operator[](size_t i) { return at(i); }
637 const T& operator[](size_t i) const { return at(i); } 724 const T& operator[](size_t i) const { return at(i); }
638 725
639 T* data() { return Base::buffer(); } 726 T* data() { return Base::buffer(); }
640 const T* data() const { return Base::buffer(); } 727 const T* data() const { return Base::buffer(); }
641 728
642 iterator begin() { return data(); } 729 iterator begin() { return data(); }
643 iterator end() { return begin() + m_size; } 730 iterator end() { return begin() + size(); }
644 const_iterator begin() const { return data(); } 731 const_iterator begin() const { return data(); }
645 const_iterator end() const { return begin() + m_size; } 732 const_iterator end() const { return begin() + size(); }
646 733
647 reverse_iterator rbegin() { return reverse_iterator(end()); } 734 reverse_iterator rbegin() { return reverse_iterator(end()); }
648 reverse_iterator rend() { return reverse_iterator(begin()); } 735 reverse_iterator rend() { return reverse_iterator(begin()); }
649 const_reverse_iterator rbegin() const { return const_reverse_iterator(en d()); } 736 const_reverse_iterator rbegin() const { return const_reverse_iterator(en d()); }
650 const_reverse_iterator rend() const { return const_reverse_iterator(begi n()); } 737 const_reverse_iterator rend() const { return const_reverse_iterator(begi n()); }
651 738
652 T& first() { return at(0); } 739 T& first() { return at(0); }
653 const T& first() const { return at(0); } 740 const T& first() const { return at(0); }
654 T& last() { return at(size() - 1); } 741 T& last() { return at(size() - 1); }
655 const T& last() const { return at(size() - 1); } 742 const T& last() const { return at(size() - 1); }
(...skipping 12 matching lines...) Expand all
668 { 755 {
669 if (size() * 2 < capacity()) 756 if (size() * 2 < capacity())
670 shrinkCapacity(size() + size() / 4 + 1); 757 shrinkCapacity(size() + size() / 4 + 1);
671 } 758 }
672 759
673 void clear() { shrinkCapacity(0); } 760 void clear() { shrinkCapacity(0); }
674 761
675 template<typename U> void append(const U*, size_t); 762 template<typename U> void append(const U*, size_t);
676 template<typename U> void append(const U&); 763 template<typename U> void append(const U&);
677 template<typename U> void uncheckedAppend(const U& val); 764 template<typename U> void uncheckedAppend(const U& val);
678 template<typename U, size_t otherCapacity, typename V> void appendVector (const Vector<U, otherCapacity, V>&); 765 template<typename U, size_t otherInlineCapacity, typename V> void append Vector(const Vector<U, otherInlineCapacity, V>&);
679 766
680 template<typename U> void insert(size_t position, const U*, size_t); 767 template<typename U> void insert(size_t position, const U*, size_t);
681 template<typename U> void insert(size_t position, const U&); 768 template<typename U> void insert(size_t position, const U&);
682 template<typename U, size_t c, typename V> void insert(size_t position, const Vector<U, c, V>&); 769 template<typename U, size_t c, typename V> void insert(size_t position, const Vector<U, c, V>&);
683 770
684 template<typename U> void prepend(const U*, size_t); 771 template<typename U> void prepend(const U*, size_t);
685 template<typename U> void prepend(const U&); 772 template<typename U> void prepend(const U&);
686 template<typename U, size_t c, typename V> void prepend(const Vector<U, c, V>&); 773 template<typename U, size_t c, typename V> void prepend(const Vector<U, c, V>&);
687 774
688 void remove(size_t position); 775 void remove(size_t position);
689 void remove(size_t position, size_t length); 776 void remove(size_t position, size_t length);
690 777
691 void removeLast() 778 void removeLast()
692 { 779 {
693 ASSERT(!isEmpty()); 780 ASSERT(!isEmpty());
694 shrink(size() - 1); 781 shrink(size() - 1);
695 } 782 }
696 783
697 Vector(size_t size, const T& val) 784 Vector(size_t size, const T& val)
698 : Base(size) 785 : Base(size)
699 { 786 {
700 m_size = size; 787 setSize(size);
701 TypeOperations::uninitializedFill(begin(), end(), val); 788 TypeOperations::uninitializedFill(begin(), end(), val);
702 } 789 }
703 790
704 void fill(const T&, size_t); 791 void fill(const T&, size_t);
705 void fill(const T& val) { fill(val, size()); } 792 void fill(const T& val) { fill(val, size()); }
706 793
707 template<typename Iterator> void appendRange(Iterator start, Iterator en d); 794 template<typename Iterator> void appendRange(Iterator start, Iterator en d);
708 795
709 void swap(Vector& other) 796 void swap(Vector& other);
710 {
711 Base::swapVectorBuffer(other);
712 std::swap(m_size, other.m_size);
713 }
714 797
715 void reverse(); 798 void reverse();
716 799
717 void trace(typename Allocator::Visitor*); 800 void trace(typename Allocator::Visitor*);
718 801
802 size_t size() const { return m_size; }
719 private: 803 private:
720 void expandCapacity(size_t newMinCapacity); 804 void expandCapacity(size_t newMinCapacity);
721 const T* expandCapacity(size_t newMinCapacity, const T*); 805 const T* expandCapacity(size_t newMinCapacity, const T*);
722 template<typename U> U* expandCapacity(size_t newMinCapacity, U*); 806 template<typename U> U* expandCapacity(size_t newMinCapacity, U*);
723 void shrinkCapacity(size_t newCapacity); 807 void shrinkCapacity(size_t newCapacity);
724 template<typename U> void appendSlowCase(const U&); 808 template<typename U> void appendSlowCase(const U&);
725 809
726 using Base::m_size; 810 void setSize(unsigned size)
811 {
812 m_size = size;
813 }
814
815 unsigned m_size;
816
727 using Base::buffer; 817 using Base::buffer;
728 using Base::capacity; 818 using Base::capacity;
729 using Base::swapVectorBuffer;
730 using Base::allocateBuffer; 819 using Base::allocateBuffer;
731 using Base::allocationSize; 820 using Base::allocationSize;
732 using Base::clearUnusedSlots; 821 using Base::clearUnusedSlots;
822 using Base::hasOutOfLineBuffer;
823
824 friend class VectorBuffer<T, inlineCapacity, Allocator>;
Mads Ager (chromium) 2014/07/18 11:03:14 Do you need this friend declaration?
Erik Corry 2014/07/22 15:49:26 Removed.
733 }; 825 };
734 826
735 template<typename T, size_t inlineCapacity, typename Allocator> 827 template<typename T, size_t inlineCapacity, typename Allocator>
828 void Vector<T, inlineCapacity, Allocator>::swap(Vector<T, inlineCapacity, Al locator>& other)
829 {
830 Base::swapVectorBuffer(other, Range(0, m_size), Range(0, other.m_size));
831 std::swap(m_size, other.m_size);
832 }
833
834 template<typename T, size_t inlineCapacity, typename Allocator>
736 Vector<T, inlineCapacity, Allocator>::Vector(const Vector& other) 835 Vector<T, inlineCapacity, Allocator>::Vector(const Vector& other)
737 : Base(other.capacity()) 836 : Base(other.capacity())
738 { 837 {
739 m_size = other.size(); 838 setSize(other.size());
740 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); 839 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
741 } 840 }
742 841
743 template<typename T, size_t inlineCapacity, typename Allocator> 842 template<typename T, size_t inlineCapacity, typename Allocator>
744 template<size_t otherCapacity> 843 template<size_t otherInlineCapacity>
745 Vector<T, inlineCapacity, Allocator>::Vector(const Vector<T, otherCapacity, Allocator>& other) 844 Vector<T, inlineCapacity, Allocator>::Vector(const Vector<T, otherInlineCapa city, Allocator>& other)
746 : Base(other.capacity()) 845 : Base(other.capacity())
747 { 846 {
748 m_size = other.size(); 847 setSize(other.size());
749 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); 848 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin());
750 } 849 }
751 850
752 template<typename T, size_t inlineCapacity, typename Allocator> 851 template<typename T, size_t inlineCapacity, typename Allocator>
753 Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>:: operator=(const Vector<T, inlineCapacity, Allocator>& other) 852 Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>:: operator=(const Vector<T, inlineCapacity, Allocator>& other)
754 { 853 {
755 if (UNLIKELY(&other == this)) 854 if (UNLIKELY(&other == this))
756 return *this; 855 return *this;
757 856
758 if (size() > other.size()) 857 if (size() > other.size())
759 shrink(other.size()); 858 shrink(other.size());
760 else if (other.size() > capacity()) { 859 else if (other.size() > capacity()) {
761 clear(); 860 clear();
762 reserveCapacity(other.size()); 861 reserveCapacity(other.size());
763 ASSERT(begin()); 862 ASSERT(begin());
764 } 863 }
765 864
766 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStu dio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last 865 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStu dio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last
767 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL 866 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL
768 if (!begin()) 867 if (!begin())
769 return *this; 868 return *this;
770 #endif 869 #endif
771 870
772 std::copy(other.begin(), other.begin() + size(), begin()); 871 std::copy(other.begin(), other.begin() + size(), begin());
773 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), e nd()); 872 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), e nd());
774 m_size = other.size(); 873 setSize(other.size());
775 874
776 return *this; 875 return *this;
777 } 876 }
778 877
779 inline bool typelessPointersAreEqual(const void* a, const void* b) { return a == b; } 878 inline bool typelessPointersAreEqual(const void* a, const void* b) { return a == b; }
780 879
781 template<typename T, size_t inlineCapacity, typename Allocator> 880 template<typename T, size_t inlineCapacity, typename Allocator>
782 template<size_t otherCapacity> 881 template<size_t otherInlineCapacity>
783 Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>:: operator=(const Vector<T, otherCapacity, Allocator>& other) 882 Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>:: operator=(const Vector<T, otherInlineCapacity, Allocator>& other)
784 { 883 {
785 // If the inline capacities match, we should call the more specific 884 // If the inline capacities match, we should call the more specific
786 // template. If the inline capacities don't match, the two objects 885 // template. If the inline capacities don't match, the two objects
787 // shouldn't be allocated the same address. 886 // shouldn't be allocated the same address.
788 ASSERT(!typelessPointersAreEqual(&other, this)); 887 ASSERT(!typelessPointersAreEqual(&other, this));
789 888
790 if (size() > other.size()) 889 if (size() > other.size())
791 shrink(other.size()); 890 shrink(other.size());
792 else if (other.size() > capacity()) { 891 else if (other.size() > capacity()) {
793 clear(); 892 clear();
794 reserveCapacity(other.size()); 893 reserveCapacity(other.size());
795 ASSERT(begin()); 894 ASSERT(begin());
796 } 895 }
797 896
798 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStu dio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last 897 // Works around an assert in VS2010. See https://connect.microsoft.com/VisualStu dio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last
799 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL 898 #if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL
800 if (!begin()) 899 if (!begin())
801 return *this; 900 return *this;
802 #endif 901 #endif
803 902
804 std::copy(other.begin(), other.begin() + size(), begin()); 903 std::copy(other.begin(), other.begin() + size(), begin());
805 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), e nd()); 904 TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), e nd());
806 m_size = other.size(); 905 setSize(other.size());
807 906
808 return *this; 907 return *this;
809 } 908 }
810 909
811 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 910 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
812 template<typename T, size_t inlineCapacity, typename Allocator> 911 template<typename T, size_t inlineCapacity, typename Allocator>
813 Vector<T, inlineCapacity, Allocator>::Vector(Vector<T, inlineCapacity, Alloc ator>&& other) 912 Vector<T, inlineCapacity, Allocator>::Vector(Vector<T, inlineCapacity, Alloc ator>&& other)
814 { 913 {
815 m_size = 0; 914 setSize(0);
816 // It's a little weird to implement a move constructor using swap but th is way we 915 // It's a little weird to implement a move constructor using swap but th is way we
817 // don't have to add a move constructor to VectorBuffer. 916 // don't have to add a move constructor to VectorBuffer.
818 swap(other); 917 swap(other);
819 } 918 }
820 919
821 template<typename T, size_t inlineCapacity, typename Allocator> 920 template<typename T, size_t inlineCapacity, typename Allocator>
822 Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>:: operator=(Vector<T, inlineCapacity, Allocator>&& other) 921 Vector<T, inlineCapacity, Allocator>& Vector<T, inlineCapacity, Allocator>:: operator=(Vector<T, inlineCapacity, Allocator>&& other)
823 { 922 {
824 swap(other); 923 swap(other);
825 return *this; 924 return *this;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 if (size() > newSize) 965 if (size() > newSize)
867 shrink(newSize); 966 shrink(newSize);
868 else if (newSize > capacity()) { 967 else if (newSize > capacity()) {
869 clear(); 968 clear();
870 reserveCapacity(newSize); 969 reserveCapacity(newSize);
871 ASSERT(begin()); 970 ASSERT(begin());
872 } 971 }
873 972
874 std::fill(begin(), end(), val); 973 std::fill(begin(), end(), val);
875 TypeOperations::uninitializedFill(end(), begin() + newSize, val); 974 TypeOperations::uninitializedFill(end(), begin() + newSize, val);
876 m_size = newSize; 975 setSize(newSize);
877 } 976 }
878 977
879 template<typename T, size_t inlineCapacity, typename Allocator> 978 template<typename T, size_t inlineCapacity, typename Allocator>
880 template<typename Iterator> 979 template<typename Iterator>
881 void Vector<T, inlineCapacity, Allocator>::appendRange(Iterator start, Itera tor end) 980 void Vector<T, inlineCapacity, Allocator>::appendRange(Iterator start, Itera tor end)
882 { 981 {
883 for (Iterator it = start; it != end; ++it) 982 for (Iterator it = start; it != end; ++it)
884 append(*it); 983 append(*it);
885 } 984 }
886 985
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 } 1018 }
920 1019
921 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> 1020 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U>
922 inline U* Vector<T, inlineCapacity, Allocator>::expandCapacity(size_t newMin Capacity, U* ptr) 1021 inline U* Vector<T, inlineCapacity, Allocator>::expandCapacity(size_t newMin Capacity, U* ptr)
923 { 1022 {
924 expandCapacity(newMinCapacity); 1023 expandCapacity(newMinCapacity);
925 return ptr; 1024 return ptr;
926 } 1025 }
927 1026
928 template<typename T, size_t inlineCapacity, typename Allocator> 1027 template<typename T, size_t inlineCapacity, typename Allocator>
929 inline void Vector<T, inlineCapacity, Allocator>::resize(size_t size) 1028 inline void Vector<T, inlineCapacity, Allocator>::resize(size_t sizeArg)
930 { 1029 {
931 if (size <= m_size) 1030 if (sizeArg <= size())
932 TypeOperations::destruct(begin() + size, end()); 1031 TypeOperations::destruct(begin() + sizeArg, end());
933 else { 1032 else {
934 if (size > capacity()) 1033 if (sizeArg > capacity())
935 expandCapacity(size); 1034 expandCapacity(sizeArg);
936 TypeOperations::initialize(end(), begin() + size); 1035 TypeOperations::initialize(end(), begin() + sizeArg);
937 } 1036 }
938 1037
939 m_size = size; 1038 setSize(sizeArg);
940 } 1039 }
941 1040
942 template<typename T, size_t inlineCapacity, typename Allocator> 1041 template<typename T, size_t inlineCapacity, typename Allocator>
943 void Vector<T, inlineCapacity, Allocator>::shrink(size_t size) 1042 void Vector<T, inlineCapacity, Allocator>::shrink(size_t sizeArg)
944 { 1043 {
945 ASSERT(size <= m_size); 1044 ASSERT(sizeArg <= size());
946 TypeOperations::destruct(begin() + size, end()); 1045 TypeOperations::destruct(begin() + sizeArg, end());
947 clearUnusedSlots(begin() + size, end()); 1046 clearUnusedSlots(begin() + sizeArg, end());
948 m_size = size; 1047 setSize(sizeArg);
949 } 1048 }
950 1049
951 template<typename T, size_t inlineCapacity, typename Allocator> 1050 template<typename T, size_t inlineCapacity, typename Allocator>
952 void Vector<T, inlineCapacity, Allocator>::grow(size_t size) 1051 void Vector<T, inlineCapacity, Allocator>::grow(size_t sizeArg)
953 { 1052 {
954 ASSERT(size >= m_size); 1053 ASSERT(sizeArg >= size());
955 if (size > capacity()) 1054 if (sizeArg > capacity())
956 expandCapacity(size); 1055 expandCapacity(sizeArg);
957 TypeOperations::initialize(end(), begin() + size); 1056 TypeOperations::initialize(end(), begin() + sizeArg);
958 m_size = size; 1057 setSize(sizeArg);
959 } 1058 }
960 1059
961 template<typename T, size_t inlineCapacity, typename Allocator> 1060 template<typename T, size_t inlineCapacity, typename Allocator>
962 void Vector<T, inlineCapacity, Allocator>::reserveCapacity(size_t newCapacit y) 1061 void Vector<T, inlineCapacity, Allocator>::reserveCapacity(size_t newCapacit y)
963 { 1062 {
964 if (UNLIKELY(newCapacity <= capacity())) 1063 if (UNLIKELY(newCapacity <= capacity()))
965 return; 1064 return;
966 T* oldBuffer = begin(); 1065 T* oldBuffer = begin();
967 T* oldEnd = end(); 1066 T* oldEnd = end();
968 Base::allocateBuffer(newCapacity); 1067 Base::allocateBuffer(newCapacity);
969 TypeOperations::move(oldBuffer, oldEnd, begin()); 1068 TypeOperations::move(oldBuffer, oldEnd, begin());
970 Base::deallocateBuffer(oldBuffer); 1069 Base::deallocateBuffer(oldBuffer);
971 } 1070 }
972 1071
973 template<typename T, size_t inlineCapacity, typename Allocator> 1072 template<typename T, size_t inlineCapacity, typename Allocator>
974 inline void Vector<T, inlineCapacity, Allocator>::reserveInitialCapacity(siz e_t initialCapacity) 1073 inline void Vector<T, inlineCapacity, Allocator>::reserveInitialCapacity(siz e_t initialCapacity)
975 { 1074 {
976 ASSERT(!m_size); 1075 ASSERT(!size());
977 ASSERT(capacity() == inlineCapacity); 1076 ASSERT(capacity() == inlineCapacity);
978 if (initialCapacity > inlineCapacity) 1077 if (initialCapacity > inlineCapacity)
979 Base::allocateBuffer(initialCapacity); 1078 Base::allocateBuffer(initialCapacity);
980 } 1079 }
981 1080
982 template<typename T, size_t inlineCapacity, typename Allocator> 1081 template<typename T, size_t inlineCapacity, typename Allocator>
983 void Vector<T, inlineCapacity, Allocator>::shrinkCapacity(size_t newCapacity ) 1082 void Vector<T, inlineCapacity, Allocator>::shrinkCapacity(size_t newCapacity )
984 { 1083 {
985 if (newCapacity >= capacity()) 1084 if (newCapacity >= capacity())
986 return; 1085 return;
(...skipping 18 matching lines...) Expand all
1005 Base::deallocateBuffer(oldBuffer); 1104 Base::deallocateBuffer(oldBuffer);
1006 } 1105 }
1007 1106
1008 // Templatizing these is better than just letting the conversion happen impl icitly, 1107 // Templatizing these is better than just letting the conversion happen impl icitly,
1009 // because for instance it allows a PassRefPtr to be appended to a RefPtr ve ctor 1108 // because for instance it allows a PassRefPtr to be appended to a RefPtr ve ctor
1010 // without refcount thrash. 1109 // without refcount thrash.
1011 1110
1012 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> 1111 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U>
1013 void Vector<T, inlineCapacity, Allocator>::append(const U* data, size_t data Size) 1112 void Vector<T, inlineCapacity, Allocator>::append(const U* data, size_t data Size)
1014 { 1113 {
1015 size_t newSize = m_size + dataSize; 1114 size_t newSize = size() + dataSize;
1016 if (newSize > capacity()) { 1115 if (newSize > capacity()) {
1017 data = expandCapacity(newSize, data); 1116 data = expandCapacity(newSize, data);
1018 ASSERT(begin()); 1117 ASSERT(begin());
1019 } 1118 }
1020 RELEASE_ASSERT(newSize >= m_size); 1119 RELEASE_ASSERT(newSize >= size());
1021 T* dest = end(); 1120 T* dest = end();
1022 VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(d ata, &data[dataSize], dest); 1121 VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(d ata, &data[dataSize], dest);
1023 m_size = newSize; 1122 setSize(newSize);
1024 } 1123 }
1025 1124
1026 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> 1125 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U>
1027 ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::append(const U& val ) 1126 ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::append(const U& val )
1028 { 1127 {
1029 if (LIKELY(size() != capacity())) { 1128 if (LIKELY(size() != capacity())) {
1030 new (NotNull, end()) T(val); 1129 new (NotNull, end()) T(val);
1031 ++m_size; 1130 setSize(size() + 1);
1032 return; 1131 return;
1033 } 1132 }
1034 1133
1035 appendSlowCase(val); 1134 appendSlowCase(val);
1036 } 1135 }
1037 1136
1038 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> 1137 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U>
1039 NEVER_INLINE void Vector<T, inlineCapacity, Allocator>::appendSlowCase(const U& val) 1138 NEVER_INLINE void Vector<T, inlineCapacity, Allocator>::appendSlowCase(const U& val)
1040 { 1139 {
1041 ASSERT(size() == capacity()); 1140 ASSERT(size() == capacity());
1042 1141
1043 const U* ptr = &val; 1142 const U* ptr = &val;
1044 ptr = expandCapacity(size() + 1, ptr); 1143 ptr = expandCapacity(size() + 1, ptr);
1045 ASSERT(begin()); 1144 ASSERT(begin());
1046 1145
1047 new (NotNull, end()) T(*ptr); 1146 new (NotNull, end()) T(*ptr);
1048 ++m_size; 1147 setSize(size() + 1);
1049 } 1148 }
1050 1149
1051 // This version of append saves a branch in the case where you know that the 1150 // This version of append saves a branch in the case where you know that the
1052 // vector's capacity is large enough for the append to succeed. 1151 // vector's capacity is large enough for the append to succeed.
1053 1152
1054 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> 1153 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U>
1055 ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::uncheckedAppend(con st U& val) 1154 ALWAYS_INLINE void Vector<T, inlineCapacity, Allocator>::uncheckedAppend(con st U& val)
1056 { 1155 {
1057 ASSERT(size() < capacity()); 1156 ASSERT(size() < capacity());
1058 const U* ptr = &val; 1157 const U* ptr = &val;
1059 new (NotNull, end()) T(*ptr); 1158 new (NotNull, end()) T(*ptr);
1060 ++m_size; 1159 setSize(size() + 1);
1061 } 1160 }
1062 1161
1063 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U, size_t otherCapacity, typename OtherAllocator> 1162 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U, size_t otherInlineCapacity, typename OtherAllocator>
1064 inline void Vector<T, inlineCapacity, Allocator>::appendVector(const Vector< U, otherCapacity, OtherAllocator>& val) 1163 inline void Vector<T, inlineCapacity, Allocator>::appendVector(const Vector< U, otherInlineCapacity, OtherAllocator>& val)
1065 { 1164 {
1066 append(val.begin(), val.size()); 1165 append(val.begin(), val.size());
1067 } 1166 }
1068 1167
1069 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> 1168 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U>
1070 void Vector<T, inlineCapacity, Allocator>::insert(size_t position, const U* data, size_t dataSize) 1169 void Vector<T, inlineCapacity, Allocator>::insert(size_t position, const U* data, size_t dataSize)
1071 { 1170 {
1072 RELEASE_ASSERT(position <= size()); 1171 RELEASE_ASSERT(position <= size());
1073 size_t newSize = m_size + dataSize; 1172 size_t newSize = size() + dataSize;
1074 if (newSize > capacity()) { 1173 if (newSize > capacity()) {
1075 data = expandCapacity(newSize, data); 1174 data = expandCapacity(newSize, data);
1076 ASSERT(begin()); 1175 ASSERT(begin());
1077 } 1176 }
1078 RELEASE_ASSERT(newSize >= m_size); 1177 RELEASE_ASSERT(newSize >= size());
1079 T* spot = begin() + position; 1178 T* spot = begin() + position;
1080 TypeOperations::moveOverlapping(spot, end(), spot + dataSize); 1179 TypeOperations::moveOverlapping(spot, end(), spot + dataSize);
1081 VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(d ata, &data[dataSize], spot); 1180 VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(d ata, &data[dataSize], spot);
1082 m_size = newSize; 1181 setSize(newSize);
1083 } 1182 }
1084 1183
1085 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> 1184 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U>
1086 inline void Vector<T, inlineCapacity, Allocator>::insert(size_t position, co nst U& val) 1185 inline void Vector<T, inlineCapacity, Allocator>::insert(size_t position, co nst U& val)
1087 { 1186 {
1088 RELEASE_ASSERT(position <= size()); 1187 RELEASE_ASSERT(position <= size());
1089 const U* data = &val; 1188 const U* data = &val;
1090 if (size() == capacity()) { 1189 if (size() == capacity()) {
1091 data = expandCapacity(size() + 1, data); 1190 data = expandCapacity(size() + 1, data);
1092 ASSERT(begin()); 1191 ASSERT(begin());
1093 } 1192 }
1094 T* spot = begin() + position; 1193 T* spot = begin() + position;
1095 TypeOperations::moveOverlapping(spot, end(), spot + 1); 1194 TypeOperations::moveOverlapping(spot, end(), spot + 1);
1096 new (NotNull, spot) T(*data); 1195 new (NotNull, spot) T(*data);
1097 ++m_size; 1196 setSize(size() + 1);
1098 } 1197 }
1099 1198
1100 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U, size_t c, typename OtherAllocator> 1199 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U, size_t c, typename OtherAllocator>
1101 inline void Vector<T, inlineCapacity, Allocator>::insert(size_t position, co nst Vector<U, c, OtherAllocator>& val) 1200 inline void Vector<T, inlineCapacity, Allocator>::insert(size_t position, co nst Vector<U, c, OtherAllocator>& val)
1102 { 1201 {
1103 insert(position, val.begin(), val.size()); 1202 insert(position, val.begin(), val.size());
1104 } 1203 }
1105 1204
1106 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> 1205 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U>
1107 void Vector<T, inlineCapacity, Allocator>::prepend(const U* data, size_t dat aSize) 1206 void Vector<T, inlineCapacity, Allocator>::prepend(const U* data, size_t dat aSize)
(...skipping 14 matching lines...) Expand all
1122 } 1221 }
1123 1222
1124 template<typename T, size_t inlineCapacity, typename Allocator> 1223 template<typename T, size_t inlineCapacity, typename Allocator>
1125 inline void Vector<T, inlineCapacity, Allocator>::remove(size_t position) 1224 inline void Vector<T, inlineCapacity, Allocator>::remove(size_t position)
1126 { 1225 {
1127 RELEASE_ASSERT(position < size()); 1226 RELEASE_ASSERT(position < size());
1128 T* spot = begin() + position; 1227 T* spot = begin() + position;
1129 spot->~T(); 1228 spot->~T();
1130 TypeOperations::moveOverlapping(spot + 1, end(), spot); 1229 TypeOperations::moveOverlapping(spot + 1, end(), spot);
1131 clearUnusedSlots(end() - 1, end()); 1230 clearUnusedSlots(end() - 1, end());
1132 --m_size; 1231 setSize(size() - 1);
1133 } 1232 }
1134 1233
1135 template<typename T, size_t inlineCapacity, typename Allocator> 1234 template<typename T, size_t inlineCapacity, typename Allocator>
1136 inline void Vector<T, inlineCapacity, Allocator>::remove(size_t position, si ze_t length) 1235 inline void Vector<T, inlineCapacity, Allocator>::remove(size_t position, si ze_t length)
1137 { 1236 {
1138 ASSERT_WITH_SECURITY_IMPLICATION(position <= size()); 1237 ASSERT_WITH_SECURITY_IMPLICATION(position <= size());
1139 RELEASE_ASSERT(position + length <= size()); 1238 RELEASE_ASSERT(position + length <= size());
1140 T* beginSpot = begin() + position; 1239 T* beginSpot = begin() + position;
1141 T* endSpot = beginSpot + length; 1240 T* endSpot = beginSpot + length;
1142 TypeOperations::destruct(beginSpot, endSpot); 1241 TypeOperations::destruct(beginSpot, endSpot);
1143 TypeOperations::moveOverlapping(endSpot, end(), beginSpot); 1242 TypeOperations::moveOverlapping(endSpot, end(), beginSpot);
1144 clearUnusedSlots(end() - length, end()); 1243 clearUnusedSlots(end() - length, end());
1145 m_size -= length; 1244 setSize(size() - length);
1146 } 1245 }
1147 1246
1148 template<typename T, size_t inlineCapacity, typename Allocator> 1247 template<typename T, size_t inlineCapacity, typename Allocator>
1149 inline void Vector<T, inlineCapacity, Allocator>::reverse() 1248 inline void Vector<T, inlineCapacity, Allocator>::reverse()
1150 { 1249 {
1151 for (size_t i = 0; i < m_size / 2; ++i) 1250 for (size_t i = 0; i < size() / 2; ++i)
1152 std::swap(at(i), at(m_size - 1 - i)); 1251 std::swap(at(i), at(size() - 1 - i));
1153 } 1252 }
1154 1253
1155 template<typename T, size_t inlineCapacity, typename Allocator> 1254 template<typename T, size_t inlineCapacity, typename Allocator>
1156 void deleteAllValues(const Vector<T, inlineCapacity, Allocator>& collection) 1255 void deleteAllValues(const Vector<T, inlineCapacity, Allocator>& collection)
1157 { 1256 {
1158 typedef typename Vector<T, inlineCapacity, Allocator>::const_iterator it erator; 1257 typedef typename Vector<T, inlineCapacity, Allocator>::const_iterator it erator;
1159 iterator end = collection.end(); 1258 iterator end = collection.end();
1160 for (iterator it = collection.begin(); it != end; ++it) 1259 for (iterator it = collection.begin(); it != end; ++it)
1161 delete *it; 1260 delete *it;
1162 } 1261 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 struct NeedsTracing<Vector<T, N> > { 1302 struct NeedsTracing<Vector<T, N> > {
1204 static const bool value = false; 1303 static const bool value = false;
1205 }; 1304 };
1206 #endif 1305 #endif
1207 1306
1208 } // namespace WTF 1307 } // namespace WTF
1209 1308
1210 using WTF::Vector; 1309 using WTF::Vector;
1211 1310
1212 #endif // WTF_Vector_h 1311 #endif // WTF_Vector_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698