| 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 ALWAYS_INLINE T* buffer() { return m_buffer; } | 279 T* buffer() { return m_buffer; } |
| 280 ALWAYS_INLINE const T* buffer() const { return m_buffer; } | 280 const T* buffer() const { return m_buffer; } |
| 281 ALWAYS_INLINE size_t capacity() const { return m_capacity; } | 281 size_t capacity() const { return m_capacity; } |
| 282 | 282 |
| 283 protected: | 283 protected: |
| 284 VectorBufferBase() | 284 VectorBufferBase() |
| 285 : m_buffer(0) | 285 : m_buffer(0) |
| 286 , m_capacity(0) | 286 , m_capacity(0) |
| 287 , m_size(0) | |
| 288 { | 287 { |
| 289 } | 288 } |
| 290 | 289 |
| 291 VectorBufferBase(T* buffer, size_t capacity) | 290 VectorBufferBase(T* buffer, size_t capacity) |
| 292 : m_buffer(buffer) | 291 : m_buffer(buffer) |
| 293 , m_capacity(capacity) | 292 , m_capacity(capacity) |
| 294 , m_size(0) | |
| 295 { | 293 { |
| 296 } | 294 } |
| 297 | 295 |
| 298 ~VectorBufferBase() | 296 ~VectorBufferBase() |
| 299 { | 297 { |
| 298 m_buffer = 0; |
| 299 m_size = 0; |
| 300 } | 300 } |
| 301 | 301 |
| 302 T* m_buffer; | 302 T* m_buffer; |
| 303 unsigned m_capacity; | 303 unsigned m_capacity; |
| 304 unsigned m_size; | 304 unsigned m_size; |
| 305 }; | 305 }; |
| 306 | 306 |
| 307 template<typename T, size_t inlineCapacity> | 307 template<typename T, size_t inlineCapacity> |
| 308 class VectorBuffer; | 308 class VectorBuffer; |
| 309 | 309 |
| 310 template<typename T> | 310 template<typename T> |
| 311 class VectorBuffer<T, 0> : private VectorBufferBase<T> { | 311 class VectorBuffer<T, 0> : private VectorBufferBase<T> { |
| 312 private: | 312 private: |
| 313 typedef VectorBufferBase<T> Base; | 313 typedef VectorBufferBase<T> Base; |
| 314 public: | 314 public: |
| 315 VectorBuffer() | 315 VectorBuffer() |
| 316 { | 316 { |
| 317 } | 317 } |
| 318 | 318 |
| 319 VectorBuffer(size_t capacity) | 319 VectorBuffer(size_t capacity) |
| 320 { | 320 { |
| 321 // 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 |
| 322 // allocation on some systems. | 322 // allocation on some systems. |
| 323 if (capacity) | 323 if (capacity) |
| 324 allocateBuffer(capacity); | 324 allocateBuffer(capacity); |
| 325 } | 325 } |
| 326 | 326 |
| 327 ~VectorBuffer() | |
| 328 { | |
| 329 } | |
| 330 | |
| 331 void deallocateBuffer(T* bufferToDeallocate) | 327 void deallocateBuffer(T* bufferToDeallocate) |
| 332 { | 328 { |
| 333 fastFree(bufferToDeallocate); | 329 fastFree(bufferToDeallocate); |
| 334 } | 330 } |
| 335 | 331 |
| 336 void clearBufferPointer() | 332 void clearBufferPointer() |
| 337 { | 333 { |
| 338 m_buffer = 0; | 334 m_buffer = 0; |
| 339 m_capacity = 0; | 335 m_capacity = 0; |
| 340 } | 336 } |
| 341 | 337 |
| 342 void destruct() | 338 ~VectorBuffer() |
| 343 { | 339 { |
| 344 deallocateBuffer(m_buffer); | 340 deallocateBuffer(buffer()); |
| 345 m_buffer = 0; | |
| 346 } | 341 } |
| 347 | 342 |
| 348 void swap(VectorBuffer<T, 0>& other) | 343 void swap(VectorBuffer<T, 0>& other) |
| 349 { | 344 { |
| 350 std::swap(m_buffer, other.m_buffer); | 345 std::swap(m_buffer, other.m_buffer); |
| 351 std::swap(m_capacity, other.m_capacity); | 346 std::swap(m_capacity, other.m_capacity); |
| 352 } | 347 } |
| 353 | 348 |
| 354 void restoreInlineBufferIfNeeded() { } | 349 void restoreInlineBufferIfNeeded() { } |
| 355 | 350 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 379 { | 374 { |
| 380 } | 375 } |
| 381 | 376 |
| 382 VectorBuffer(size_t capacity) | 377 VectorBuffer(size_t capacity) |
| 383 : Base(inlineBuffer(), inlineCapacity) | 378 : Base(inlineBuffer(), inlineCapacity) |
| 384 { | 379 { |
| 385 if (capacity > inlineCapacity) | 380 if (capacity > inlineCapacity) |
| 386 Base::allocateBuffer(capacity); | 381 Base::allocateBuffer(capacity); |
| 387 } | 382 } |
| 388 | 383 |
| 389 ~VectorBuffer() | |
| 390 { | |
| 391 } | |
| 392 | |
| 393 void deallocateBuffer(T* bufferToDeallocate) | 384 void deallocateBuffer(T* bufferToDeallocate) |
| 394 { | 385 { |
| 395 if (UNLIKELY(bufferToDeallocate != inlineBuffer())) | 386 if (UNLIKELY(bufferToDeallocate != inlineBuffer())) |
| 396 fastFree(bufferToDeallocate); | 387 fastFree(bufferToDeallocate); |
| 397 } | 388 } |
| 398 | 389 |
| 399 void destruct() | |
| 400 { | |
| 401 deallocateBuffer(m_buffer); | |
| 402 m_buffer = 0; | |
| 403 } | |
| 404 | |
| 405 void clearBufferPointer() | 390 void clearBufferPointer() |
| 406 { | 391 { |
| 407 m_buffer = 0; | 392 m_buffer = 0; |
| 408 m_capacity = 0; | 393 m_capacity = 0; |
| 409 } | 394 } |
| 410 | 395 |
| 396 ~VectorBuffer() |
| 397 { |
| 398 deallocateBuffer(buffer()); |
| 399 } |
| 400 |
| 411 void allocateBuffer(size_t newCapacity) | 401 void allocateBuffer(size_t newCapacity) |
| 412 { | 402 { |
| 413 // FIXME: This should ASSERT(!m_buffer) to catch misuse/leaks. | 403 // FIXME: This should ASSERT(!m_buffer) to catch misuse/leaks. |
| 414 if (newCapacity > inlineCapacity) | 404 if (newCapacity > inlineCapacity) |
| 415 Base::allocateBuffer(newCapacity); | 405 Base::allocateBuffer(newCapacity); |
| 416 else { | 406 else { |
| 417 m_buffer = inlineBuffer(); | 407 m_buffer = inlineBuffer(); |
| 418 m_capacity = inlineCapacity; | 408 m_capacity = inlineCapacity; |
| 419 } | 409 } |
| 420 } | 410 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 using Base::capacity; | 454 using Base::capacity; |
| 465 | 455 |
| 466 protected: | 456 protected: |
| 467 using Base::m_size; | 457 using Base::m_size; |
| 468 | 458 |
| 469 private: | 459 private: |
| 470 using Base::m_buffer; | 460 using Base::m_buffer; |
| 471 using Base::m_capacity; | 461 using Base::m_capacity; |
| 472 | 462 |
| 473 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); | 463 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); |
| 474 ALWAYS_INLINE T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inli
neBuffer.buffer); } | 464 T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffe
r); } |
| 475 ALWAYS_INLINE const T* inlineBuffer() const { return reinterpret_cast_pt
r<const T*>(m_inlineBuffer.buffer); } | 465 const T* inlineBuffer() const { return reinterpret_cast_ptr<const T*>(m_
inlineBuffer.buffer); } |
| 476 | 466 |
| 477 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; | 467 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; |
| 478 }; | 468 }; |
| 479 | 469 |
| 480 template<typename T, size_t inlineCapacity = 0> | 470 template<typename T, size_t inlineCapacity = 0> |
| 481 class Vector : private VectorBuffer<T, inlineCapacity> { | 471 class Vector : private VectorBuffer<T, inlineCapacity> { |
| 482 WTF_MAKE_FAST_ALLOCATED; | 472 WTF_MAKE_FAST_ALLOCATED; |
| 483 private: | 473 private: |
| 484 typedef VectorBuffer<T, inlineCapacity> Base; | 474 typedef VectorBuffer<T, inlineCapacity> Base; |
| 485 typedef VectorTypeOperations<T> TypeOperations; | 475 typedef VectorTypeOperations<T> TypeOperations; |
| 486 | 476 |
| 487 public: | 477 public: |
| 488 typedef T ValueType; | 478 typedef T ValueType; |
| 489 | 479 |
| 490 typedef T* iterator; | 480 typedef T* iterator; |
| 491 typedef const T* const_iterator; | 481 typedef const T* const_iterator; |
| 492 typedef std::reverse_iterator<iterator> reverse_iterator; | 482 typedef std::reverse_iterator<iterator> reverse_iterator; |
| 493 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 483 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
| 494 | 484 |
| 495 Vector() | 485 Vector() |
| 496 { | 486 { |
| 497 // Initialization occurs on the base classes. | 487 m_size = 0; |
| 498 } | 488 } |
| 499 | 489 |
| 500 explicit Vector(size_t size) | 490 explicit Vector(size_t size) |
| 501 : Base(size) | 491 : Base(size) |
| 502 { | 492 { |
| 503 m_size = size; | 493 m_size = size; |
| 504 TypeOperations::initialize(begin(), end()); | 494 TypeOperations::initialize(begin(), end()); |
| 505 } | 495 } |
| 506 | 496 |
| 507 ~Vector() | 497 ~Vector() |
| 508 { | 498 { |
| 509 if (!inlineCapacity) { | 499 shrink(0); |
| 510 if (LIKELY(!Base::buffer())) | |
| 511 return; | |
| 512 shrink(0); | |
| 513 } else { | |
| 514 if (UNLIKELY(m_size)) | |
| 515 shrink(0); | |
| 516 } | |
| 517 Base::destruct(); | |
| 518 } | 500 } |
| 519 | 501 |
| 520 Vector(const Vector&); | 502 Vector(const Vector&); |
| 521 template<size_t otherCapacity> | 503 template<size_t otherCapacity> |
| 522 Vector(const Vector<T, otherCapacity>&); | 504 Vector(const Vector<T, otherCapacity>&); |
| 523 | 505 |
| 524 Vector& operator=(const Vector&); | 506 Vector& operator=(const Vector&); |
| 525 template<size_t otherCapacity> | 507 template<size_t otherCapacity> |
| 526 Vector& operator=(const Vector<T, otherCapacity>&); | 508 Vector& operator=(const Vector<T, otherCapacity>&); |
| 527 | 509 |
| 528 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | 510 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) |
| 529 Vector(Vector&&); | 511 Vector(Vector&&); |
| 530 Vector& operator=(Vector&&); | 512 Vector& operator=(Vector&&); |
| 531 #endif | 513 #endif |
| 532 | 514 |
| 533 ALWAYS_INLINE size_t size() const { return m_size; } | 515 size_t size() const { return m_size; } |
| 534 ALWAYS_INLINE size_t capacity() const { return Base::capacity(); } | 516 size_t capacity() const { return Base::capacity(); } |
| 535 ALWAYS_INLINE bool isEmpty() const { return !size(); } | 517 bool isEmpty() const { return !size(); } |
| 536 | 518 |
| 537 T& at(size_t i) | 519 T& at(size_t i) |
| 538 { | 520 { |
| 539 RELEASE_ASSERT(i < size()); | 521 RELEASE_ASSERT(i < size()); |
| 540 return Base::buffer()[i]; | 522 return Base::buffer()[i]; |
| 541 } | 523 } |
| 542 const T& at(size_t i) const | 524 const T& at(size_t i) const |
| 543 { | 525 { |
| 544 RELEASE_ASSERT(i < size()); | 526 RELEASE_ASSERT(i < size()); |
| 545 return Base::buffer()[i]; | 527 return Base::buffer()[i]; |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 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) |
| 1082 { | 1064 { |
| 1083 return !(a == b); | 1065 return !(a == b); |
| 1084 } | 1066 } |
| 1085 | 1067 |
| 1086 } // namespace WTF | 1068 } // namespace WTF |
| 1087 | 1069 |
| 1088 using WTF::Vector; | 1070 using WTF::Vector; |
| 1089 | 1071 |
| 1090 #endif // WTF_Vector_h | 1072 #endif // WTF_Vector_h |
| OLD | NEW |