/*************************************************************************** copyright : (C) 2005-2006 by Robby Stephenson email : robby@periapsis.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of version 2 of the GNU General Public License as * * published by the Free Software Foundation; * * * ***************************************************************************/ #ifndef TELLICO_PTRVECTOR_H #define TELLICO_PTRVECTOR_H #include <kdebug.h> #include <ksharedptr.h> #include <tqvaluevector.h> namespace Tellico { template <class T> class Vector; template <class T> class VectorIterator; template <class T> class VectorConstIterator; template <class T> bool operator==(const VectorIterator<T>& left, const VectorIterator<T>& right); template <class T> bool operator!=(const VectorIterator<T>& left, const VectorIterator<T>& right); template <class T> bool operator==(const VectorConstIterator<T>& left, const VectorConstIterator<T>& right); template <class T> bool operator!=(const VectorConstIterator<T>& left, const VectorConstIterator<T>& right); template <class T> class VectorIterator { public: VectorIterator() : m_vector(0), m_index(0) {} VectorIterator(Vector<T>* vector, size_t index) : m_vector(vector), m_index(index) {} VectorIterator(const VectorIterator<T>& other) : m_vector(other.m_vector), m_index(other.m_index) {} // operator T*() { return m_vector->at(m_index).data(); } operator KSharedPtr<T>() { return m_vector->at(m_index); } T* operator->() { return m_vector->at(m_index).data(); } T& operator*() { return *m_vector->at(m_index); } T* data() { return m_vector->at(m_index).data(); } VectorIterator& operator++() { ++m_index; return *this; } VectorIterator& operator--() { --m_index; return *this; } friend bool operator==(const VectorIterator<T>& left, const VectorIterator<T>& right) { return left.m_vector == right.m_vector && left.m_index == right.m_index; } friend bool operator!=(const VectorIterator<T>& left, const VectorIterator<T>& right) { return left.m_vector != right.m_vector || left.m_index != right.m_index; } bool nextEnd() const { return m_index == m_vector->count()-1; } private: friend class Vector<T>; Vector<T>* m_vector; size_t m_index; }; template <class T> class VectorConstIterator { public: VectorConstIterator() : m_vector(0), m_index(0) {} VectorConstIterator(const Vector<T>* vector, size_t index) : m_vector(vector), m_index(index) {} VectorConstIterator(const VectorIterator<T>& other) : m_vector(other.m_vector), m_index(other.m_index) {} // operator const T*() { return m_vector->at(m_index).data(); } operator KSharedPtr<const T>() { return m_vector->at(m_index); } const T* operator->() const { return m_vector->at(m_index).data(); } const T& operator*() const { return *m_vector->at(m_index); } const T* data() const { return m_vector->at(m_index).data(); } VectorConstIterator& operator++() { ++m_index; return *this; } VectorConstIterator& operator--() { --m_index; return *this; } friend bool operator==(const VectorConstIterator<T>& left, const VectorConstIterator<T>& right) { return left.m_vector == right.m_vector && left.m_index == right.m_index; } friend bool operator!=(const VectorConstIterator<T>& left, const VectorConstIterator<T>& right) { return left.m_vector != right.m_vector || left.m_index != right.m_index; } bool nextEnd() const { return m_index == m_vector->count()-1; } private: friend class Vector<T>; const Vector<T>* m_vector; size_t m_index; }; template <class T> class Vector { public: typedef KSharedPtr<T> Ptr; typedef VectorIterator<T> Iterator; typedef VectorConstIterator<T> ConstIterator; Vector() {} Vector(Ptr t) { append(t); } Vector(const Vector<T>& v) : m_baseVector(v.m_baseVector) {} Vector& operator=(const Vector<T>& other) { if(this != &other) { m_baseVector = other.m_baseVector; } return *this; } bool operator== (const Vector<T>& x) const { return x.m_baseVector == m_baseVector; } bool isEmpty() const { return m_baseVector.empty(); } size_t count() const { return m_baseVector.size(); } Ptr& operator[](size_t i) { return m_baseVector[i]; } const Ptr& operator[](size_t i) const { return m_baseVector[i]; } Ptr& at(size_t i, bool* ok = 0) { return m_baseVector.at(i, ok); } const Ptr& at(size_t i, bool* ok = 0) const { return m_baseVector.at(i, ok); } Iterator begin() { return Iterator(this, 0); } ConstIterator begin() const { return ConstIterator(this, 0); } ConstIterator constBegin() const { return ConstIterator(this, 0); } Iterator end() { return Iterator(this, count()); } ConstIterator end() const { return ConstIterator(this, count()); } ConstIterator constEnd() const { return ConstIterator(this, count()); } Ptr& front() { return at(0); } const Ptr& front() const { return at(0); } Ptr& back() { return at(count()-1); } const Ptr& back() const { return at(count()-1); } void clear() { m_baseVector.clear(); } void append(Ptr t) { m_baseVector.append(t); } void append(Vector<T> v); void insert(Iterator pos, Ptr t) { m_baseVector.insert(&m_baseVector[pos.m_index], t); } Iterator find(Ptr t) { for(size_t i = 0; i < count(); ++i) { if(m_baseVector[i].data() == t) { return Iterator(this, i); } } return end(); } bool contains(Ptr t) const { return tqFind(m_baseVector.begin(), m_baseVector.end(), Ptr(t)) != m_baseVector.end(); } bool remove(const Ptr& t) { Ptr* it = tqFind(m_baseVector.begin(), m_baseVector.end(), t); if(it == m_baseVector.end()) return false; m_baseVector.erase(it); return true; } private: TQValueVector<Ptr> m_baseVector; }; template <class T> class PtrVector; template <class T> class PtrVectorIterator; template <class T> class PtrVectorConstIterator; template <class T> bool operator==(const PtrVectorIterator<T>& left, const PtrVectorIterator<T>& right); template <class T> bool operator!=(const PtrVectorIterator<T>& left, const PtrVectorIterator<T>& right); template <class T> bool operator==(const PtrVectorConstIterator<T>& left, const PtrVectorConstIterator<T>& right); template <class T> bool operator!=(const PtrVectorConstIterator<T>& left, const PtrVectorConstIterator<T>& right); template <class T> class PtrVectorIterator { public: PtrVectorIterator() : m_vector(0), m_index(0) {} PtrVectorIterator(const PtrVector<T>* vector, size_t index) : m_vector(vector), m_index(index) {} PtrVectorIterator(const PtrVectorIterator<T>& other) : m_vector(other.m_vector), m_index(other.m_index) {} T* operator->() { return &m_vector->at(m_index); } T& operator*() { return m_vector->at(m_index); } T* ptr() { return &m_vector->at(m_index); } PtrVectorIterator& operator++() { ++m_index; return *this; } PtrVectorIterator& operator--() { --m_index; return *this; } friend bool operator==(const PtrVectorIterator<T>& left, const PtrVectorIterator<T>& right) { return left.m_vector == right.m_vector && left.m_index == right.m_index; } friend bool operator!=(const PtrVectorIterator<T>& left, const PtrVectorIterator<T>& right) { return left.m_vector != right.m_vector || left.m_index != right.m_index; } private: const PtrVector<T>* m_vector; size_t m_index; }; template <class T> class PtrVectorConstIterator { public: PtrVectorConstIterator() : m_vector(0), m_index(0) {} PtrVectorConstIterator(const PtrVector<T>* vector, size_t index) : m_vector(vector), m_index(index) {} PtrVectorConstIterator(const PtrVectorConstIterator<T>& other) : m_vector(other.m_vector), m_index(other.m_index) {} const T* operator->() const { return &m_vector->at(m_index); } const T& operator*() const { return m_vector->at(m_index); } const T* ptr() const { return &m_vector->at(m_index); } PtrVectorConstIterator& operator++() { ++m_index; return *this; } PtrVectorConstIterator& operator--() { --m_index; return *this; } friend bool operator==(const PtrVectorConstIterator<T>& left, const PtrVectorConstIterator<T>& right) { return left.m_vector == right.m_vector && left.m_index == right.m_index; } friend bool operator!=(const PtrVectorConstIterator<T>& left, const PtrVectorConstIterator<T>& right) { return left.m_vector != right.m_vector || left.m_index != right.m_index; } private: const PtrVector<T>* m_vector; size_t m_index; }; /** * @author Robby Stephenson */ template <class T> class PtrVector { public: typedef Tellico::PtrVectorIterator<T> Iterator; typedef Tellico::PtrVectorConstIterator<T> ConstIterator; PtrVector() : m_autoDelete(false) {} PtrVector(const PtrVector<T>& other) : m_baseVector(other.m_baseVector), m_autoDelete(false) {} PtrVector& operator=(const PtrVector<T>& other) { if(this != &other) { m_baseVector = other.m_baseVector; m_autoDelete = false; } return *this; } ~PtrVector() { if(m_autoDelete) clear(); } size_t count() const { return m_baseVector.size(); } bool isEmpty() const { return m_baseVector.empty(); } bool autoDelete() const { return m_autoDelete; } void setAutoDelete(bool b) { m_autoDelete = b; } T& operator[](size_t n) const { check(n); return *m_baseVector[n]; } T& at(size_t n) const { check(n); return *m_baseVector.at(n); } Iterator begin() { return Iterator(this, 0); } ConstIterator begin() const { return ConstIterator(this, 0); } ConstIterator constBegin() const { return ConstIterator(this, 0); } Iterator end() { return Iterator(this, count()); } ConstIterator end() const { return ConstIterator(this, count()); } ConstIterator constEnd() const { return ConstIterator(this, count()); } T* front() { return count() > 0 ? m_baseVector.at(0) : 0; } const T* front() const { return count() > 0 ? m_baseVector.at(0) : 0; } T* back() { return count() > 0 ? m_baseVector.at(count()-1) : 0; } const T* back() const { return count() > 0 ? m_baseVector.at(count()-1) : 0; } void clear() { while(remove(begin())) { ; } } void push_back(T* ptr) { m_baseVector.push_back(ptr); } bool remove(T* ptr); bool remove(Iterator it); bool contains(const T* ptr) const; private: #ifndef NDEBUG void check(size_t n) const { if(n >= count()) kdDebug() << "PtrVector() - bad index" << endl; } #else void check(size_t) const {} #endif TQValueVector<T*> m_baseVector; bool m_autoDelete : 1; }; } template <class T> void Tellico::Vector<T>::append(Tellico::Vector<T> v) { typename Tellico::Vector<T>::Iterator it; for(it = v.begin(); it != v.end(); ++it) { append(it.data()); } } template <class T> bool Tellico::PtrVector<T>::remove(T* t) { if(!t) { return false; } T** ptr = tqFind(m_baseVector.begin(), m_baseVector.end(), t); if(ptr == m_baseVector.end()) { return false; } if(m_autoDelete) { delete *ptr; } m_baseVector.erase(ptr); // in case the pointer is in the vector multiple times while(remove(t)) { kdDebug() << "PtrVector::remove() - pointer was duplicated in vector" << endl; } return true; } template <class T> bool Tellico::PtrVector<T>::remove(Iterator it) { if(it == end()) { return false; } return remove(it.ptr()); } template <class T> bool Tellico::PtrVector<T>::contains(const T* t) const { if(!t) { return false; } const T* const* ptr = tqFind(m_baseVector.begin(), m_baseVector.end(), t); return ptr != m_baseVector.end(); } #endif