PulseView  unreleased development snapshot
A Qt-based sigrok GUI
viewitemiterator.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of the PulseView project.
3  *
4  * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef PULSEVIEW_PV_VIEWS_TRACE_VIEWITEMITERATOR_HPP
21 #define PULSEVIEW_PV_VIEWS_TRACE_VIEWITEMITERATOR_HPP
22 
23 #include <algorithm>
24 #include <cassert>
25 #include <iterator>
26 #include <memory>
27 #include <stack>
28 #include <type_traits>
29 #include <vector>
30 
31 #include <pv/session.hpp>
32 
33 using std::dynamic_pointer_cast;
34 using std::forward_iterator_tag;
35 using std::shared_ptr;
36 using std::stack;
37 
38 namespace pv {
39 namespace views {
40 namespace trace {
41 
42 template<class Owner, class Item> class ViewItemIterator
43 {
44 public:
45  typedef typename Owner::item_list::const_iterator child_iterator;
46  typedef shared_ptr<Item> value_type;
47  typedef ptrdiff_t difference_type;
48  typedef value_type pointer;
49  typedef const value_type& reference;
50  typedef forward_iterator_tag iterator_category;
51 
52 public:
53  ViewItemIterator(Owner *owner) :
54  owner_stack_({owner}) {}
55 
56  ViewItemIterator(Owner *owner, child_iterator iter) :
57  owner_stack_({owner}) {
58  assert(owner);
59  if (iter != owner->child_items().end())
60  iter_stack_.push(iter);
61  }
62 
66 
67  reference operator*() const {
68  return *iter_stack_.top();
69  }
70 
71  reference operator->() const {
72  return *this;
73  }
74 
76  assert(!owner_stack_.empty());
77  assert(!iter_stack_.empty());
78 
79  shared_ptr<Owner> owner(dynamic_pointer_cast<Owner>(
80  *iter_stack_.top()));
81  if (owner && !owner->child_items().empty()) {
82  owner_stack_.push(owner.get());
83  iter_stack_.push(owner->child_items().begin());
84  } else {
85  while (!iter_stack_.empty() && (++iter_stack_.top()) ==
86  owner_stack_.top()->child_items().end()) {
87  owner_stack_.pop();
88  iter_stack_.pop();
89  }
90  }
91 
92  return *this;
93  }
94 
97  ++*this;
98  return pre;
99  }
100 
101  bool operator==(const ViewItemIterator &o) const {
102  return (iter_stack_.empty() && o.iter_stack_.empty()) || (
103  iter_stack_.size() == o.iter_stack_.size() &&
104  owner_stack_.top() == o.owner_stack_.top() &&
105  iter_stack_.top() == o.iter_stack_.top());
106  }
107 
108  bool operator!=(const ViewItemIterator &o) const {
109  return !((const ViewItemIterator&)*this == o);
110  }
111 
114  swap(iter_stack_, other.iter_stack_);
115  }
116 
117 private:
118  stack<Owner*> owner_stack_;
119  stack<child_iterator> iter_stack_;
120 };
121 
122 template<class Owner, class Item>
124 {
125  a.swap(b);
126 }
127 
128 } // namespace trace
129 } // namespace views
130 } // namespace pv
131 
132 #endif // PULSEVIEW_PV_VIEWS_TRACE_VIEWITEMITERATOR_HPP
void swap(ViewItemIterator< Owner, Item > &other)
Owner::item_list::const_iterator child_iterator
ViewItemIterator(Owner *owner, child_iterator iter)
ViewItemIterator(const ViewItemIterator< Owner, Item > &o)
bool operator==(const ViewItemIterator &o) const
ViewItemIterator< Owner, Item > operator++(int)
bool operator!=(const ViewItemIterator &o) const
ViewItemIterator< Owner, Item > & operator++()