Index: src/core/SkTLList.h |
diff --git a/src/core/SkTLList.h b/src/core/SkTLList.h |
index 17e8a6a85e55da458a3fe38805c73f52c795736e..1a8c54cb7c208ebfe099247338d18de12e356a9f 100644 |
--- a/src/core/SkTLList.h |
+++ b/src/core/SkTLList.h |
@@ -12,12 +12,6 @@ |
#include "SkTypes.h" |
#include <utility> |
-template <typename T> class SkTLList; |
-template <typename T> |
-inline void* operator new(size_t, SkTLList<T>* list, |
- typename SkTLList<T>::Placement placement, |
- const typename SkTLList<T>::Iter& location); |
- |
/** Doubly-linked list of objects. The objects' lifetimes are controlled by the list. I.e. the |
the list creates the objects and they are deleted upon removal. This class block-allocates |
space for entries based on a param passed to the constructor. |
@@ -27,9 +21,11 @@ inline void* operator new(size_t, SkTLList<T>* list, |
SkNEW_INSERT_IN_LLIST_AFTER(list, location, type_name, args) |
where list is a SkTLList<type_name>*, location is an iterator, and args is the paren-surrounded |
constructor arguments for type_name. These macros behave like addBefore() and addAfter(). |
+ |
+ allocCnt is the number of objects to allocate as a group. In the worst case fragmentation |
+ each object is using the space required for allocCnt unfragmented objects. |
*/ |
-template <typename T> |
-class SkTLList : SkNoncopyable { |
+template <typename T, unsigned int N> class SkTLList : SkNoncopyable { |
private: |
struct Block; |
struct Node { |
@@ -40,13 +36,9 @@ private: |
typedef SkTInternalLList<Node> NodeList; |
public: |
- |
class Iter; |
- /** allocCnt is the number of objects to allocate as a group. In the worst case fragmentation |
- each object is using the space required for allocCnt unfragmented objects. */ |
- SkTLList(int allocCnt = 1) : fCount(0), fAllocCnt(allocCnt) { |
- SkASSERT(allocCnt > 0); |
+ SkTLList() : fCount(0) { |
this->validate(); |
} |
@@ -59,7 +51,7 @@ public: |
Block* block = node->fBlock; |
node = iter.next(); |
if (0 == --block->fNodesInUse) { |
- for (int i = 0; i < fAllocCnt; ++i) { |
+ for (unsigned int i = 0; i < N; ++i) { |
block->fNodes[i].~Node(); |
} |
sk_free(block); |
@@ -221,23 +213,21 @@ public: |
private: |
struct Block { |
int fNodesInUse; |
- Node fNodes[1]; |
+ Node fNodes[N]; |
}; |
- size_t blockSize() const { return sizeof(Block) + sizeof(Node) * (fAllocCnt-1); } |
- |
Node* createNode() { |
Node* node = fFreeList.head(); |
if (node) { |
fFreeList.remove(node); |
++node->fBlock->fNodesInUse; |
} else { |
- Block* block = reinterpret_cast<Block*>(sk_malloc_throw(this->blockSize())); |
+ Block* block = reinterpret_cast<Block*>(sk_malloc_throw(sizeof(Block))); |
node = &block->fNodes[0]; |
new (node) Node; |
node->fBlock = block; |
block->fNodesInUse = 1; |
- for (int i = 1; i < fAllocCnt; ++i) { |
+ for (unsigned int i = 1; i < N; ++i) { |
new (block->fNodes + i) Node; |
fFreeList.addToHead(block->fNodes + i); |
block->fNodes[i].fBlock = block; |
@@ -253,7 +243,7 @@ private: |
SkTCast<T*>(node->fObj)->~T(); |
if (0 == --node->fBlock->fNodesInUse) { |
Block* block = node->fBlock; |
- for (int i = 0; i < fAllocCnt; ++i) { |
+ for (unsigned int i = 0; i < N; ++i) { |
if (block->fNodes + i != node) { |
fFreeList.remove(block->fNodes + i); |
} |
@@ -271,7 +261,7 @@ private: |
#ifdef SK_DEBUG |
SkASSERT((0 == fCount) == fList.isEmpty()); |
SkASSERT((0 != fCount) || fFreeList.isEmpty()); |
- |
+ |
fList.validate(); |
fFreeList.validate(); |
typename NodeList::Iter iter; |
@@ -279,11 +269,11 @@ private: |
while (freeNode) { |
SkASSERT(fFreeList.isInList(freeNode)); |
Block* block = freeNode->fBlock; |
- SkASSERT(block->fNodesInUse > 0 && block->fNodesInUse < fAllocCnt); |
+ SkASSERT(block->fNodesInUse > 0 && (unsigned)block->fNodesInUse < N); |
int activeCnt = 0; |
int freeCnt = 0; |
- for (int i = 0; i < fAllocCnt; ++i) { |
+ for (unsigned int i = 0; i < N; ++i) { |
bool free = fFreeList.isInList(block->fNodes + i); |
bool active = fList.isInList(block->fNodes + i); |
SkASSERT(free != active); |
@@ -300,11 +290,11 @@ private: |
++count; |
SkASSERT(fList.isInList(activeNode)); |
Block* block = activeNode->fBlock; |
- SkASSERT(block->fNodesInUse > 0 && block->fNodesInUse <= fAllocCnt); |
+ SkASSERT(block->fNodesInUse > 0 && (unsigned)block->fNodesInUse <= N); |
int activeCnt = 0; |
int freeCnt = 0; |
- for (int i = 0; i < fAllocCnt; ++i) { |
+ for (unsigned int i = 0; i < N; ++i) { |
bool free = fFreeList.isInList(block->fNodes + i); |
bool active = fList.isInList(block->fNodes + i); |
SkASSERT(free != active); |
@@ -321,8 +311,6 @@ private: |
NodeList fList; |
NodeList fFreeList; |
int fCount; |
- int fAllocCnt; |
- |
}; |
#endif |