2 * Copyright 2009-2013, Stephan Aßmus <superstippi@gmx.de>
3 * All rights reserved. Distributed under the terms of the MIT License.
13 #include <SupportDefs.h>
16 template <typename ItemType
, bool PlainOldData
, uint32 BlockSize
= 8>
18 typedef List
<ItemType
, PlainOldData
, BlockSize
> SelfType
;
28 List(const SelfType
& other
)
40 // Make sure to call destructors of old objects.
46 SelfType
& operator=(const SelfType
& other
)
52 if (_Resize(other
.fCount
))
53 memcpy(fItems
, other
.fItems
, fCount
* sizeof(ItemType
));
55 // Make sure to call destructors of old objects.
56 // NOTE: Another option would be to use
57 // ItemType::operator=(const ItemType& other), but then
58 // we would need to be carefull which objects are already
59 // initialized. Also ItemType would be required to implement the
60 // operator, while doing it this way requires only a copy
63 for (uint32 i
= 0; i
< other
.fCount
; i
++) {
64 if (!Add(other
.ItemAtFast(i
)))
71 bool operator==(const SelfType
& other
) const
76 if (fCount
!= other
.fCount
)
82 return memcmp(fItems
, other
.fItems
,
83 fCount
* sizeof(ItemType
)) == 0;
85 for (uint32 i
= 0; i
< other
.fCount
; i
++) {
86 if (ItemAtFast(i
) != other
.ItemAtFast(i
))
93 bool operator!=(const SelfType
& other
) const
95 return !(*this == other
);
103 inline bool IsEmpty() const
108 inline int32
CountItems() const
113 inline bool Add(const ItemType
& copyFrom
)
115 if (_Resize(fCount
+ 1)) {
116 ItemType
* item
= fItems
+ fCount
- 1;
117 // Initialize the new object from the original.
119 new (item
) ItemType(copyFrom
);
127 inline bool Add(const ItemType
& copyFrom
, int32 index
)
129 if (index
< 0 || index
> (int32
)fCount
)
132 if (!_Resize(fCount
+ 1))
135 int32 nextIndex
= index
+ 1;
136 if ((int32
)fCount
> nextIndex
)
137 memmove(fItems
+ nextIndex
, fItems
+ index
,
138 (fCount
- nextIndex
) * sizeof(ItemType
));
140 ItemType
* item
= fItems
+ index
;
142 new (item
) ItemType(copyFrom
);
158 inline bool Remove(int32 index
)
160 if (index
< 0 || index
>= (int32
)fCount
)
164 ItemType
* object
= fItems
+ index
;
168 int32 nextIndex
= index
+ 1;
169 if ((int32
)fCount
> nextIndex
) {
170 memcpy(fItems
+ index
, fItems
+ nextIndex
,
171 (fCount
- nextIndex
) * sizeof(ItemType
));
178 inline bool Remove(const ItemType
& item
)
180 return Remove(IndexOf(item
));
183 inline bool Replace(int32 index
, const ItemType
& copyFrom
)
185 if (index
< 0 || index
>= (int32
)fCount
)
188 ItemType
* item
= fItems
+ index
;
189 // Initialize the new object from the original.
192 new (item
) ItemType(copyFrom
);
198 inline const ItemType
& ItemAt(int32 index
) const
200 if (index
< 0 || index
>= (int32
)fCount
)
202 return ItemAtFast(index
);
205 inline const ItemType
& ItemAtFast(int32 index
) const
207 return *(fItems
+ index
);
210 inline const ItemType
& LastItem() const
214 return ItemAt((int32
)fCount
- 1);
217 inline int32
IndexOf(const ItemType
& item
) const
219 for (uint32 i
= 0; i
< fCount
; i
++) {
220 if (ItemAtFast(i
) == item
)
226 inline bool Contains(const ItemType
& item
) const
228 return IndexOf(item
) >= 0;
232 inline bool _Resize(uint32 count
)
234 if (count
> fAllocatedCount
) {
235 uint32 allocationCount
= (count
+ BlockSize
- 1)
236 / BlockSize
* BlockSize
;
237 ItemType
* items
= reinterpret_cast<ItemType
*>(
238 realloc(fItems
, allocationCount
* sizeof(ItemType
)));
243 fAllocatedCount
= allocationCount
;
244 } else if (count
< fCount
) {
246 // Uninit old objects so that we can re-use them when
247 // appending objects without the need to re-allocate.
248 for (uint32 i
= count
; i
< fCount
; i
++) {
249 ItemType
* object
= fItems
+ i
;
261 uint32 fAllocatedCount
;