Clementine-audio-player-Mac.../3rdparty/taglib/toolkit/tlist.tcc

324 lines
7.2 KiB
C++

/***************************************************************************
copyright : (C) 2002 - 2008 by Scott Wheeler
email : wheeler@kde.org
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <algorithm>
#include "trefcounter.h"
namespace TagLib {
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
// The functionality of List<T>::setAutoDelete() is implemented here partial
// template specialization. This is implemented in such a way that calling
// setAutoDelete() on non-pointer types will simply have no effect.
// A base for the generic and specialized private class types. New
// non-templatized members should be added here.
// BIC change to RefCounter
class ListPrivateBase : public RefCounterOld
{
public:
ListPrivateBase() : autoDelete(false) {}
bool autoDelete;
};
// A generic implementation
template <class T>
template <class TP> class List<T>::ListPrivate : public ListPrivateBase
{
public:
ListPrivate() : ListPrivateBase() {}
ListPrivate(const std::list<TP> &l) : ListPrivateBase(), list(l) {}
void clear() {
list.clear();
}
std::list<TP> list;
};
// A partial specialization for all pointer types that implements the
// setAutoDelete() functionality.
template <class T>
template <class TP> class List<T>::ListPrivate<TP *> : public ListPrivateBase
{
public:
ListPrivate() : ListPrivateBase() {}
ListPrivate(const std::list<TP *> &l) : ListPrivateBase(), list(l) {}
~ListPrivate() {
clear();
}
void clear() {
if(autoDelete) {
typename std::list<TP *>::const_iterator it = list.begin();
for(; it != list.end(); ++it)
delete *it;
}
list.clear();
}
std::list<TP *> list;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
template <class T>
List<T>::List() :
d(new ListPrivate<T>())
{
}
template <class T>
List<T>::List(const List<T> &l) : d(l.d)
{
d->ref();
}
template <class T>
List<T>::~List()
{
if(d->deref())
delete d;
}
template <class T>
typename List<T>::Iterator List<T>::begin()
{
detach();
return d->list.begin();
}
template <class T>
typename List<T>::ConstIterator List<T>::begin() const
{
return d->list.begin();
}
template <class T>
typename List<T>::Iterator List<T>::end()
{
detach();
return d->list.end();
}
template <class T>
typename List<T>::ConstIterator List<T>::end() const
{
return d->list.end();
}
template <class T>
typename List<T>::Iterator List<T>::insert(Iterator it, const T &item)
{
detach();
return d->list.insert(it, item);
}
template <class T>
List<T> &List<T>::sortedInsert(const T &value, bool unique)
{
detach();
Iterator it = begin();
while(it != end() && *it < value)
++it;
if(unique && it != end() && *it == value)
return *this;
insert(it, value);
return *this;
}
template <class T>
List<T> &List<T>::append(const T &item)
{
detach();
d->list.push_back(item);
return *this;
}
template <class T>
List<T> &List<T>::append(const List<T> &l)
{
detach();
d->list.insert(d->list.end(), l.begin(), l.end());
return *this;
}
template <class T>
List<T> &List<T>::prepend(const T &item)
{
detach();
d->list.push_front(item);
return *this;
}
template <class T>
List<T> &List<T>::prepend(const List<T> &l)
{
detach();
d->list.insert(d->list.begin(), l.begin(), l.end());
return *this;
}
template <class T>
List<T> &List<T>::clear()
{
detach();
d->clear();
return *this;
}
template <class T>
unsigned int List<T>::size() const
{
return static_cast<unsigned int>(d->list.size());
}
template <class T>
bool List<T>::isEmpty() const
{
return d->list.empty();
}
template <class T>
typename List<T>::Iterator List<T>::find(const T &value)
{
detach();
return std::find(d->list.begin(), d->list.end(), value);
}
template <class T>
typename List<T>::ConstIterator List<T>::find(const T &value) const
{
return std::find(d->list.begin(), d->list.end(), value);
}
template <class T>
bool List<T>::contains(const T &value) const
{
return std::find(d->list.begin(), d->list.end(), value) != d->list.end();
}
template <class T>
typename List<T>::Iterator List<T>::erase(Iterator it)
{
return d->list.erase(it);
}
template <class T>
const T &List<T>::front() const
{
return d->list.front();
}
template <class T>
T &List<T>::front()
{
detach();
return d->list.front();
}
template <class T>
const T &List<T>::back() const
{
return d->list.back();
}
template <class T>
void List<T>::setAutoDelete(bool autoDelete)
{
d->autoDelete = autoDelete;
}
template <class T>
T &List<T>::back()
{
detach();
return d->list.back();
}
template <class T>
T &List<T>::operator[](unsigned int i)
{
Iterator it = d->list.begin();
std::advance(it, i);
return *it;
}
template <class T>
const T &List<T>::operator[](unsigned int i) const
{
ConstIterator it = d->list.begin();
std::advance(it, i);
return *it;
}
template <class T>
List<T> &List<T>::operator=(const List<T> &l)
{
List<T>(l).swap(*this);
return *this;
}
template <class T>
void List<T>::swap(List<T> &l)
{
using std::swap;
swap(d, l.d);
}
template <class T>
bool List<T>::operator==(const List<T> &l) const
{
return d->list == l.d->list;
}
template <class T>
bool List<T>::operator!=(const List<T> &l) const
{
return d->list != l.d->list;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
template <class T>
void List<T>::detach()
{
if(d->count() > 1) {
d->deref();
d = new ListPrivate<T>(d->list);
}
}
} // namespace TagLib