OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #ifndef SkTemplates_DEFINED | 10 #ifndef SkTemplates_DEFINED |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 } | 473 } |
474 | 474 |
475 private: | 475 private: |
476 T* fPtr; | 476 T* fPtr; |
477 union { | 477 union { |
478 uint32_t fStorage32[(N*sizeof(T) + 3) >> 2]; | 478 uint32_t fStorage32[(N*sizeof(T) + 3) >> 2]; |
479 T fTStorage[1]; // do NOT want to invoke T::T() | 479 T fTStorage[1]; // do NOT want to invoke T::T() |
480 }; | 480 }; |
481 }; | 481 }; |
482 | 482 |
| 483 ////////////////////////////////////////////////////////////////////////////////
////////////////// |
| 484 |
| 485 /** |
| 486 * Pass the object and the storage that was offered during SkInPlaceNewCheck, a
nd this will |
| 487 * safely destroy (and free if it was dynamically allocated) the object. |
| 488 */ |
| 489 template <typename T> void SkInPlaceDeleteCheck(T* obj, void* storage) { |
| 490 if (storage == obj) { |
| 491 obj->~T(); |
| 492 } else { |
| 493 SkDELETE(obj); |
| 494 } |
| 495 } |
| 496 |
| 497 /** |
| 498 * Allocates T, using storage if it is large enough, and allocating on the heap
(via new) if |
| 499 * storage is not large enough. |
| 500 * |
| 501 * obj = SkInPlaceNewCheck<Type>(storage, size); |
| 502 * ... |
| 503 * SkInPlaceDeleteCheck(obj, storage); |
| 504 */ |
| 505 template <typename T> T* SkInPlaceNewCheck(void* storage, size_t size) { |
| 506 return (sizeof(T) <= size) ? new (storage) T : SkNEW(T); |
| 507 } |
| 508 |
| 509 template <typename T, typename A1, typename A2, typename A3> |
| 510 T* SkInPlaceNewCheck(void* storage, size_t size, const A1& a1, const A2& a2, con
st A3& a3) { |
| 511 return (sizeof(T) <= size) ? new (storage) T(a1, a2, a3) : SkNEW_ARGS(T, (a1
, a2, a3)); |
| 512 } |
| 513 |
483 /** | 514 /** |
484 * Reserves memory that is aligned on double and pointer boundaries. | 515 * Reserves memory that is aligned on double and pointer boundaries. |
485 * Hopefully this is sufficient for all practical purposes. | 516 * Hopefully this is sufficient for all practical purposes. |
486 */ | 517 */ |
487 template <size_t N> class SkAlignedSStorage : SkNoncopyable { | 518 template <size_t N> class SkAlignedSStorage : SkNoncopyable { |
488 public: | 519 public: |
| 520 size_t size() const { return N; } |
489 void* get() { return fData; } | 521 void* get() { return fData; } |
490 const void* get() const { return fData; } | 522 const void* get() const { return fData; } |
| 523 |
491 private: | 524 private: |
492 union { | 525 union { |
493 void* fPtr; | 526 void* fPtr; |
494 double fDouble; | 527 double fDouble; |
495 char fData[N]; | 528 char fData[N]; |
496 }; | 529 }; |
497 }; | 530 }; |
498 | 531 |
499 /** | 532 /** |
500 * Reserves memory that is aligned on double and pointer boundaries. | 533 * Reserves memory that is aligned on double and pointer boundaries. |
501 * Hopefully this is sufficient for all practical purposes. Otherwise, | 534 * Hopefully this is sufficient for all practical purposes. Otherwise, |
502 * we have to do some arcane trickery to determine alignment of non-POD | 535 * we have to do some arcane trickery to determine alignment of non-POD |
503 * types. Lifetime of the memory is the lifetime of the object. | 536 * types. Lifetime of the memory is the lifetime of the object. |
504 */ | 537 */ |
505 template <int N, typename T> class SkAlignedSTStorage : SkNoncopyable { | 538 template <int N, typename T> class SkAlignedSTStorage : SkNoncopyable { |
506 public: | 539 public: |
507 /** | 540 /** |
508 * Returns void* because this object does not initialize the | 541 * Returns void* because this object does not initialize the |
509 * memory. Use placement new for types that require a cons. | 542 * memory. Use placement new for types that require a cons. |
510 */ | 543 */ |
511 void* get() { return fStorage.get(); } | 544 void* get() { return fStorage.get(); } |
512 private: | 545 private: |
513 SkAlignedSStorage<sizeof(T)*N> fStorage; | 546 SkAlignedSStorage<sizeof(T)*N> fStorage; |
514 }; | 547 }; |
515 | 548 |
516 #endif | 549 #endif |
OLD | NEW |