OLD | NEW |
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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 void reallocateBuffer(size_t newCapacity) | 269 void reallocateBuffer(size_t newCapacity) |
270 { | 270 { |
271 ASSERT(shouldReallocateBuffer(newCapacity)); | 271 ASSERT(shouldReallocateBuffer(newCapacity)); |
272 // Using "unsigned" is not a limitation because Chromium's max mallo
c() is 2GB even on 64-bit. | 272 // Using "unsigned" is not a limitation because Chromium's max mallo
c() is 2GB even on 64-bit. |
273 RELEASE_ASSERT(newCapacity <= std::numeric_limits<unsigned>::max() /
sizeof(T)); | 273 RELEASE_ASSERT(newCapacity <= std::numeric_limits<unsigned>::max() /
sizeof(T)); |
274 size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T)); | 274 size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T)); |
275 m_capacity = sizeToAllocate / sizeof(T); | 275 m_capacity = sizeToAllocate / sizeof(T); |
276 m_buffer = static_cast<T*>(fastRealloc(m_buffer, sizeToAllocate)); | 276 m_buffer = static_cast<T*>(fastRealloc(m_buffer, sizeToAllocate)); |
277 } | 277 } |
278 | 278 |
279 void deallocateBuffer(T* bufferToDeallocate) | |
280 { | |
281 if (!bufferToDeallocate) | |
282 return; | |
283 | |
284 if (m_buffer == bufferToDeallocate) { | |
285 m_buffer = 0; | |
286 m_capacity = 0; | |
287 } | |
288 | |
289 fastFree(bufferToDeallocate); | |
290 } | |
291 | |
292 T* buffer() { return m_buffer; } | 279 T* buffer() { return m_buffer; } |
293 const T* buffer() const { return m_buffer; } | 280 const T* buffer() const { return m_buffer; } |
294 size_t capacity() const { return m_capacity; } | 281 size_t capacity() const { return m_capacity; } |
295 | 282 |
296 T* releaseBuffer() | |
297 { | |
298 T* buffer = m_buffer; | |
299 m_buffer = 0; | |
300 m_capacity = 0; | |
301 return buffer; | |
302 } | |
303 | |
304 protected: | 283 protected: |
305 VectorBufferBase() | 284 VectorBufferBase() |
306 : m_buffer(0) | 285 : m_buffer(0) |
307 , m_capacity(0) | 286 , m_capacity(0) |
308 { | 287 { |
309 } | 288 } |
310 | 289 |
311 VectorBufferBase(T* buffer, size_t capacity) | 290 VectorBufferBase(T* buffer, size_t capacity) |
312 : m_buffer(buffer) | 291 : m_buffer(buffer) |
313 , m_capacity(capacity) | 292 , m_capacity(capacity) |
314 { | 293 { |
315 } | 294 } |
316 | 295 |
317 ~VectorBufferBase() | 296 ~VectorBufferBase() |
318 { | 297 { |
319 // FIXME: It would be nice to find a way to ASSERT that m_buffer has
n't leaked here. | 298 m_buffer = 0; |
| 299 m_size = 0; |
320 } | 300 } |
321 | 301 |
322 T* m_buffer; | 302 T* m_buffer; |
323 unsigned m_capacity; | 303 unsigned m_capacity; |
324 unsigned m_size; | 304 unsigned m_size; |
325 }; | 305 }; |
326 | 306 |
327 template<typename T, size_t inlineCapacity> | 307 template<typename T, size_t inlineCapacity> |
328 class VectorBuffer; | 308 class VectorBuffer; |
329 | 309 |
330 template<typename T> | 310 template<typename T> |
331 class VectorBuffer<T, 0> : private VectorBufferBase<T> { | 311 class VectorBuffer<T, 0> : private VectorBufferBase<T> { |
332 private: | 312 private: |
333 typedef VectorBufferBase<T> Base; | 313 typedef VectorBufferBase<T> Base; |
334 public: | 314 public: |
335 VectorBuffer() | 315 VectorBuffer() |
336 { | 316 { |
337 } | 317 } |
338 | 318 |
339 VectorBuffer(size_t capacity) | 319 VectorBuffer(size_t capacity) |
340 { | 320 { |
341 // Calling malloc(0) might take a lock and may actually do an | 321 // Calling malloc(0) might take a lock and may actually do an |
342 // allocation on some systems. | 322 // allocation on some systems. |
343 if (capacity) | 323 if (capacity) |
344 allocateBuffer(capacity); | 324 allocateBuffer(capacity); |
345 } | 325 } |
346 | 326 |
| 327 void deallocateBuffer(T* bufferToDeallocate) |
| 328 { |
| 329 fastFree(bufferToDeallocate); |
| 330 } |
| 331 |
| 332 void clearBufferPointer() |
| 333 { |
| 334 m_buffer = 0; |
| 335 m_capacity = 0; |
| 336 } |
| 337 |
347 ~VectorBuffer() | 338 ~VectorBuffer() |
348 { | 339 { |
349 deallocateBuffer(buffer()); | 340 deallocateBuffer(buffer()); |
350 } | 341 } |
351 | 342 |
352 void swap(VectorBuffer<T, 0>& other) | 343 void swap(VectorBuffer<T, 0>& other) |
353 { | 344 { |
354 std::swap(m_buffer, other.m_buffer); | 345 std::swap(m_buffer, other.m_buffer); |
355 std::swap(m_capacity, other.m_capacity); | 346 std::swap(m_capacity, other.m_capacity); |
356 } | 347 } |
357 | 348 |
358 void restoreInlineBufferIfNeeded() { } | 349 void restoreInlineBufferIfNeeded() { } |
359 | 350 |
360 using Base::allocateBuffer; | 351 using Base::allocateBuffer; |
361 using Base::shouldReallocateBuffer; | 352 using Base::shouldReallocateBuffer; |
362 using Base::reallocateBuffer; | 353 using Base::reallocateBuffer; |
363 using Base::deallocateBuffer; | |
364 | 354 |
365 using Base::buffer; | 355 using Base::buffer; |
366 using Base::capacity; | 356 using Base::capacity; |
367 | 357 |
368 using Base::releaseBuffer; | |
369 | |
370 protected: | 358 protected: |
371 using Base::m_size; | 359 using Base::m_size; |
372 | 360 |
373 private: | 361 private: |
374 using Base::m_buffer; | 362 using Base::m_buffer; |
375 using Base::m_capacity; | 363 using Base::m_capacity; |
376 }; | 364 }; |
377 | 365 |
378 template<typename T, size_t inlineCapacity> | 366 template<typename T, size_t inlineCapacity> |
379 class VectorBuffer : private VectorBufferBase<T> { | 367 class VectorBuffer : private VectorBufferBase<T> { |
380 WTF_MAKE_NONCOPYABLE(VectorBuffer); | 368 WTF_MAKE_NONCOPYABLE(VectorBuffer); |
381 private: | 369 private: |
382 typedef VectorBufferBase<T> Base; | 370 typedef VectorBufferBase<T> Base; |
383 public: | 371 public: |
384 VectorBuffer() | 372 VectorBuffer() |
385 : Base(inlineBuffer(), inlineCapacity) | 373 : Base(inlineBuffer(), inlineCapacity) |
386 { | 374 { |
387 } | 375 } |
388 | 376 |
389 VectorBuffer(size_t capacity) | 377 VectorBuffer(size_t capacity) |
390 : Base(inlineBuffer(), inlineCapacity) | 378 : Base(inlineBuffer(), inlineCapacity) |
391 { | 379 { |
392 if (capacity > inlineCapacity) | 380 if (capacity > inlineCapacity) |
393 Base::allocateBuffer(capacity); | 381 Base::allocateBuffer(capacity); |
394 } | 382 } |
395 | 383 |
| 384 void deallocateBuffer(T* bufferToDeallocate) |
| 385 { |
| 386 if (UNLIKELY(bufferToDeallocate != inlineBuffer())) |
| 387 fastFree(bufferToDeallocate); |
| 388 } |
| 389 |
| 390 void clearBufferPointer() |
| 391 { |
| 392 m_buffer = 0; |
| 393 m_capacity = 0; |
| 394 } |
| 395 |
396 ~VectorBuffer() | 396 ~VectorBuffer() |
397 { | 397 { |
398 deallocateBuffer(buffer()); | 398 deallocateBuffer(buffer()); |
399 } | 399 } |
400 | 400 |
401 void allocateBuffer(size_t newCapacity) | 401 void allocateBuffer(size_t newCapacity) |
402 { | 402 { |
403 // FIXME: This should ASSERT(!m_buffer) to catch misuse/leaks. | 403 // FIXME: This should ASSERT(!m_buffer) to catch misuse/leaks. |
404 if (newCapacity > inlineCapacity) | 404 if (newCapacity > inlineCapacity) |
405 Base::allocateBuffer(newCapacity); | 405 Base::allocateBuffer(newCapacity); |
406 else { | 406 else { |
407 m_buffer = inlineBuffer(); | 407 m_buffer = inlineBuffer(); |
408 m_capacity = inlineCapacity; | 408 m_capacity = inlineCapacity; |
409 } | 409 } |
410 } | 410 } |
411 | 411 |
412 void deallocateBuffer(T* bufferToDeallocate) | |
413 { | |
414 if (bufferToDeallocate == inlineBuffer()) | |
415 return; | |
416 Base::deallocateBuffer(bufferToDeallocate); | |
417 } | |
418 | |
419 bool shouldReallocateBuffer(size_t newCapacity) const | 412 bool shouldReallocateBuffer(size_t newCapacity) const |
420 { | 413 { |
421 // We cannot reallocate the inline buffer. | 414 // We cannot reallocate the inline buffer. |
422 return Base::shouldReallocateBuffer(newCapacity) && std::min(static_
cast<size_t>(m_capacity), newCapacity) > inlineCapacity; | 415 return Base::shouldReallocateBuffer(newCapacity) && std::min(static_
cast<size_t>(m_capacity), newCapacity) > inlineCapacity; |
423 } | 416 } |
424 | 417 |
425 void reallocateBuffer(size_t newCapacity) | 418 void reallocateBuffer(size_t newCapacity) |
426 { | 419 { |
427 ASSERT(shouldReallocateBuffer(newCapacity)); | 420 ASSERT(shouldReallocateBuffer(newCapacity)); |
428 Base::reallocateBuffer(newCapacity); | 421 Base::reallocateBuffer(newCapacity); |
(...skipping 24 matching lines...) Expand all Loading... |
453 { | 446 { |
454 if (m_buffer) | 447 if (m_buffer) |
455 return; | 448 return; |
456 m_buffer = inlineBuffer(); | 449 m_buffer = inlineBuffer(); |
457 m_capacity = inlineCapacity; | 450 m_capacity = inlineCapacity; |
458 } | 451 } |
459 | 452 |
460 using Base::buffer; | 453 using Base::buffer; |
461 using Base::capacity; | 454 using Base::capacity; |
462 | 455 |
463 T* releaseBuffer() | |
464 { | |
465 if (buffer() == inlineBuffer()) | |
466 return 0; | |
467 return Base::releaseBuffer(); | |
468 } | |
469 | |
470 protected: | 456 protected: |
471 using Base::m_size; | 457 using Base::m_size; |
472 | 458 |
473 private: | 459 private: |
474 using Base::m_buffer; | 460 using Base::m_buffer; |
475 using Base::m_capacity; | 461 using Base::m_capacity; |
476 | 462 |
477 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); | 463 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); |
478 T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffe
r); } | 464 T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffe
r); } |
479 const T* inlineBuffer() const { return reinterpret_cast_ptr<const T*>(m_
inlineBuffer.buffer); } | 465 const T* inlineBuffer() const { return reinterpret_cast_ptr<const T*>(m_
inlineBuffer.buffer); } |
(...skipping 18 matching lines...) Expand all Loading... |
498 | 484 |
499 Vector() | 485 Vector() |
500 { | 486 { |
501 m_size = 0; | 487 m_size = 0; |
502 } | 488 } |
503 | 489 |
504 explicit Vector(size_t size) | 490 explicit Vector(size_t size) |
505 : Base(size) | 491 : Base(size) |
506 { | 492 { |
507 m_size = size; | 493 m_size = size; |
508 if (begin()) | 494 TypeOperations::initialize(begin(), end()); |
509 TypeOperations::initialize(begin(), end()); | |
510 } | 495 } |
511 | 496 |
512 ~Vector() | 497 ~Vector() |
513 { | 498 { |
514 if (m_size) | 499 shrink(0); |
515 shrink(0); | |
516 } | 500 } |
517 | 501 |
518 Vector(const Vector&); | 502 Vector(const Vector&); |
519 template<size_t otherCapacity> | 503 template<size_t otherCapacity> |
520 Vector(const Vector<T, otherCapacity>&); | 504 Vector(const Vector<T, otherCapacity>&); |
521 | 505 |
522 Vector& operator=(const Vector&); | 506 Vector& operator=(const Vector&); |
523 template<size_t otherCapacity> | 507 template<size_t otherCapacity> |
524 Vector& operator=(const Vector<T, otherCapacity>&); | 508 Vector& operator=(const Vector<T, otherCapacity>&); |
525 | 509 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 void removeLast() | 582 void removeLast() |
599 { | 583 { |
600 ASSERT(!isEmpty()); | 584 ASSERT(!isEmpty()); |
601 shrink(size() - 1); | 585 shrink(size() - 1); |
602 } | 586 } |
603 | 587 |
604 Vector(size_t size, const T& val) | 588 Vector(size_t size, const T& val) |
605 : Base(size) | 589 : Base(size) |
606 { | 590 { |
607 m_size = size; | 591 m_size = size; |
608 if (begin()) | 592 TypeOperations::uninitializedFill(begin(), end(), val); |
609 TypeOperations::uninitializedFill(begin(), end(), val); | |
610 } | 593 } |
611 | 594 |
612 void fill(const T&, size_t); | 595 void fill(const T&, size_t); |
613 void fill(const T& val) { fill(val, size()); } | 596 void fill(const T& val) { fill(val, size()); } |
614 | 597 |
615 template<typename Iterator> void appendRange(Iterator start, Iterator en
d); | 598 template<typename Iterator> void appendRange(Iterator start, Iterator en
d); |
616 | 599 |
617 T* releaseBuffer(); | |
618 | |
619 void swap(Vector<T, inlineCapacity>& other) | 600 void swap(Vector<T, inlineCapacity>& other) |
620 { | 601 { |
621 std::swap(m_size, other.m_size); | 602 std::swap(m_size, other.m_size); |
622 Base::swap(other); | 603 Base::swap(other); |
623 } | 604 } |
624 | 605 |
625 void reverse(); | 606 void reverse(); |
626 | 607 |
627 private: | 608 private: |
628 void expandCapacity(size_t newMinCapacity); | 609 void expandCapacity(size_t newMinCapacity); |
629 const T* expandCapacity(size_t newMinCapacity, const T*); | 610 const T* expandCapacity(size_t newMinCapacity, const T*); |
630 template<typename U> U* expandCapacity(size_t newMinCapacity, U*); | 611 template<typename U> U* expandCapacity(size_t newMinCapacity, U*); |
631 template<typename U> void appendSlowCase(const U&); | 612 template<typename U> void appendSlowCase(const U&); |
632 | 613 |
633 using Base::m_size; | 614 using Base::m_size; |
634 using Base::buffer; | 615 using Base::buffer; |
635 using Base::capacity; | 616 using Base::capacity; |
636 using Base::swap; | 617 using Base::swap; |
637 using Base::allocateBuffer; | 618 using Base::allocateBuffer; |
638 using Base::deallocateBuffer; | |
639 using Base::shouldReallocateBuffer; | 619 using Base::shouldReallocateBuffer; |
640 using Base::reallocateBuffer; | 620 using Base::reallocateBuffer; |
641 using Base::restoreInlineBufferIfNeeded; | 621 using Base::restoreInlineBufferIfNeeded; |
642 using Base::releaseBuffer; | |
643 }; | 622 }; |
644 | 623 |
645 template<typename T, size_t inlineCapacity> | 624 template<typename T, size_t inlineCapacity> |
646 Vector<T, inlineCapacity>::Vector(const Vector& other) | 625 Vector<T, inlineCapacity>::Vector(const Vector& other) |
647 : Base(other.capacity()) | 626 : Base(other.capacity()) |
648 { | 627 { |
649 m_size = other.size(); | 628 m_size = other.size(); |
650 if (begin()) | 629 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); |
651 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin(
)); | |
652 } | 630 } |
653 | 631 |
654 template<typename T, size_t inlineCapacity> | 632 template<typename T, size_t inlineCapacity> |
655 template<size_t otherCapacity> | 633 template<size_t otherCapacity> |
656 Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other) | 634 Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other) |
657 : Base(other.capacity()) | 635 : Base(other.capacity()) |
658 { | 636 { |
659 m_size = other.size(); | 637 m_size = other.size(); |
660 if (begin()) | 638 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); |
661 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin(
)); | |
662 } | 639 } |
663 | 640 |
664 template<typename T, size_t inlineCapacity> | 641 template<typename T, size_t inlineCapacity> |
665 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector
<T, inlineCapacity>& other) | 642 Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector
<T, inlineCapacity>& other) |
666 { | 643 { |
667 if (&other == this) | 644 if (UNLIKELY(&other == this)) |
668 return *this; | 645 return *this; |
669 | 646 |
670 if (size() > other.size()) | 647 if (size() > other.size()) |
671 shrink(other.size()); | 648 shrink(other.size()); |
672 else if (other.size() > capacity()) { | 649 else if (other.size() > capacity()) { |
673 clear(); | 650 clear(); |
674 reserveCapacity(other.size()); | 651 reserveCapacity(other.size()); |
675 ASSERT(begin()); | 652 ASSERT(begin()); |
676 } | 653 } |
677 | 654 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 } | 799 } |
823 | 800 |
824 template<typename T, size_t inlineCapacity> | 801 template<typename T, size_t inlineCapacity> |
825 inline void Vector<T, inlineCapacity>::resize(size_t size) | 802 inline void Vector<T, inlineCapacity>::resize(size_t size) |
826 { | 803 { |
827 if (size <= m_size) | 804 if (size <= m_size) |
828 TypeOperations::destruct(begin() + size, end()); | 805 TypeOperations::destruct(begin() + size, end()); |
829 else { | 806 else { |
830 if (size > capacity()) | 807 if (size > capacity()) |
831 expandCapacity(size); | 808 expandCapacity(size); |
832 if (begin()) | 809 TypeOperations::initialize(end(), begin() + size); |
833 TypeOperations::initialize(end(), begin() + size); | |
834 } | 810 } |
835 | 811 |
836 m_size = size; | 812 m_size = size; |
837 } | 813 } |
838 | 814 |
839 template<typename T, size_t inlineCapacity> | 815 template<typename T, size_t inlineCapacity> |
840 void Vector<T, inlineCapacity>::shrink(size_t size) | 816 void Vector<T, inlineCapacity>::shrink(size_t size) |
841 { | 817 { |
842 ASSERT(size <= m_size); | 818 ASSERT(size <= m_size); |
843 TypeOperations::destruct(begin() + size, end()); | 819 TypeOperations::destruct(begin() + size, end()); |
844 m_size = size; | 820 m_size = size; |
845 } | 821 } |
846 | 822 |
847 template<typename T, size_t inlineCapacity> | 823 template<typename T, size_t inlineCapacity> |
848 void Vector<T, inlineCapacity>::grow(size_t size) | 824 void Vector<T, inlineCapacity>::grow(size_t size) |
849 { | 825 { |
850 ASSERT(size >= m_size); | 826 ASSERT(size >= m_size); |
851 if (size > capacity()) | 827 if (size > capacity()) |
852 expandCapacity(size); | 828 expandCapacity(size); |
853 if (begin()) | 829 TypeOperations::initialize(end(), begin() + size); |
854 TypeOperations::initialize(end(), begin() + size); | |
855 m_size = size; | 830 m_size = size; |
856 } | 831 } |
857 | 832 |
858 template<typename T, size_t inlineCapacity> | 833 template<typename T, size_t inlineCapacity> |
859 void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity) | 834 void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity) |
860 { | 835 { |
861 if (newCapacity <= capacity()) | 836 if (UNLIKELY(newCapacity <= capacity())) |
862 return; | 837 return; |
863 T* oldBuffer = begin(); | 838 T* oldBuffer = begin(); |
864 T* oldEnd = end(); | 839 T* oldEnd = end(); |
865 Base::allocateBuffer(newCapacity); | 840 Base::allocateBuffer(newCapacity); |
866 if (begin()) | 841 TypeOperations::move(oldBuffer, oldEnd, begin()); |
867 TypeOperations::move(oldBuffer, oldEnd, begin()); | |
868 Base::deallocateBuffer(oldBuffer); | 842 Base::deallocateBuffer(oldBuffer); |
869 } | 843 } |
870 | 844 |
871 template<typename T, size_t inlineCapacity> | 845 template<typename T, size_t inlineCapacity> |
872 inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initial
Capacity) | 846 inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initial
Capacity) |
873 { | 847 { |
874 ASSERT(!m_size); | 848 ASSERT(!m_size); |
875 ASSERT(capacity() == inlineCapacity); | 849 ASSERT(capacity() == inlineCapacity); |
876 if (initialCapacity > inlineCapacity) | 850 if (initialCapacity > inlineCapacity) |
877 Base::allocateBuffer(initialCapacity); | 851 Base::allocateBuffer(initialCapacity); |
(...skipping 12 matching lines...) Expand all Loading... |
890 if (newCapacity > 0) { | 864 if (newCapacity > 0) { |
891 if (Base::shouldReallocateBuffer(newCapacity)) { | 865 if (Base::shouldReallocateBuffer(newCapacity)) { |
892 Base::reallocateBuffer(newCapacity); | 866 Base::reallocateBuffer(newCapacity); |
893 return; | 867 return; |
894 } | 868 } |
895 | 869 |
896 T* oldEnd = end(); | 870 T* oldEnd = end(); |
897 Base::allocateBuffer(newCapacity); | 871 Base::allocateBuffer(newCapacity); |
898 if (begin() != oldBuffer) | 872 if (begin() != oldBuffer) |
899 TypeOperations::move(oldBuffer, oldEnd, begin()); | 873 TypeOperations::move(oldBuffer, oldEnd, begin()); |
| 874 } else { |
| 875 Base::clearBufferPointer(); |
900 } | 876 } |
901 | 877 |
902 Base::deallocateBuffer(oldBuffer); | 878 Base::deallocateBuffer(oldBuffer); |
903 Base::restoreInlineBufferIfNeeded(); | 879 Base::restoreInlineBufferIfNeeded(); |
904 } | 880 } |
905 | 881 |
906 // Templatizing these is better than just letting the conversion happen impl
icitly, | 882 // Templatizing these is better than just letting the conversion happen impl
icitly, |
907 // because for instance it allows a PassRefPtr to be appended to a RefPtr ve
ctor | 883 // because for instance it allows a PassRefPtr to be appended to a RefPtr ve
ctor |
908 // without refcount thrash. | 884 // without refcount thrash. |
909 | 885 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1053 } | 1029 } |
1054 | 1030 |
1055 template<typename T, size_t inlineCapacity> | 1031 template<typename T, size_t inlineCapacity> |
1056 inline void Vector<T, inlineCapacity>::reverse() | 1032 inline void Vector<T, inlineCapacity>::reverse() |
1057 { | 1033 { |
1058 for (size_t i = 0; i < m_size / 2; ++i) | 1034 for (size_t i = 0; i < m_size / 2; ++i) |
1059 std::swap(at(i), at(m_size - 1 - i)); | 1035 std::swap(at(i), at(m_size - 1 - i)); |
1060 } | 1036 } |
1061 | 1037 |
1062 template<typename T, size_t inlineCapacity> | 1038 template<typename T, size_t inlineCapacity> |
1063 inline T* Vector<T, inlineCapacity>::releaseBuffer() | |
1064 { | |
1065 T* buffer = Base::releaseBuffer(); | |
1066 if (inlineCapacity && !buffer && m_size) { | |
1067 // If the vector had some data, but no buffer to release, | |
1068 // that means it was using the inline buffer. In that case, | |
1069 // we create a brand new buffer so the caller always gets one. | |
1070 size_t bytes = m_size * sizeof(T); | |
1071 buffer = static_cast<T*>(fastMalloc(bytes)); | |
1072 memcpy(buffer, data(), bytes); | |
1073 } | |
1074 m_size = 0; | |
1075 return buffer; | |
1076 } | |
1077 | |
1078 template<typename T, size_t inlineCapacity> | |
1079 void deleteAllValues(const Vector<T, inlineCapacity>& collection) | 1039 void deleteAllValues(const Vector<T, inlineCapacity>& collection) |
1080 { | 1040 { |
1081 typedef typename Vector<T, inlineCapacity>::const_iterator iterator; | 1041 typedef typename Vector<T, inlineCapacity>::const_iterator iterator; |
1082 iterator end = collection.end(); | 1042 iterator end = collection.end(); |
1083 for (iterator it = collection.begin(); it != end; ++it) | 1043 for (iterator it = collection.begin(); it != end; ++it) |
1084 delete *it; | 1044 delete *it; |
1085 } | 1045 } |
1086 | 1046 |
1087 template<typename T, size_t inlineCapacity> | 1047 template<typename T, size_t inlineCapacity> |
1088 inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b) | 1048 inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b) |
(...skipping 14 matching lines...) Expand all Loading... |
1103 inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, i
nlineCapacity>& b) | 1063 inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, i
nlineCapacity>& b) |
1104 { | 1064 { |
1105 return !(a == b); | 1065 return !(a == b); |
1106 } | 1066 } |
1107 | 1067 |
1108 } // namespace WTF | 1068 } // namespace WTF |
1109 | 1069 |
1110 using WTF::Vector; | 1070 using WTF::Vector; |
1111 | 1071 |
1112 #endif // WTF_Vector_h | 1072 #endif // WTF_Vector_h |
OLD | NEW |