2
* This file is part of Soprano Project.
4
* Copyright (C) 2006 Daniele Galdi <daniele.galdi@gmail.com>
5
* Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Library General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Library General Public License for more details.
17
* You should have received a copy of the GNU Library General Public License
18
* along with this library; see the file COPYING.LIB. If not, write to
19
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
* Boston, MA 02110-1301, USA.
23
#ifndef SOPRANO_ITERATOR_H
24
#define SOPRANO_ITERATOR_H
26
#include <QtCore/QSharedDataPointer>
27
#include <QtCore/QList>
29
#include "iteratorbackend.h"
35
* \class Iterator iterator.h Soprano/Iterator
37
* \brief The basic %Soprano iterator class.
39
* Iterators in %Soprano are very easy to use through two methods
40
* next() and current(). Instead of the latter operator*() can also be used.
41
* Both can be called subsequetially to retrieve the current element
42
* until next() has been called again.
45
* Soprano::Iterator<X> it;
46
* while( it.next() ) {
48
* doSomethingElse( it.current() );
52
* Many backends do lock the underlying Model during iteration. Thus,
53
* it is always a good idea to cache the results if they are to be used
54
* to modify the model:
57
* Soprano::StatementIterator it = model->listStatements();
58
* QList<Statement> allStatements = it.allElements();
59
* Q_FOREACH( Soprano::Statement s, allStatements ) {
60
* modifyTheModel( model, s );
64
* Also, Iterators have to be closed.
65
* This can either be achieved by deleting the iterator, finishing it (next() does return \p false),
66
* or calling close(). Before that other operations on the Model may block.
68
* Iterators are not thread-safe. Two threads using the same iterator at the same time may result
69
* in undefined behaviour and even crashes.
71
* \warning Be aware that iterators in Soprano are shared objects which means
72
* that copies of one iterator object work on the same data.
74
* \author Daniele Galdi <daniele.galdi@gmail.com><br>Sebastian Trueg <trueg@kde.org>
76
template<typename T> class Iterator : public Error::ErrorCache
80
* Creates and empty, invalid iterator.
85
* Create a new Iterator instance that uses sti as backend.
86
* Iterator will take ownership of the backend.
88
Iterator( IteratorBackend<T> *sti );
90
Iterator( const Iterator &sti );
94
Iterator& operator=( const Iterator& );
97
* Close the iterator and release any locks on the underlying Model.
102
* Advances to the next element in the iterator.
103
*\return true if another element can be read from the iterator,
104
* false if the end has been reached.
109
* Get the element the iterator currently points to. Be aware that
110
* a valid current element is only available if next() returned \p true.
112
*\return the current element.
117
* Retrieve the current element in the iterator.
119
* This is equivalent to current().
121
* \return The element the iterator currently points to or
122
* an invalid one if next has never been called.
127
* \return \p true if the Iterator is valid, \p false otherwise. (An invalid iterator
130
bool isValid() const;
133
* Convenience method which extracts all elements (this does not include the
134
* elements that have already been read from the iterator) from the iterator
135
* and returns them in a list.
137
* Be aware that after calling this method the iterator will be invalid.
139
* \return A list of all elements that rest in the iterator.
141
QList<T> allElements();
145
* Set the backend to read the actual data from.
146
* A previous backend will be deleted if there are no other Iterator
147
* instances using it.
149
void setBackend( IteratorBackend<T>* b );
151
IteratorBackend<T>* backend() const;
155
QSharedDataPointer<Private> d;
160
/** \cond iterator_implementation */
161
template<typename T> class Soprano::Iterator<T>::Private : public QSharedData
175
IteratorBackend<T>* backend;
179
template<typename T> Soprano::Iterator<T>::Iterator()
180
: Error::ErrorCache(),
186
template<typename T> Soprano::Iterator<T>::Iterator( IteratorBackend<T> *sti )
187
: Error::ErrorCache(),
193
template<typename T> Soprano::Iterator<T>::Iterator( const Iterator<T> &other )
194
: Error::ErrorCache(),
199
template<typename T> Soprano::Iterator<T>::~Iterator()
203
template<typename T> Soprano::Iterator<T>& Soprano::Iterator<T>::operator=( const Iterator<T>& other )
209
template<typename T> void Soprano::Iterator<T>::setBackend( IteratorBackend<T>* b )
211
if ( d->backend != b ) {
212
// now we want it to detach
217
template<typename T> Soprano::IteratorBackend<T>* Soprano::Iterator<T>::backend() const
222
template<typename T> void Soprano::Iterator<T>::close()
224
// some evil hacking to avoid detachment of the shared data
226
const Private* cd = d.constData();
227
cd->backend->close();
228
setError( cd->backend->lastError() );
231
setError( QString::fromLatin1( "Invalid iterator." ) );
235
template<typename T> bool Soprano::Iterator<T>::next()
237
// some evil hacking to avoid detachment of the shared data
238
const Private* cd = d.constData();
240
bool hasNext = cd->backend->next();
241
setError( cd->backend->lastError() );
243
cd->backend->close();
248
setError( QString::fromLatin1( "Invalid iterator." ) );
253
template<typename T> T Soprano::Iterator<T>::current() const
256
T c = d->backend->current();
257
setError( d->backend->lastError() );
261
setError( QString::fromLatin1( "Invalid iterator." ) );
266
template<typename T> T Soprano::Iterator<T>::operator*() const
271
template<typename T> bool Soprano::Iterator<T>::isValid() const
273
return d->backend != 0;
277
template<typename T> QList<T> Soprano::Iterator<T>::allElements()
281
sl.append( current() );