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.
tellico/src/ptrvector.h

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