You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
12 KiB
323 lines
12 KiB
/***************************************************************************
|
|
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 TDESharedPtr<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 TDESharedPtr<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 TDESharedPtr<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
|