X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=pv%2Fview%2Fviewitemiterator.hpp;fp=pv%2Fview%2Fviewitemiterator.hpp;h=179de383965218d2b31321b96b67686ab424f316;hb=c373f82810ad9c5376a7370118de9dd587ee0e43;hp=0000000000000000000000000000000000000000;hpb=21d5f19c7992046c7a1735096364138eb6de50cf;p=pulseview.git diff --git a/pv/view/viewitemiterator.hpp b/pv/view/viewitemiterator.hpp new file mode 100644 index 0000000..179de38 --- /dev/null +++ b/pv/view/viewitemiterator.hpp @@ -0,0 +1,132 @@ +/* + * 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_VIEWITEMITERATOR_HPP +#define PULSEVIEW_PV_VIEW_VIEWITEMITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace pv { +namespace view { + +template class ViewItemIterator +{ +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: + ViewItemIterator(Owner *owner) : + owner_stack_({owner}) {} + + ViewItemIterator(Owner *owner, child_iterator iter) : + owner_stack_({owner}) { + assert(owner); + if (iter != owner->child_items().end()) + iter_stack_.push(iter); + } + + ViewItemIterator(const ViewItemIterator &o) : + owner_stack_(o.owner_stack_), + iter_stack_(o.iter_stack_) {} + + reference operator*() const { + return *iter_stack_.top(); + } + + reference operator->() const { + return *this; + } + + ViewItemIterator& operator++() { + using std::dynamic_pointer_cast; + using std::shared_ptr; + + assert(!owner_stack_.empty()); + assert(!iter_stack_.empty()); + + shared_ptr owner(dynamic_pointer_cast( + *iter_stack_.top())); + if (owner && !owner->child_items().empty()) { + owner_stack_.push(owner.get()); + iter_stack_.push(owner->child_items().begin()); + } else { + while (!iter_stack_.empty() && (++iter_stack_.top()) == + owner_stack_.top()->child_items().end()) { + owner_stack_.pop(); + iter_stack_.pop(); + } + } + + return *this; + } + + ViewItemIterator operator++(int) { + ViewItemIterator pre = *this; + ++*this; + return pre; + } + + bool operator==(const ViewItemIterator &o) const { + return (iter_stack_.empty() && o.iter_stack_.empty()) || ( + iter_stack_.size() == o.iter_stack_.size() && + owner_stack_.top() == o.owner_stack_.top() && + iter_stack_.top() == o.iter_stack_.top()); + } + + bool operator!=(const ViewItemIterator &o) const { + return !((const ViewItemIterator&)*this == o); + } + + void swap(ViewItemIterator& other) { + swap(owner_stack_, other.owner_stack_); + swap(iter_stack_, other.iter_stack_); + } + +private: + std::stack owner_stack_; + std::stack iter_stack_; +}; + +template +void swap(ViewItemIterator& a, ViewItemIterator& b) +{ + a.swap(b); +} + +} // namespace view +} // namespace pv + +#endif // PULSEVIEW_PV_VIEW_VIEWITEMITERATOR_HPP