I have been trying to get my head around how to develop a standard style iterator for a QAbstractItemModel, and am getting fairly stuck. I can search the model using depth first or breadth first algorithms, but when it comes to applying these modes to an iterator I'm not sure how to proceed. Could some on point me in the right direct (possibly with pseudo code), or they have an example they are willing to share i would be very grateful.
Thanks
C++14
iterator over the rows of a QAbstractItemModel
for a given role. It only iterates over the rows of the model, the column remains unchanged.
class ModelRowIterator : public std::iterator
<
std::input_iterator_tag, // iterator_category
QVariant, // value_type
int, // difference_type
const QVariant*, // pointer
QVariant // reference
>
{
QModelIndex index_;
int role_ = 0;
public:
ModelRowIterator() {}
ModelRowIterator(const QModelIndex& index, int role) : index_(index), role_(role) {}
ModelRowIterator& operator++()
{
if (index_.isValid())
index_ = index_.model()->index(index_.row()+1, index_.column());
return *this;
}
ModelRowIterator operator++(int)
{
ModelRowIterator ret = *this;
++(*this);
return ret;
}
bool operator==(const ModelRowIterator& other) const
{
return (!other.index_.isValid() && !index_.isValid()) // ending condition
|| (other.index_ == index_ && other.role_ == role_);
}
bool operator!=(const ModelRowIterator& other) const
{
return !(other == *this);
}
reference operator*() const
{
return index_.isValid() ? index_.data(role_) : QVariant{};
}
};
Note: std::iterator
is deprecated in C++17
.
Usage:
QAbstractItemModel model;
int role = ...;
ModelRowIterator begin { model.index(0,0), role };
ModelRowIterator end {};
std::for_each(begin, end, [](const QVariant& v) { qDebug() << v; });
auto range = boost::make_range(begin, end);
boost::range::equal(range, [](const QVariant& v) { qDebug() << v; });