IteratorBase.h
Go to the documentation of this file.
1 #ifndef WIRECELL_ITERATORBASE
2 #define WIRECELL_ITERATORBASE
3 
4 #include <vector>
5 
6 
7 namespace WireCell {
8 
9  /** An abstract base class for an iterator providing access to an
10  * object of type VType.
11  *
12  * See WireCell::Iterator for what to expose to the client in your
13  * class/interface API.
14  */
15  template <typename ValueType>
16  class IteratorBase {
17  public:
18 
19  typedef ValueType value_type;
20 
21  virtual ~IteratorBase() {}
22 
23  virtual bool operator==(const IteratorBase& rhs) const = 0;
24  virtual bool operator!=(const IteratorBase& rhs) const = 0;
25  virtual IteratorBase& operator=(const IteratorBase& rhs) = 0;
26  virtual IteratorBase& operator++() = 0;
27  virtual value_type operator* () const = 0;
28 
29  virtual IteratorBase* clone() const = 0;
30  };
31 
32  /** Handy adapter from an iterator to an abstract base iterator.
33  *
34  * Eg:
35  *
36  * class MyData : virtual public IData {...};
37  * typedef IteratorBase< const IData* > my_base_iterator;
38  * typedef std::vector<MyData*> MyStore;
39  * typedef IteratorAdapter< MyStore::iterator, my_base_iterator > my_iterator;
40  *
41  * typedef std::Iterator<const IMyData*> data_iterator;
42  * typedef std::pair<data_iterator, data_iterator> data_range;
43  *
44  * In interface class:
45  *
46  * data_range get_data() const = 0;
47  *
48  * In implementation with
49  *
50  * MyStore m_store;
51  *
52  * data_range MyImp::get_data() {
53  * return data_range(my_iterator(m_store.begin(),
54  * my_iterator(m_store.end()));
55  * }
56  *
57  * Reasons not to use this adapter and go to the trouble to write
58  * your own iterator class:
59  *
60  * - want to not use up memory making all objects up front
61  *
62  * - can generate them on the fly fast enough.
63  *
64  * - want lazy data access or otherwise, have the iterator "phone
65  * home" to some other container or source of data.
66  *
67  * - simply not using a STL container or something that already
68  * has std::iterators to access the underlying collection.
69  *
70  */
71  template <typename adapted_iterator, typename base_iterator>
73  {
74  public:
75 
77 
78  IteratorAdapter(adapted_iterator it) : m_it(it) {}
79  virtual ~IteratorAdapter() {}
80 
81  const IteratorAdapter& dc(const base_iterator& other) const {
82  return *dynamic_cast<const IteratorAdapter*>(&other); // segfault on type mismatch
83  }
84  bool operator==(const base_iterator& rhs) const {
85  return m_it == dc(rhs).m_it;
86  }
87  bool operator!=(const base_iterator& rhs) const {
88  return m_it != dc(rhs).m_it;
89  }
91  m_it = dc(rhs).m_it;
92  return *this;
93  }
95  ++m_it;
96  return *this;
97  }
98  value_type operator*() const {
99  return *m_it;
100  }
101 
102  base_iterator* clone() const {
103  return new IteratorAdapter(m_it);
104  }
105  private:
106  adapted_iterator m_it;
107  };
108 
109 
110 }
111 
112 #endif
IteratorAdapter(adapted_iterator it)
Definition: IteratorBase.h:78
bool operator!=(const base_iterator &rhs) const
Definition: IteratorBase.h:87
typename traits_t::value_type value_type
base_iterator & operator++()
Definition: IteratorBase.h:94
base_iterator::value_type value_type
Definition: IteratorBase.h:76
const IteratorAdapter & dc(const base_iterator &other) const
Definition: IteratorBase.h:81
value_type operator*() const
Definition: IteratorBase.h:98
virtual IteratorBase * clone() const =0
base_iterator * clone() const
Definition: IteratorBase.h:102
adapted_iterator m_it
Definition: IteratorBase.h:106
virtual value_type operator*() const =0
Definition: Main.h:22
bool operator==(const base_iterator &rhs) const
Definition: IteratorBase.h:84
base_iterator & operator=(const base_iterator &rhs)
Definition: IteratorBase.h:90
virtual bool operator==(const IteratorBase &rhs) const =0
virtual bool operator!=(const IteratorBase &rhs) const =0
virtual IteratorBase & operator++()=0
virtual IteratorBase & operator=(const IteratorBase &rhs)=0