/*************************************************************************** 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 #include #include namespace Tellico { template class Vector; template class VectorIterator; template class VectorConstIterator; template bool operator==(const VectorIterator& left, const VectorIterator& right); template bool operator!=(const VectorIterator& left, const VectorIterator& right); template bool operator==(const VectorConstIterator& left, const VectorConstIterator& right); template bool operator!=(const VectorConstIterator& left, const VectorConstIterator& right); template class VectorIterator { public: VectorIterator() : m_vector(0), m_index(0) {} VectorIterator(Vector* vector, size_t index) : m_vector(vector), m_index(index) {} VectorIterator(const VectorIterator& other) : m_vector(other.m_vector), m_index(other.m_index) {} // operator T*() { return m_vector->at(m_index).data(); } operator TDESharedPtr() { 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& left, const VectorIterator& right) { return left.m_vector == right.m_vector && left.m_index == right.m_index; } friend bool operator!=(const VectorIterator& left, const VectorIterator& 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; Vector* m_vector; size_t m_index; }; template class VectorConstIterator { public: VectorConstIterator() : m_vector(0), m_index(0) {} VectorConstIterator(const Vector* vector, size_t index) : m_vector(vector), m_index(index) {} VectorConstIterator(const VectorIterator& other) : m_vector(other.m_vector), m_index(other.m_index) {} // operator const T*() { return m_vector->at(m_index).data(); } operator TDESharedPtr() { 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& left, const VectorConstIterator& right) { return left.m_vector == right.m_vector && left.m_index == right.m_index; } friend bool operator!=(const VectorConstIterator& left, const VectorConstIterator& 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; const Vector* m_vector; size_t m_index; }; template class Vector { public: typedef TDESharedPtr Ptr; typedef VectorIterator Iterator; typedef VectorConstIterator ConstIterator; Vector() {} Vector(Ptr t) { append(t); } Vector(const Vector& v) : m_baseVector(v.m_baseVector) {} Vector& operator=(const Vector& other) { if(this != &other) { m_baseVector = other.m_baseVector; } return *this; } bool operator== (const Vector& 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 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 m_baseVector; }; template class PtrVector; template class PtrVectorIterator; template class PtrVectorConstIterator; template bool operator==(const PtrVectorIterator& left, const PtrVectorIterator& right); template bool operator!=(const PtrVectorIterator& left, const PtrVectorIterator& right); template bool operator==(const PtrVectorConstIterator& left, const PtrVectorConstIterator& right); template bool operator!=(const PtrVectorConstIterator& left, const PtrVectorConstIterator& right); template class PtrVectorIterator { public: PtrVectorIterator() : m_vector(0), m_index(0) {} PtrVectorIterator(const PtrVector* vector, size_t index) : m_vector(vector), m_index(index) {} PtrVectorIterator(const PtrVectorIterator& 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& left, const PtrVectorIterator& right) { return left.m_vector == right.m_vector && left.m_index == right.m_index; } friend bool operator!=(const PtrVectorIterator& left, const PtrVectorIterator& right) { return left.m_vector != right.m_vector || left.m_index != right.m_index; } private: const PtrVector* m_vector; size_t m_index; }; template class PtrVectorConstIterator { public: PtrVectorConstIterator() : m_vector(0), m_index(0) {} PtrVectorConstIterator(const PtrVector* vector, size_t index) : m_vector(vector), m_index(index) {} PtrVectorConstIterator(const PtrVectorConstIterator& 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& left, const PtrVectorConstIterator& right) { return left.m_vector == right.m_vector && left.m_index == right.m_index; } friend bool operator!=(const PtrVectorConstIterator& left, const PtrVectorConstIterator& right) { return left.m_vector != right.m_vector || left.m_index != right.m_index; } private: const PtrVector* m_vector; size_t m_index; }; /** * @author Robby Stephenson */ template class PtrVector { public: typedef Tellico::PtrVectorIterator Iterator; typedef Tellico::PtrVectorConstIterator ConstIterator; PtrVector() : m_autoDelete(false) {} PtrVector(const PtrVector& other) : m_baseVector(other.m_baseVector), m_autoDelete(false) {} PtrVector& operator=(const PtrVector& 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 m_baseVector; bool m_autoDelete : 1; }; } template void Tellico::Vector::append(Tellico::Vector v) { typename Tellico::Vector::Iterator it; for(it = v.begin(); it != v.end(); ++it) { append(it.data()); } } template bool Tellico::PtrVector::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 bool Tellico::PtrVector::remove(Iterator it) { if(it == end()) { return false; } return remove(it.ptr()); } template bool Tellico::PtrVector::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