X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=pv%2Fview%2Frowitemiterator.hpp;fp=pv%2Fview%2Frowitemiterator.hpp;h=110dc57418f0a280d8e050941993971b6138c1a8;hb=2acdb232d6bb452cfdfaea3ef5218fb4da592329;hp=0000000000000000000000000000000000000000;hpb=8dbbc7f0b9ea59d0f0d62225772f8a56eee125f5;p=pulseview.git diff --git a/pv/view/rowitemiterator.hpp b/pv/view/rowitemiterator.hpp new file mode 100644 index 0000000..110dc57 --- /dev/null +++ b/pv/view/rowitemiterator.hpp @@ -0,0 +1,143 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2014 Joel Holdsworth + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef PULSEVIEW_PV_VIEW_ROWITEMITERATOR_H +#define PULSEVIEW_PV_VIEW_ROWITEMITERATOR_H + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace pv { +namespace view { + +template class RowItemIterator +{ +public: + typedef typename std::conditional::value, + typename Owner::item_list::const_iterator, + typename Owner::item_list::iterator>::type child_iterator; + + typedef std::shared_ptr value_type; + typedef ptrdiff_t difference_type; + typedef value_type pointer; + typedef value_type& reference; + typedef std::forward_iterator_tag iterator_category; + +public: + RowItemIterator(Owner *owner) : + owner_(owner), + lock_(owner->session().signals_mutex()) {} + + RowItemIterator(Owner *owner, child_iterator iter) : + owner_(owner), + lock_(owner->session().signals_mutex()) { + assert(owner); + if (iter != owner->child_items().end()) + iter_stack_.push(iter); + } + + RowItemIterator(const RowItemIterator &o) : + owner_(o.owner_), + lock_(*o.lock_.mutex()), + iter_stack_(o.iter_stack_) {} + + reference operator*() const { + return *iter_stack_.top(); + } + + reference operator->() const { + return *this; + } + + RowItemIterator& operator++() { + using std::dynamic_pointer_cast; + using std::shared_ptr; + + assert(owner_); + assert(!iter_stack_.empty()); + + shared_ptr owner(dynamic_pointer_cast( + *iter_stack_.top())); + if (owner && !owner->child_items().empty()) { + owner_ = owner.get(); + iter_stack_.push(owner->child_items().begin()); + } else { + ++iter_stack_.top(); + while (owner_ && iter_stack_.top() == + owner_->child_items().end()) { + iter_stack_.pop(); + owner_ = iter_stack_.empty() ? nullptr : + (*iter_stack_.top()++)->owner(); + } + } + + return *this; + } + + RowItemIterator operator++(int) { + RowItemIterator pre = *this; + ++*this; + return pre; + } + + bool operator==(const RowItemIterator &o) const { + return (iter_stack_.empty() && o.iter_stack_.empty()) || + (owner_ == o.owner_ && + iter_stack_.size() == o.iter_stack_.size() && + std::equal( + owner_->child_items().cbegin(), + owner_->child_items().cend(), + o.owner_->child_items().cbegin())); + } + + bool operator!=(const RowItemIterator &o) const { + return !((const RowItemIterator&)*this == o); + } + + void swap(RowItemIterator& other) { + swap(owner_, other.owner_); + swap(iter_stack_, other.iter_stack_); + } + +private: + Owner *owner_; + boost::shared_lock lock_; + std::stack iter_stack_; +}; + +template +void swap(RowItemIterator& a, RowItemIterator& b) +{ + a.swap(b); +} + +} // namespace view +} // namespace pv + +#endif // PULSEVIEW_PV_VIEW_ROWITEMITERATOR_H