diff options
Diffstat (limited to 'src/ptrvector.h')
-rw-r--r-- | src/ptrvector.h | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/src/ptrvector.h b/src/ptrvector.h new file mode 100644 index 0000000..1dd66ea --- /dev/null +++ b/src/ptrvector.h @@ -0,0 +1,322 @@ +/*************************************************************************** + copyright : (C) 2005-2006 by Robby Stephenson + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 <qvaluevector.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 qFind(m_baseVector.begin(), m_baseVector.end(), Ptr(t)) != m_baseVector.end(); } + bool remove(const Ptr& t) { + Ptr* it = qFind(m_baseVector.begin(), m_baseVector.end(), t); + if(it == m_baseVector.end()) return false; + m_baseVector.erase(it); + return true; + } + +private: + QValueVector<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 + + QValueVector<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 = qFind(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 = qFind(m_baseVector.begin(), m_baseVector.end(), t); + return ptr != m_baseVector.end(); +} + +#endif |