/* dtkAbstractDataComposite.cpp --- * * Author: Thibaud Kloczko * Copyright (C) 2011 - Thibaud Kloczko, Inria. * Created: Wed Sep 21 14:28:37 2011 (+0200) * Version: $Id: 90c3369417d06008c5c4f088d791438dfa044d62 $ * Last-Updated: jeu. oct. 9 09:12:05 2014 (+0200) * By: Thibaud Kloczko * Update #: 530 */ /* Commentary: * */ /* Change log: * */ #include "dtkAbstractDataComposite.h" #include "dtkGlobal.h" // ///////////////////////////////////////////////////////////////// // dtkAbstractDataCompositePrivate // ///////////////////////////////////////////////////////////////// class dtkAbstractDataCompositePrivate { public: dtkAbstractDataCompositePrivate(void); dtkAbstractDataCompositePrivate( QVector *ivector); dtkAbstractDataCompositePrivate( QVector& ivector); dtkAbstractDataCompositePrivate(const QVector& ivector); dtkAbstractDataCompositePrivate( QList *ilist); dtkAbstractDataCompositePrivate( QList& ilist); dtkAbstractDataCompositePrivate(const QList& ilist); public: dtkAbstractDataComposite::Type type; const QVector& const_vector; QVector& vector; const QList& const_list; QList& list; const QVector *cv; QVector *vv; const QList *cl; QList *vl; }; dtkAbstractDataCompositePrivate::dtkAbstractDataCompositePrivate(QVector *ivector) : const_vector(*new QVector()), vector(*ivector), const_list(*new QList()), list(*new QList()), cv(0), vv(ivector), cl(0), vl(0) { cv = &const_vector; cl = &const_list; vl = &list; } dtkAbstractDataCompositePrivate::dtkAbstractDataCompositePrivate(const QVector& ivector) : const_vector(ivector), vector(*new QVector()), const_list(*new QList()), list(*new QList()), cv(&ivector) { vv = &vector; cl = &const_list; vl = &list; } dtkAbstractDataCompositePrivate::dtkAbstractDataCompositePrivate(QVector& ivector) : const_vector(*new QVector()), vector(ivector), const_list(*new QList()), list(*new QList()), vv(&ivector) { cv = &const_vector; cl = &const_list; vl = &list; } dtkAbstractDataCompositePrivate::dtkAbstractDataCompositePrivate(QList *ilist) : const_vector(*new QVector()), vector(*new QVector()), const_list(*new QList()), list(*ilist), vl(ilist) { cv = &const_vector; vv = &vector; cl = &const_list; } dtkAbstractDataCompositePrivate::dtkAbstractDataCompositePrivate(const QList& ilist) : const_vector(*new QVector()), vector(*new QVector()), const_list(ilist), list(*new QList()), cl(&ilist) { cv = &const_vector; vv = &vector; vl = &list; } dtkAbstractDataCompositePrivate::dtkAbstractDataCompositePrivate(QList& ilist) : const_vector(*new QVector()), vector(*new QVector()), const_list(*new QList()), list(ilist), vl(&ilist) { cv = &const_vector; vv = &vector; cl = &const_list; } // ///////////////////////////////////////////////////////////////// // dtkAbstractDataComposite definition // ///////////////////////////////////////////////////////////////// //! Constructs a composite data from a const QVector. /*! * */ dtkAbstractDataComposite::dtkAbstractDataComposite(const QVector& vector, dtkAbstractData *parent) : dtkAbstractData(parent), d(new dtkAbstractDataCompositePrivate(vector)) { d->type = dtkAbstractDataComposite::ConstVector; } //! Constructs a composite data from a QVector. /*! * */ dtkAbstractDataComposite::dtkAbstractDataComposite(QVector& vector, dtkAbstractData *parent) : dtkAbstractData(parent), d(new dtkAbstractDataCompositePrivate(vector)) { d->type = dtkAbstractDataComposite::Vector; } //! Constructs a composite data from a const QList. /*! * */ dtkAbstractDataComposite::dtkAbstractDataComposite(const QList& list, dtkAbstractData *parent) : dtkAbstractData(parent), d(new dtkAbstractDataCompositePrivate(list)) { d->type = dtkAbstractDataComposite::ConstList; } //! Constructs a composite data from a QList. /*! * */ dtkAbstractDataComposite::dtkAbstractDataComposite(QList& list, dtkAbstractData *parent) : dtkAbstractData(parent), d(new dtkAbstractDataCompositePrivate(list)) { d->type = dtkAbstractDataComposite::List; } //! Destructs the composite data. /*! * */ dtkAbstractDataComposite::~dtkAbstractDataComposite(void) { if (d->cv) { delete d->cv; d->cv = NULL; } if (d->vv) { delete d->vv; d->vv = NULL; } if (d->cl) { delete d->cl; d->cl = NULL; } if (d->vl) { delete d->vl; d->vl = NULL; } delete d; d = NULL; } //! Insert \a data at the end of the composite. /*! * */ void dtkAbstractDataComposite::append(dtkAbstractData *data) { switch (d->type) { case dtkAbstractDataComposite::Vector: d->vector.append(data); break; case dtkAbstractDataComposite::List: d->list.append(data); break; case dtkAbstractDataComposite::ConstVector: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is of type const vector. Adding data failed"; break; case dtkAbstractDataComposite::ConstList: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is of type const list. Adding data failed"; break; default: qDebug() << DTK_PRETTY_FUNCTION << "Composite data has no type. Adding data failed"; break; } } //! Remove \a data from the composite. /*! * */ void dtkAbstractDataComposite::remove(dtkAbstractData *data) { qlonglong index; switch (d->type) { case dtkAbstractDataComposite::Vector: index = d->vector.indexOf(data); while (index >= 0) { d->vector.remove(index); index = d->vector.indexOf(data); } break; case dtkAbstractDataComposite::List: d->list.removeAll(data); break; case dtkAbstractDataComposite::ConstVector: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is of type const vector. Removing data failed"; break; case dtkAbstractDataComposite::ConstList: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is of type const list. Removing data failed"; break; default: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is empty. Removing data failed"; break; } } //! Returns true if the composite contains an occurrence of \a data; //! otherwise returns false. /*! * */ bool dtkAbstractDataComposite::has(dtkAbstractData *data) const { bool has = false; switch (d->type) { case dtkAbstractDataComposite::Vector: has = d->vector.contains(data); break; case dtkAbstractDataComposite::List: has = d->list.contains(data); break; case dtkAbstractDataComposite::ConstVector: has = d->const_vector.contains(data); break; case dtkAbstractDataComposite::ConstList: has = d->const_list.contains(data); break; default: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is empty. Returns false."; break; } return has; } //! Returns the number of items in the composite. /*! * */ qlonglong dtkAbstractDataComposite::count(void) { qlonglong count = 0; switch (d->type) { case dtkAbstractDataComposite::Vector: count = d->vector.count(); break; case dtkAbstractDataComposite::List: count = d->list.count(); break; case dtkAbstractDataComposite::ConstVector: count = d->const_vector.count(); break; case dtkAbstractDataComposite::ConstList: count = d->const_list.count(); break; default: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is empty. Returns 0."; break; } return count; } //! Returns the index position of the first occurrence of \a data in //! the composite, searching forward from index position \a //! from. Returns -1 if no item matched. /*! * */ qlonglong dtkAbstractDataComposite::indexOf(dtkAbstractData *data, qlonglong from) { qlonglong index = -1; switch (d->type) { case dtkAbstractDataComposite::Vector: index = d->vector.indexOf(data, from); break; case dtkAbstractDataComposite::List: index = d->list.indexOf(data, from); break; case dtkAbstractDataComposite::ConstVector: index = d->const_vector.indexOf(data, from); break; case dtkAbstractDataComposite::ConstList: index = d->const_list.indexOf(data, from); break; default: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is empty. Returns -1."; break; } return index; } //! Returns type of the composite (eg vector or list). /*! * */ dtkAbstractDataComposite::Type dtkAbstractDataComposite::type(void) { return d->type; } //! Returns the item at index position \a index in the composite. /*! * \a index must be a valid index position in the composite (i.e., 0 <= i < size). */ const dtkAbstractData *dtkAbstractDataComposite::at(qlonglong index) const { dtkAbstractData *data = NULL; switch (d->type) { case dtkAbstractDataComposite::Vector: data = d->vector.at(index); break; case dtkAbstractDataComposite::List: data = d->list.at(index); break; case dtkAbstractDataComposite::ConstVector: data = d->const_vector.at(index); break; case dtkAbstractDataComposite::ConstList: data = d->const_list.at(index); break; default: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is empty. Returns NULL."; break; } return data; } //! Returns the item at index position \a index in the composite. /*! * \a index must be a valid index position in the composite (i.e., 0 <= i < size). */ dtkAbstractData *dtkAbstractDataComposite::at(qlonglong index) { dtkAbstractData *data = NULL; switch (d->type) { case dtkAbstractDataComposite::Vector: data = d->vector[index]; break; case dtkAbstractDataComposite::List: data = d->list[index]; break; case dtkAbstractDataComposite::ConstVector: data = d->const_vector[index]; break; case dtkAbstractDataComposite::ConstList: data = d->const_list[index]; break; default: qDebug() << DTK_PRETTY_FUNCTION << "Composite data is empty. Returns NULL."; break; } return data; } //! Returns the data of the composite as a Qt vector. /*! * When composite has been created using a Qt vector, a reference to * this original vector is returned. * * When composite has been created using a Qt list, a reference to a * vector containing a copy of the original list is returned. */ const QVector& dtkAbstractDataComposite::vector(void) const { switch (d->type) { case dtkAbstractDataComposite::Vector: return d->vector; break; case dtkAbstractDataComposite::ConstVector: return d->const_vector; break; case dtkAbstractDataComposite::List: d->vector = d->list.toVector(); return d->vector; break; case dtkAbstractDataComposite::ConstList: d->vector = d->const_list.toVector(); return d->vector; break; default: return d->vector; break; } } //! Returns the data of the composite as a Qt vector. /*! * When composite has been created using a non const Qt vector, a * reference to this original vector is returned. * * When composite has been created using a const Qt vector, a * reference to a copy of this original vector is returned. * * When composite has been created using a Qt list, a reference to a * vector containing a copy of the original list is returned. */ QVector& dtkAbstractDataComposite::vector(void) { switch (d->type) { case dtkAbstractDataComposite::Vector: return d->vector; break; case dtkAbstractDataComposite::ConstVector: d->vector = d->const_vector; return d->vector; break; case dtkAbstractDataComposite::List: d->vector = d->list.toVector(); return d->vector; break; case dtkAbstractDataComposite::ConstList: d->vector = d->const_list.toVector(); return d->vector; break; default: return d->vector; break; } } //! Returns the data of the composite as a Qt list. /*! * When composite has been created using a Qt list, a reference to * this original list is returned. * * When composite has been created using a Qt vector, a reference to a * list containing a copy of the original vector is returned. */ const QList& dtkAbstractDataComposite::list(void) const { switch (d->type) { case dtkAbstractDataComposite::Vector: d->list = d->vector.toList(); return d->list; break; case dtkAbstractDataComposite::ConstVector: d->list = d->const_vector.toList(); return d->list; break; case dtkAbstractDataComposite::List: return d->list; break; case dtkAbstractDataComposite::ConstList: return d->const_list; break; default: return d->list; break; } } //! Returns the data of the composite as a Qt list. /*! * When composite has been created using a non const Qt list, a * reference to this original list is returned. * * When composite has been created using a const Qt list, a * reference to a copy of this original list is returned. * * When composite has been created using a Qt vector, a reference to a * list containing a copy of the original vector is returned. */ QList& dtkAbstractDataComposite::list(void) { switch (d->type) { case dtkAbstractDataComposite::Vector: d->list = d->vector.toList(); return d->list; break; case dtkAbstractDataComposite::ConstVector: d->list = d->const_vector.toList(); return d->list; break; case dtkAbstractDataComposite::List: return d->list; break; case dtkAbstractDataComposite::ConstList: d->list = d->const_list; return d->list; break; default: return d->list; break; } } // ///////////////////////////////////////////////////////////////// // Private constructors // ///////////////////////////////////////////////////////////////// //! Constructs a composite data from a pointer to a QVector. /*! * */ dtkAbstractDataComposite::dtkAbstractDataComposite(QVector *vector) : dtkAbstractData(), d(new dtkAbstractDataCompositePrivate(vector)) { d->type = dtkAbstractDataComposite::Vector; } //! Constructs a composite data from a pointer to a QList /*! * */ dtkAbstractDataComposite::dtkAbstractDataComposite(QList *list) : dtkAbstractData(), d(new dtkAbstractDataCompositePrivate(list)) { d->type = dtkAbstractDataComposite::List; } // ///////////////////////////////////////////////////////////////// // Static methods for creating composite by copying vector or list // ///////////////////////////////////////////////////////////////// //! Creates a composite from a copy of \a vector. /*! * */ dtkAbstractDataComposite *dtkAbstractDataComposite::createFromVectorCopy(const QVector& vector) { return new dtkAbstractDataComposite(new QVector(vector)); } //! Creates a composite from a copy of \a vector. /*! * */ dtkAbstractDataComposite *dtkAbstractDataComposite::createFromVectorCopy(QVector& vector) { return new dtkAbstractDataComposite(new QVector(vector)); } //! Creates a composite from a copy of \a vector. /*! * */ dtkAbstractDataComposite *dtkAbstractDataComposite::createFromListCopy(const QList& list) { return new dtkAbstractDataComposite(new QList(list)); } //! Creates a composite from a copy of \a vector. /*! * */ dtkAbstractDataComposite *dtkAbstractDataComposite::createFromListCopy(QList& list) { return new dtkAbstractDataComposite(new QList(list)); } // ///////////////////////////////////////////////////////////////// // dtkAbstractDataComposite documentation // ///////////////////////////////////////////////////////////////// /*! \class dtkAbstractDataComposite * * \brief Class enabling dealing with collection of dtkAbstractData*. * * * * Example: * \code * * * * \endcode * * */