3 Copyright (C) 2005 and later, Cockos Incorporated
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
25 This file provides a simple templated class for a list of pointers. By default this list
26 doesn't free any of the pointers, but you can call Empty(true) or Delete(x,true) to delete the pointer,
27 or you can use Empty(true,free) etc to call free (or any other function).
29 Note: on certain compilers, instantiating with WDL_PtrList<void> bla; will give a warning, since
30 the template will create code for "delete (void *)x;" which isn't technically valid. Oh well.
34 #ifndef _WDL_PTRLIST_H_
35 #define _WDL_PTRLIST_H_
39 template<class PTRTYPE
> class WDL_PtrList
42 explicit WDL_PtrList(int defgran
=4096, int prealloc
=0) : m_buf(defgran
)
44 if (prealloc
>0) m_buf
.Prealloc(prealloc
);
51 void Prealloc(int sz
) { m_buf
.Prealloc(sz
); }
52 void ResizeToCurrent() { m_buf
.ResizeToCurrent(); }
54 PTRTYPE
**GetList() const { return m_buf
.Get(); }
55 PTRTYPE
*Get(INT_PTR index
) const
57 PTRTYPE
**list
= m_buf
.Get();
58 if (list
&& (UINT_PTR
)index
< (UINT_PTR
)m_buf
.GetSize()) return list
[index
];
62 int GetSize(void) const { return m_buf
.GetSize(); }
66 const int l
= GetSize()-1;
68 PTRTYPE
*ret
= m_buf
.Get()[l
];
69 m_buf
.Resize(l
,false);
72 PTRTYPE
*GetLast() const { return Get(GetSize()-1); }
74 int Find(const PTRTYPE
*p
) const
78 PTRTYPE
**list
=m_buf
.Get();
80 const int n
= GetSize();
81 for (x
= 0; x
< n
; x
++) if (list
[x
] == p
) return x
;
85 int FindR(const PTRTYPE
*p
) const
89 PTRTYPE
**list
=m_buf
.Get();
91 while (--x
>= 0) if (list
[x
] == p
) return x
;
96 PTRTYPE
*Add(PTRTYPE
*item
) { return m_buf
.Add(item
) ? item
: NULL
; }
97 void Add(PTRTYPE
**items
, int numitems
) { m_buf
.Add(items
, numitems
); }
99 PTRTYPE
*Set(int index
, PTRTYPE
*item
)
101 PTRTYPE
**list
=m_buf
.Get();
102 if (list
&& index
>= 0 && index
< GetSize()) return list
[index
]=item
;
106 PTRTYPE
*Insert(int index
, PTRTYPE
*item
)
108 const int s
=GetSize();
109 m_buf
.Insert(item
, wdl_clamp(index
,0,s
));
113 template<class SB
, class SB2
> int FindSorted(SB p
, int (*compar
)(SB2 a
, const PTRTYPE
*b
)) const
116 int i
= LowerBound(p
,&m
,compar
);
119 PTRTYPE
*InsertSorted(PTRTYPE
*item
, int (*compar
)(const PTRTYPE
*a
, const PTRTYPE
*b
))
122 return Insert(LowerBound(item
,&m
,compar
),item
);
124 template<class SB
, class SB2
> PTRTYPE
*InsertSorted(PTRTYPE
*item
, SB ref
, int (*compar
)(SB2 a
, const PTRTYPE
*b
))
127 return Insert(LowerBound(ref
,&m
,compar
),item
);
130 void Delete(int index
) { m_buf
.Delete(index
); }
131 void Delete(int index
, bool wantDelete
, void (*delfunc
)(void *)=NULL
)
133 PTRTYPE
**list
=GetList();
135 if (list
&& index
>= 0 && index
< size
)
139 if (delfunc
) delfunc(Get(index
));
140 else delete Get(index
);
142 // if delfunc modified the list this could be unpredictable
143 WDL_ASSERT(size
== GetSize());
144 if (index
< --size
) memmove(list
+index
,list
+index
+1,(unsigned int)sizeof(PTRTYPE
*)*(size
-index
));
145 m_buf
.Resize(size
,false);
148 template<class PT
> void Delete(int index
, PT delfunc
)
150 PTRTYPE
**list
=GetList();
152 if (list
&& index
>= 0 && index
< size
)
154 if (delfunc
) delfunc(Get(index
));
155 // if delfunc modified the list this could be unpredictable
156 WDL_ASSERT(size
== GetSize());
158 if (index
< --size
) memmove(list
+index
,list
+index
+1,(unsigned int)sizeof(PTRTYPE
*)*(size
-index
));
159 m_buf
.Resize(size
,false);
162 void DeletePtr(const PTRTYPE
*p
) { Delete(Find(p
)); }
163 void DeletePtr(const PTRTYPE
*p
, bool wantDelete
, void (*delfunc
)(void *)=NULL
) { Delete(Find(p
),wantDelete
,delfunc
); }
164 template<class PT
> void DeletePtr(const PTRTYPE
*p
, PT delfunc
) { Delete(Find(p
),delfunc
); }
166 void DeleteRange(int index
, int count
) { m_buf
.DeleteRange(index
,count
); }
170 m_buf
.Resize(0,false);
172 void Empty(bool wantDelete
, void (*delfunc
)(void *)=NULL
)
177 for (x
= GetSize()-1; x
>= 0; x
--)
182 if (delfunc
) delfunc(p
);
185 // if delfunc modified the list this could be unpredictable
186 WDL_ASSERT(x
== GetSize()-1);
187 m_buf
.Resize(x
,false);
190 m_buf
.Resize(0,false);
192 template<class PT
> void Empty(PT delfunc
)
194 WDL_ASSERT(delfunc
!= NULL
);
195 for (int x
= GetSize()-1; x
>= 0; x
--)
198 if (delfunc
&& p
) delfunc(p
);
199 // if delfunc modified the list this could be unpredictable
200 WDL_ASSERT(x
== GetSize()-1);
201 m_buf
.Resize(x
,false);
205 template<class SB
, class SB2
> int LowerBound(SB key
, bool* ismatch
, int (*compar
)(SB2 a
, const PTRTYPE
*b
)) const
209 PTRTYPE
**list
=GetList();
213 int cmp
= compar(key
, list
[b
]);
214 if (cmp
> 0) a
= b
+1;
215 else if (cmp
< 0) c
= b
;
226 int DeleteBatch(bool (*proc
)(PTRTYPE
*p
, void *ctx
), void *ctx
=NULL
) // proc returns true to remove item. returns number removed
228 const int sz
= GetSize();
230 PTRTYPE
**rd
= GetList(), **wr
= rd
;
231 for (int x
= 0; x
< sz
; x
++)
235 if (rd
!= wr
) *wr
=*rd
;
241 if (cnt
< sz
) m_buf
.Resize(cnt
,false);
245 const PTRTYPE
**begin() const { return GetList(); }
246 const PTRTYPE
**end() const { return GetList() + GetSize(); }
247 PTRTYPE
**begin() { return GetList(); }
248 PTRTYPE
**end() { return GetList() + GetSize(); }
251 WDL_TypedBuf
<PTRTYPE
*> m_buf
;
256 template<class PTRTYPE
> class WDL_PtrList_DeleteOnDestroy
: public WDL_PtrList
<PTRTYPE
>
259 explicit WDL_PtrList_DeleteOnDestroy(void (*delfunc
)(void *)=NULL
, int defgran
=4096) : WDL_PtrList
<PTRTYPE
>(defgran
), m_delfunc(delfunc
) { }
260 ~WDL_PtrList_DeleteOnDestroy()
262 WDL_PtrList
<PTRTYPE
>::Empty(true,m_delfunc
);
265 void (*m_delfunc
)(void *);