2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
13 #include <SupportDefs.h>
23 template<typename Element
>
27 Array(const Array
<Element
>& other
);
30 inline int32
Size() const { return fSize
; }
31 inline int32
Count() const { return fSize
; }
32 inline bool IsEmpty() const { return fSize
== 0; }
33 inline Element
* Elements() const { return fElements
; }
35 inline bool Add(const Element
& element
);
36 inline bool AddUninitialized(int32 elementCount
);
37 inline bool Insert(const Element
& element
, int32 index
);
38 inline bool InsertUninitialized(int32 index
, int32 count
);
39 inline bool Remove(int32 index
, int32 count
= 1);
42 inline void MakeEmpty();
44 inline Element
& ElementAt(int32 index
);
45 inline const Element
& ElementAt(int32 index
) const;
47 inline Element
& operator[](int32 index
);
48 inline const Element
& operator[](int32 index
) const;
50 Array
<Element
>& operator=(const Array
<Element
>& other
);
53 static const int32 kMinCapacity
= 8;
55 bool _Resize(int32 index
, int32 delta
);
64 template<typename Element
>
65 Array
<Element
>::Array()
74 template<typename Element
>
75 Array
<Element
>::Array(const Array
<Element
>& other
)
85 template<typename Element
>
86 Array
<Element
>::~Array()
92 template<typename Element
>
94 Array
<Element
>::Add(const Element
& element
)
96 if (!_Resize(fSize
, 1))
99 fElements
[fSize
] = element
;
105 template<typename Element
>
107 Array
<Element
>::AddUninitialized(int32 elementCount
)
109 return InsertUninitialized(fSize
, elementCount
);
113 template<typename Element
>
115 Array
<Element
>::Insert(const Element
& element
, int32 index
)
117 if (index
< 0 || index
> fSize
)
120 if (!_Resize(index
, 1))
123 fElements
[index
] = element
;
129 template<typename Element
>
131 Array
<Element
>::InsertUninitialized(int32 index
, int32 count
)
133 if (index
< 0 || index
> fSize
|| count
< 0)
138 if (!_Resize(index
, count
))
146 template<typename Element
>
148 Array
<Element
>::Remove(int32 index
, int32 count
)
150 if (index
< 0 || count
< 0 || index
+ count
> fSize
) {
153 snprintf(buffer
, sizeof(buffer
), "Array::Remove(): index: %" B_PRId32
154 ", count: %" B_PRId32
", size: %" B_PRId32
, index
, count
, fSize
);
162 if (index
+ count
< fSize
) {
163 memmove(fElements
+ index
, fElements
+ index
+ count
,
164 sizeof(Element
) * (fSize
- index
- count
));
167 _Resize(index
, -count
);
174 template<typename Element
>
176 Array
<Element
>::Clear()
189 template<typename Element
>
191 Array
<Element
>::MakeEmpty()
197 template<typename Element
>
199 Array
<Element
>::ElementAt(int32 index
)
201 return fElements
[index
];
205 template<typename Element
>
207 Array
<Element
>::ElementAt(int32 index
) const
209 return fElements
[index
];
213 template<typename Element
>
215 Array
<Element
>::operator[](int32 index
)
217 return fElements
[index
];
221 template<typename Element
>
223 Array
<Element
>::operator[](int32 index
) const
225 return fElements
[index
];
229 template<typename Element
>
231 Array
<Element
>::operator=(const Array
<Element
>& other
)
235 if (other
.fSize
> 0 && _Resize(0, other
.fSize
)) {
237 memcpy(fElements
, other
.fElements
, fSize
* sizeof(Element
));
244 template<typename Element
>
246 Array
<Element
>::_Resize(int32 index
, int32 delta
)
248 // determine new capacity
249 int32 newSize
= fSize
+ delta
;
250 int32 newCapacity
= kMinCapacity
;
251 while (newCapacity
< newSize
)
254 if (newCapacity
== fCapacity
) {
255 // the capacity doesn't change -- still make room for/remove elements
258 // leave a gap of delta elements
259 memmove(fElements
+ index
+ delta
, fElements
+ index
,
260 (fSize
- index
) * sizeof(Element
));
261 } else if (index
< fSize
+ delta
) {
262 // drop -delta elements
263 memcpy(fElements
+ index
, fElements
+ index
- delta
,
264 (fSize
- index
+ delta
) * sizeof(Element
));
271 // allocate new array
272 Element
* elements
= (Element
*)malloc(newCapacity
* sizeof(Element
));
273 if (elements
== NULL
)
277 memcpy(elements
, fElements
, index
* sizeof(Element
));
280 // leave a gap of delta elements
281 memcpy(elements
+ index
+ delta
, fElements
+ index
,
282 (fSize
- index
) * sizeof(Element
));
283 } else if (index
< fSize
+ delta
) {
284 // drop -delta elements
285 memcpy(elements
+ index
, fElements
+ index
- delta
,
286 (fSize
- index
+ delta
) * sizeof(Element
));
291 fElements
= elements
;
292 fCapacity
= newCapacity
;
297 } // namespace BPrivate
300 using BPrivate::Array
;