Added TagLib (with AUTORS and COPYING files)
[someplayer] / src / taglib / toolkit / tlist.tcc
1 /***************************************************************************
2     copyright            : (C) 2002 - 2008 by Scott Wheeler
3     email                : wheeler@kde.org
4  ***************************************************************************/
5
6 /***************************************************************************
7  *   This library is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU Lesser General Public License version   *
9  *   2.1 as published by the Free Software Foundation.                     *
10  *                                                                         *
11  *   This library is distributed in the hope that it will be useful, but   *
12  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
14  *   Lesser General Public License for more details.                       *
15  *                                                                         *
16  *   You should have received a copy of the GNU Lesser General Public      *
17  *   License along with this library; if not, write to the Free Software   *
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
19  *   USA                                                                   *
20  *                                                                         *
21  *   Alternatively, this file is available under the Mozilla Public        *
22  *   License Version 1.1.  You may obtain a copy of the License at         *
23  *   http://www.mozilla.org/MPL/                                           *
24  ***************************************************************************/
25
26 #include <algorithm>
27
28 namespace TagLib {
29
30 ////////////////////////////////////////////////////////////////////////////////
31 // public members
32 ////////////////////////////////////////////////////////////////////////////////
33
34 // The functionality of List<T>::setAutoDelete() is implemented here partial
35 // template specialization.  This is implemented in such a way that calling
36 // setAutoDelete() on non-pointer types will simply have no effect.
37
38 // A base for the generic and specialized private class types.  New
39 // non-templatized members should be added here.
40
41 class ListPrivateBase : public RefCounter
42 {
43 public:
44   ListPrivateBase() : autoDelete(false) {}
45   bool autoDelete;
46 };
47
48 // A generic implementation
49
50 template <class T>
51 template <class TP> class List<T>::ListPrivate  : public ListPrivateBase
52 {
53 public:
54   ListPrivate() : ListPrivateBase() {}
55   ListPrivate(const std::list<TP> &l) : ListPrivateBase(), list(l) {}
56   void clear() {
57     list.clear();
58   }
59   std::list<TP> list;
60 };
61
62 // A partial specialization for all pointer types that implements the
63 // setAutoDelete() functionality.
64
65 template <class T>
66 template <class TP> class List<T>::ListPrivate<TP *>  : public ListPrivateBase
67 {
68 public:
69   ListPrivate() : ListPrivateBase() {}
70   ListPrivate(const std::list<TP *> &l) : ListPrivateBase(), list(l) {}
71   ~ListPrivate() {
72     clear();
73   }
74   void clear() {
75     if(autoDelete) {
76       typename std::list<TP *>::const_iterator it = list.begin();
77       for(; it != list.end(); ++it)
78         delete *it;
79     }
80     list.clear();
81   }
82   std::list<TP *> list;
83 };
84
85 ////////////////////////////////////////////////////////////////////////////////
86 // public members
87 ////////////////////////////////////////////////////////////////////////////////
88
89 template <class T>
90 List<T>::List()
91 {
92   d = new ListPrivate<T>;
93 }
94
95 template <class T>
96 List<T>::List(const List<T> &l) : d(l.d)
97 {
98   d->ref();
99 }
100
101 template <class T>
102 List<T>::~List()
103 {
104   if(d->deref())
105     delete d;
106 }
107
108 template <class T>
109 typename List<T>::Iterator List<T>::begin()
110 {
111   detach();
112   return d->list.begin();
113 }
114
115 template <class T>
116 typename List<T>::ConstIterator List<T>::begin() const
117 {
118   return d->list.begin();
119 }
120
121 template <class T>
122 typename List<T>::Iterator List<T>::end()
123 {
124   detach();
125   return d->list.end();
126 }
127
128 template <class T>
129 typename List<T>::ConstIterator List<T>::end() const
130 {
131   return d->list.end();
132 }
133
134 template <class T>
135 typename List<T>::Iterator List<T>::insert(Iterator it, const T &item)
136 {
137   detach();
138   return d->list.insert(it, item);
139 }
140
141 template <class T>
142 List<T> &List<T>::sortedInsert(const T &value, bool unique)
143 {
144   detach();
145   Iterator it = begin();
146   while(it != end() && *it < value)
147     ++it;
148   if(unique && it != end() && *it == value)
149     return *this;
150   insert(it, value);
151   return *this;
152 }
153
154 template <class T>
155 List<T> &List<T>::append(const T &item)
156 {
157   detach();
158   d->list.push_back(item);
159   return *this;
160 }
161
162 template <class T>
163 List<T> &List<T>::append(const List<T> &l)
164 {
165   detach();
166   d->list.insert(d->list.end(), l.begin(), l.end());
167   return *this;
168 }
169
170 template <class T>
171 List<T> &List<T>::prepend(const T &item)
172 {
173   detach();
174   d->list.push_front(item);
175   return *this;
176 }
177
178 template <class T>
179 List<T> &List<T>::prepend(const List<T> &l)
180 {
181   detach();
182   d->list.insert(d->list.begin(), l.begin(), l.end());
183   return *this;
184 }
185
186 template <class T>
187 List<T> &List<T>::clear()
188 {
189   detach();
190   d->clear();
191   return *this;
192 }
193
194 template <class T>
195 TagLib::uint List<T>::size() const
196 {
197   return d->list.size();
198 }
199
200 template <class T>
201 bool List<T>::isEmpty() const
202 {
203   return d->list.empty();
204 }
205
206 template <class T>
207 typename List<T>::Iterator List<T>::find(const T &value)
208 {
209   return std::find(d->list.begin(), d->list.end(), value);
210 }
211
212 template <class T>
213 typename List<T>::ConstIterator List<T>::find(const T &value) const
214 {
215   return std::find(d->list.begin(), d->list.end(), value);
216 }
217
218 template <class T>
219 bool List<T>::contains(const T &value) const
220 {
221   return std::find(d->list.begin(), d->list.end(), value) != d->list.end();
222 }
223
224 template <class T>
225 typename List<T>::Iterator List<T>::erase(Iterator it)
226 {
227   return d->list.erase(it);
228 }
229
230 template <class T>
231 const T &List<T>::front() const
232 {
233   return d->list.front();
234 }
235
236 template <class T>
237 T &List<T>::front()
238 {
239   detach();
240   return d->list.front();
241 }
242
243 template <class T>
244 const T &List<T>::back() const
245 {
246   return d->list.back();
247 }
248
249 template <class T>
250 void List<T>::setAutoDelete(bool autoDelete)
251 {
252   d->autoDelete = autoDelete;
253 }
254
255 template <class T>
256 T &List<T>::back()
257 {
258   detach();
259   return d->list.back();
260 }
261
262 template <class T>
263 T &List<T>::operator[](uint i)
264 {
265   Iterator it = d->list.begin();
266
267   for(uint j = 0; j < i; j++)
268     ++it;
269
270   return *it;
271 }
272
273 template <class T>
274 const T &List<T>::operator[](uint i) const
275 {
276   ConstIterator it = d->list.begin();
277
278   for(uint j = 0; j < i; j++)
279     ++it;
280
281   return *it;
282 }
283
284 template <class T>
285 List<T> &List<T>::operator=(const List<T> &l)
286 {
287   if(&l == this)
288     return *this;
289
290   if(d->deref())
291     delete d;
292   d = l.d;
293   d->ref();
294   return *this;
295 }
296
297 template <class T>
298 bool List<T>::operator==(const List<T> &l) const
299 {
300   return d->list == l.d->list;
301 }
302
303 ////////////////////////////////////////////////////////////////////////////////
304 // protected members
305 ////////////////////////////////////////////////////////////////////////////////
306
307 template <class T>
308 void List<T>::detach()
309 {
310   if(d->count() > 1) {
311     d->deref();
312     d = new ListPrivate<T>(d->list);
313   }
314 }
315
316 } // namespace TagLib