set base sdk to 10.9
[wdl/wdl-ol.git] / WDL / ptrlist.h
blob154e0420053eeae21f56782cf3f81a7186780280
1 /*
2 WDL - ptrlist.h
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_
37 #include "heapbuf.h"
39 template<class PTRTYPE> class WDL_PtrList
41 public:
42 explicit WDL_PtrList(int defgran=4096) : m_hb(defgran WDL_HEAPBUF_TRACEPARM("WDL_PtrList"))
46 ~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];
55 return NULL;
58 int GetSize(void) const { return m_hb.GetSize()/(unsigned int)sizeof(PTRTYPE *); }
60 int Find(const PTRTYPE *p) const
62 if (p)
64 PTRTYPE **list=(PTRTYPE **)m_hb.Get();
65 int x;
66 const int n = GetSize();
67 for (x = 0; x < n; x ++) if (list[x] == p) return x;
69 return -1;
71 int FindR(const PTRTYPE *p) const
73 if (p)
75 PTRTYPE **list=(PTRTYPE **)m_hb.Get();
76 int x = GetSize();
77 while (--x >= 0) if (list[x] == p) return x;
79 return -1;
82 PTRTYPE *Add(PTRTYPE *item)
84 const int s=GetSize();
85 PTRTYPE **list=(PTRTYPE **)m_hb.ResizeOK((s+1)*(unsigned int)sizeof(PTRTYPE*),false);
86 if (list)
88 list[s]=item;
89 return item;
91 return NULL;
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;
98 return NULL;
101 PTRTYPE *Insert(int index, PTRTYPE *item)
103 int s=GetSize();
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;
110 int x;
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
116 bool m;
117 int i = LowerBound(p,&m,compar);
118 return m ? i : -1;
120 PTRTYPE *InsertSorted(PTRTYPE *item, int (*compar)(const PTRTYPE **a, const PTRTYPE **b))
122 bool m;
123 return Insert(LowerBound(item,&m,compar),item);
126 void Delete(int index)
128 PTRTYPE **list=GetList();
129 int size=GetSize();
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();
139 int size=GetSize();
140 if (list && index >= 0 && index < size)
142 if (wantDelete)
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();
154 int size=GetSize();
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); }
166 void Empty()
168 m_hb.Resize(0,false);
170 void Empty(bool wantDelete, void (*delfunc)(void *)=NULL)
172 if (wantDelete)
174 int x;
175 for (x = GetSize()-1; x >= 0; x --)
177 PTRTYPE* p = Get(x);
178 if (p)
180 if (delfunc) delfunc(p);
181 else delete p;
183 m_hb.Resize(x*(unsigned int)sizeof(PTRTYPE *),false);
186 m_hb.Resize(0,false);
188 void Empty(void (*delfunc)(PTRTYPE *))
190 int x;
191 for (x = GetSize()-1; x >= 0; x --)
193 PTRTYPE* p = Get(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();
201 else
203 WDL_PtrList<PTRTYPE> tmp;
204 int x;
205 for(x=0;x<GetSize();x++)tmp.Add(Get(x));
206 Empty();
207 tmp.Empty(true,delfunc);
211 int LowerBound(const PTRTYPE *key, bool* ismatch, int (*compar)(const PTRTYPE **a, const PTRTYPE **b)) const
213 int a = 0;
214 int c = GetSize();
215 PTRTYPE **list=GetList();
216 while (a != c)
218 int b = (a+c)/2;
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;
222 else
224 *ismatch = true;
225 return b;
228 *ismatch = false;
229 return a;
232 void Compact() { m_hb.Resize(m_hb.GetSize(),true); }
234 private:
235 WDL_HeapBuf m_hb;
240 template<class PTRTYPE> class WDL_PtrList_DeleteOnDestroy : public WDL_PtrList<PTRTYPE>
242 public:
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);
248 private:
249 void (*m_delfunc)(void *);
252 #endif