From 6b71530299d18b4cdbf83ad88a17eb206758237a Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 8 Sep 2014 20:24:46 +0100 Subject: [PATCH] Added pv::view::RowItemIterator --- pv/view/rowitemiterator.h | 143 ++++++++++++++++++++++++++++++++++++++ pv/view/rowitemowner.cpp | 25 +++++++ pv/view/rowitemowner.h | 40 ++++++++++- 3 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 pv/view/rowitemiterator.h diff --git a/pv/view/rowitemiterator.h b/pv/view/rowitemiterator.h new file mode 100644 index 00000000..256cdd09 --- /dev/null +++ b/pv/view/rowitemiterator.h @@ -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 diff --git a/pv/view/rowitemowner.cpp b/pv/view/rowitemowner.cpp index d6150f89..8633525e 100644 --- a/pv/view/rowitemowner.cpp +++ b/pv/view/rowitemowner.cpp @@ -29,6 +29,11 @@ using std::vector; namespace pv { namespace view { +vector< shared_ptr >& RowItemOwner::child_items() +{ + return _items; +} + const vector< shared_ptr >& RowItemOwner::child_items() const { return _items; @@ -59,5 +64,25 @@ void RowItemOwner::remove_child_item(std::shared_ptr item) _items.erase(iter); } +RowItemOwner::iterator RowItemOwner::begin() +{ + return iterator(this, _items.begin()); +} + +RowItemOwner::iterator RowItemOwner::end() +{ + return iterator(this); +} + +RowItemOwner::const_iterator RowItemOwner::begin() const +{ + return const_iterator(this, _items.cbegin()); +} + +RowItemOwner::const_iterator RowItemOwner::end() const +{ + return const_iterator(this); +} + } // view } // pv diff --git a/pv/view/rowitemowner.h b/pv/view/rowitemowner.h index 4b538e6d..98df5ff7 100644 --- a/pv/view/rowitemowner.h +++ b/pv/view/rowitemowner.h @@ -24,6 +24,8 @@ #include #include +#include "rowitemiterator.h" + namespace pv { class SigSession; @@ -35,6 +37,11 @@ class View; class RowItemOwner { +public: + typedef std::vector< std::shared_ptr > item_list; + typedef RowItemIterator iterator; + typedef RowItemIterator const_iterator; + public: /** * Returns the session of the onwer. @@ -61,8 +68,12 @@ public: /** * Returns a list of row items owned by this object. */ - virtual const std::vector< std::shared_ptr >& - child_items() const; + virtual item_list& child_items(); + + /** + * Returns a list of row items owned by this object. + */ + virtual const item_list& child_items() const; /** * Clears the list of child items. @@ -79,10 +90,33 @@ public: */ void remove_child_item(std::shared_ptr item); + /** + * Returns a depth-first iterator at the beginning of the child RowItem + * tree. + */ + iterator begin(); + + /** + * Returns a depth-first iterator at the end of the child RowItem tree. + */ + iterator end(); + + /** + * Returns a constant depth-first iterator at the beginning of the + * child RowItem tree. + */ + const_iterator begin() const; + + /** + * Returns a constant depth-first iterator at the end of the child + * RowItem tree. + */ + const_iterator end() const; + virtual void update_viewport() = 0; private: - std::vector< std::shared_ptr > _items; + item_list _items; }; } // view -- 2.30.2