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) : m_hb(defgran
WDL_HEAPBUF_TRACEPARM("WDL_PtrList"))
50 PTRTYPE
**GetList() const { return (PTRTYPE
**)m_hb
.Get(); }
51 PTRTYPE
*Get(INT_PTR index
) const
53 PTRTYPE
**list
= (PTRTYPE
**)m_hb
.Get();
54 if (list
&& index
>= 0 && index
< (INT_PTR
)(m_hb
.GetSize()/sizeof(PTRTYPE
*))) return list
[index
];
58 int GetSize(void) const { return m_hb
.GetSize()/(unsigned int)sizeof(PTRTYPE
*); }
60 int Find(const PTRTYPE
*p
) const
64 PTRTYPE
**list
=(PTRTYPE
**)m_hb
.Get();
66 const int n
= GetSize();
67 for (x
= 0; x
< n
; x
++) if (list
[x
] == p
) return x
;
71 int FindR(const PTRTYPE
*p
) const
75 PTRTYPE
**list
=(PTRTYPE
**)m_hb
.Get();
77 while (--x
>= 0) if (list
[x
] == p
) return x
;
82 PTRTYPE
*Add(PTRTYPE
*item
)
84 const int s
=GetSize();
85 PTRTYPE
**list
=(PTRTYPE
**)m_hb
.ResizeOK((s
+1)*(unsigned int)sizeof(PTRTYPE
*),false);
94 PTRTYPE
*Set(int index
, PTRTYPE
*item
)
96 PTRTYPE
**list
=(PTRTYPE
**)m_hb
.Get();
97 if (list
&& index
>= 0 && index
< GetSize()) return list
[index
]=item
;
101 PTRTYPE
*Insert(int index
, PTRTYPE
*item
)
104 PTRTYPE
**list
= (PTRTYPE
**)m_hb
.ResizeOK((s
+1)*(unsigned int)sizeof(PTRTYPE
*),false);
106 if (!list
) return item
;
108 if (index
<0) index
=0;
111 for (x
= s
; x
> index
; x
--) list
[x
]=list
[x
-1];
112 return (list
[x
] = item
);
114 int FindSorted(const PTRTYPE
*p
, int (*compar
)(const PTRTYPE
**a
, const PTRTYPE
**b
)) const
117 int i
= LowerBound(p
,&m
,compar
);
120 PTRTYPE
*InsertSorted(PTRTYPE
*item
, int (*compar
)(const PTRTYPE
**a
, const PTRTYPE
**b
))
123 return Insert(LowerBound(item
,&m
,compar
),item
);
126 void Delete(int index
)
128 PTRTYPE
**list
=GetList();
130 if (list
&& index
>= 0 && index
< size
)
132 if (index
< --size
) memmove(list
+index
,list
+index
+1,(unsigned int)sizeof(PTRTYPE
*)*(size
-index
));
133 m_hb
.Resize(size
* (unsigned int)sizeof(PTRTYPE
*),false);
136 void Delete(int index
, bool wantDelete
, void (*delfunc
)(void *)=NULL
)
138 PTRTYPE
**list
=GetList();
140 if (list
&& index
>= 0 && index
< size
)
144 if (delfunc
) delfunc(Get(index
));
145 else delete Get(index
);
147 if (index
< --size
) memmove(list
+index
,list
+index
+1,(unsigned int)sizeof(PTRTYPE
*)*(size
-index
));
148 m_hb
.Resize(size
* (unsigned int)sizeof(PTRTYPE
*),false);
151 void Delete(int index
, void (*delfunc
)(PTRTYPE
*))
153 PTRTYPE
**list
=GetList();
155 if (list
&& index
>= 0 && index
< size
)
157 if (delfunc
) delfunc(Get(index
));
158 if (index
< --size
) memmove(list
+index
,list
+index
+1,(unsigned int)sizeof(PTRTYPE
*)*(size
-index
));
159 m_hb
.Resize(size
* (unsigned int)sizeof(PTRTYPE
*),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 void DeletePtr(const PTRTYPE
*p
, void (*delfunc
)(PTRTYPE
*)) { Delete(Find(p
),delfunc
); }
168 m_hb
.Resize(0,false);
170 void Empty(bool wantDelete
, void (*delfunc
)(void *)=NULL
)
175 for (x
= GetSize()-1; x
>= 0; x
--)
180 if (delfunc
) delfunc(p
);
183 m_hb
.Resize(x
*(unsigned int)sizeof(PTRTYPE
*),false);
186 m_hb
.Resize(0,false);
188 void Empty(void (*delfunc
)(PTRTYPE
*))
191 for (x
= GetSize()-1; x
>= 0; x
--)
194 if (delfunc
&& p
) delfunc(p
);
195 m_hb
.Resize(x
*(unsigned int)sizeof(PTRTYPE
*),false);
198 void EmptySafe(bool wantDelete
=false,void (*delfunc
)(void *)=NULL
)
200 if (!wantDelete
) Empty();
203 WDL_PtrList
<PTRTYPE
> tmp
;
205 for(x
=0;x
<GetSize();x
++)tmp
.Add(Get(x
));
207 tmp
.Empty(true,delfunc
);
211 int LowerBound(const PTRTYPE
*key
, bool* ismatch
, int (*compar
)(const PTRTYPE
**a
, const PTRTYPE
**b
)) const
215 PTRTYPE
**list
=GetList();
219 int cmp
= compar((const PTRTYPE
**)&key
, (const PTRTYPE
**)(list
+b
));
220 if (cmp
> 0) a
= b
+1;
221 else if (cmp
< 0) c
= b
;
232 void Compact() { m_hb
.Resize(m_hb
.GetSize(),true); }
240 template<class PTRTYPE
> class WDL_PtrList_DeleteOnDestroy
: public WDL_PtrList
<PTRTYPE
>
243 explicit WDL_PtrList_DeleteOnDestroy(void (*delfunc
)(void *)=NULL
, int defgran
=4096) : WDL_PtrList
<PTRTYPE
>(defgran
), m_delfunc(delfunc
) { }
244 ~WDL_PtrList_DeleteOnDestroy()
246 WDL_PtrList
<PTRTYPE
>::EmptySafe(true,m_delfunc
);
249 void (*m_delfunc
)(void *);