/*************************************************************************** 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 namespace TagLib { //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// // The functionality of List::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. class ListPrivateBase : public RefCounter { public: ListPrivateBase() : autoDelete(false) {} bool autoDelete; }; // A generic implementation template template class List::ListPrivate : public ListPrivateBase { public: ListPrivate() : ListPrivateBase() {} ListPrivate(const std::list &l) : ListPrivateBase(), list(l) {} void clear() { list.clear(); } std::list list; }; // A partial specialization for all pointer types that implements the // setAutoDelete() functionality. template template class List::ListPrivate : public ListPrivateBase { public: ListPrivate() : ListPrivateBase() {} ListPrivate(const std::list &l) : ListPrivateBase(), list(l) {} ~ListPrivate() { clear(); } void clear() { if(autoDelete) { typename std::list::const_iterator it = list.begin(); for(; it != list.end(); ++it) delete *it; } list.clear(); } std::list list; }; //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// template List::List() { d = new ListPrivate; } template List::List(const List &l) : d(l.d) { d->ref(); } template List::~List() { if(d->deref()) delete d; } template typename List::Iterator List::begin() { detach(); return d->list.begin(); } template typename List::ConstIterator List::begin() const { return d->list.begin(); } template typename List::Iterator List::end() { detach(); return d->list.end(); } template typename List::ConstIterator List::end() const { return d->list.end(); } template typename List::Iterator List::insert(Iterator it, const T &item) { detach(); return d->list.insert(it, item); } template List &List::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 List &List::append(const T &item) { detach(); d->list.push_back(item); return *this; } template List &List::append(const List &l) { detach(); d->list.insert(d->list.end(), l.begin(), l.end()); return *this; } template List &List::prepend(const T &item) { detach(); d->list.push_front(item); return *this; } template List &List::prepend(const List &l) { detach(); d->list.insert(d->list.begin(), l.begin(), l.end()); return *this; } template List &List::clear() { detach(); d->clear(); return *this; } template TagLib::uint List::size() const { return d->list.size(); } template bool List::isEmpty() const { return d->list.empty(); } template typename List::Iterator List::find(const T &value) { return std::find(d->list.begin(), d->list.end(), value); } template typename List::ConstIterator List::find(const T &value) const { return std::find(d->list.begin(), d->list.end(), value); } template bool List::contains(const T &value) const { return std::find(d->list.begin(), d->list.end(), value) != d->list.end(); } template typename List::Iterator List::erase(Iterator it) { return d->list.erase(it); } template const T &List::front() const { return d->list.front(); } template T &List::front() { detach(); return d->list.front(); } template const T &List::back() const { return d->list.back(); } template void List::setAutoDelete(bool autoDelete) { d->autoDelete = autoDelete; } template T &List::back() { detach(); return d->list.back(); } template T &List::operator[](uint i) { Iterator it = d->list.begin(); for(uint j = 0; j < i; j++) ++it; return *it; } template const T &List::operator[](uint i) const { ConstIterator it = d->list.begin(); for(uint j = 0; j < i; j++) ++it; return *it; } template List &List::operator=(const List &l) { if(&l == this) return *this; if(d->deref()) delete d; d = l.d; d->ref(); return *this; } template bool List::operator==(const List &l) const { return d->list == l.d->list; } template bool List::operator!=(const List &l) const { return d->list != l.d->list; } //////////////////////////////////////////////////////////////////////////////// // protected members //////////////////////////////////////////////////////////////////////////////// template void List::detach() { if(d->count() > 1) { d->deref(); d = new ListPrivate(d->list); } } } // namespace TagLib