The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
iterator.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file Generic iterator definitions, to take some mess out of other headers.
17  */
18 
19 #ifndef UTILS_ITERATOR_HPP_INCLUDED
20 #define UTILS_ITERATOR_HPP_INCLUDED
21 
22 #include <iterator>
23 
24 namespace util {
25 
26 // Forward declaration.
27 template<typename Value, class Container, class Deref, class Key> class const_iterator_extend;
28 
29 /// This is an iterator class that extends an existing iterator by overriding
30 /// dereference. Access to the underlying iterator is controlled, promoting
31 /// a black-box approach.
32 ///
33 /// The expected use of this class is as a typedef.
34 /// If used in conjunction with a typedef of const_iterator_extend (with the
35 /// same template parameters), you get conversion to your const iterator.
36 ///
37 /// Value = Intended value_type (result of dereferencing).
38 /// Container = The container whose iterator is being extended.
39 /// Deref = A class whose member
40 /// static const Value& eval(const Container::const_iterator &)
41 /// can be used for dereferencing. (The const's might seem odd, but
42 /// they allow the same class to be used for const_iterator_extend.)
43 /// A const_cast will be used to convert the return value to Value&.
44 /// Key = A class that unlocks the underlying iterator. (This way the
45 /// underlying iterator is not exposed to everyone.) If Key is
46 /// accessible, then the underlying iterator can be obtained via
47 /// get(const Key &).
48 template <typename Value, class Container, class Deref, class Key>
50 {
51 public:
52  // Handy shortcut.
54 
55  // Types required of an iterator:
56  typedef Value value_type;
57  typedef value_type * pointer;
58  typedef value_type & reference;
59  typedef typename base_iter_type::difference_type difference_type;
60  typedef typename base_iter_type::iterator_category iterator_category;
61 
62  /// Default constructor
64  /// Initialized constructor
65  explicit iterator_extend(const base_iter_type & iter) : iter_(iter) {}
66 
67 
68  // Comparison:
69  bool operator==(const iterator_extend & that) const { return iter_ == that.iter_; }
70  bool operator!=(const iterator_extend & that) const { return iter_ != that.iter_; }
71  // For random-access iterators:
72  bool operator<(const iterator_extend & that) const { return iter_ < that.iter_; }
73  bool operator>(const iterator_extend & that) const { return iter_ > that.iter_; }
74  bool operator<=(const iterator_extend & that) const { return iter_ <= that.iter_; }
75  bool operator>=(const iterator_extend & that) const { return iter_ >= that.iter_; }
76 
77  // Dereference:
78  reference operator*() const { return const_cast<Value &>(Deref::eval(iter_)); }
79  pointer operator->() const { return &*(*this); }
80 
81  // Increment/decrement:
82  iterator_extend & operator++() { ++iter_; return *this; }
83  iterator_extend & operator--() { --iter_; return *this; }
86  // Arithmetic (for random-access iterators):
87  iterator_extend & operator+=(difference_type n) { iter_ += n; return *this; }
88  iterator_extend & operator-=(difference_type n) { iter_ -= n; return *this; }
89  iterator_extend operator+(difference_type n) const { return iterator_extend(iter_ + n); }
90  iterator_extend operator-(difference_type n) const { return iterator_extend(iter_ - n); }
91  difference_type operator-(const iterator_extend & that) const { return iter_ - that.iter_; }
93  { return -(that - const_iterator_extend<Value, Container, Deref, Key>(*this)); }
94  reference operator[](difference_type n) const { return *(*this + n); }
95 
96  // Allow access to the underlying iterator to those with the key.
97  const base_iter_type & get(const Key &) const { return iter_; }
98 
99 private:
100  /// The underlying base iterator.
101  base_iter_type iter_;
102 };
103 
104 
105 /// This is a const_iterator class that extends an existing const_iterator by
106 /// overriding dereference. Access to the underlying iterator is controlled,
107 /// promoting a black-box approach.
108 ///
109 /// The expected use of this class is as a typedef.
110 /// If used in conjunction with a typedef of iterator_extend (with the same
111 /// template parameters), you get conversion from your regular iterator.
112 ///
113 /// Value = Intended value_type, minus "const".
114 /// Container = The container whose const_iterator is being extended.
115 /// Deref = A class whose member
116 /// static const Value& eval(const Container::const_iterator &)
117 /// can be used for dereferencing. (This same class can be used
118 /// for iterator_extend.)
119 /// Key = A class that unlocks the underlying const_iterator. (This way
120 /// the underlying const_iterator is not exposed to everyone.) If
121 /// Key is accessible, then the underlying const_iterator can be
122 /// obtained via get(const Key &).
123 template <typename Value, class Container, class Deref, class Key>
125 {
126 public:
127  // Handy shortcut.
128  typedef typename Container::const_iterator base_iter_type;
129 
130  // Types required of an iterator:
131  typedef const Value value_type;
132  typedef value_type * pointer;
133  typedef value_type & reference;
134  typedef typename base_iter_type::difference_type difference_type;
135  typedef typename base_iter_type::iterator_category iterator_category;
136 
137  /// Default constructor
139  /// Initialized constructor
140  explicit const_iterator_extend(const base_iter_type & iter) : iter_(iter) {}
141  /// Conversion from iterator_extend (same parameters).
143  iter_(iter.get(Key()))
144  {}
145 
146  // Comparison:
147  bool operator==(const const_iterator_extend & that) const { return iter_ == that.iter_; }
148  bool operator!=(const const_iterator_extend & that) const { return iter_ != that.iter_; }
149  // For random-access iterators:
150  bool operator<(const const_iterator_extend & that) const { return iter_ < that.iter_; }
151  bool operator>(const const_iterator_extend & that) const { return iter_ > that.iter_; }
152  bool operator<=(const const_iterator_extend & that) const { return iter_ <= that.iter_; }
153  bool operator>=(const const_iterator_extend & that) const { return iter_ >= that.iter_; }
154 
155  // Dereference:
156  reference operator*() const { return Deref::eval(iter_); }
157  pointer operator->() const { return &*(*this); }
158 
159  // Increment/decrement:
160  const_iterator_extend & operator++() { ++iter_; return *this; }
161  const_iterator_extend & operator--() { --iter_; return *this; }
164  // Arithmetic (for random-access iterators):
165  const_iterator_extend & operator+=(difference_type n) { iter_ += n; return *this; }
166  const_iterator_extend & operator-=(difference_type n) { iter_ -= n; return *this; }
167  const_iterator_extend operator+(difference_type n) const { return const_iterator_extend(iter_ + n); }
168  const_iterator_extend operator-(difference_type n) const { return const_iterator_extend(iter_ - n); }
169  difference_type operator-(const const_iterator_extend & that) const { return iter_ - that.iter_; }
170  reference operator[](difference_type n) const { return *(*this + n); }
171 
172  // Allow access to the underlying iterator to those with the key.
173  const base_iter_type & get(const Key &) const { return iter_; }
174 
175 private:
176  /// The underlying base iterator.
177  base_iter_type iter_;
178 };
179 
180 }// namespace util
181 
182 
183 /*
184  * An example of how to use these iterators:
185 
186 #include <vector>
187 
188 class int_vect {
189  // We will store a vector of pointers to int.
190  typedef std::vector<int *> pint_vector;
191  pint_vector data_;
192 
193  // We need a struct to control access to underlying iterators.
194  // Also, it is convenient to put evaluation in a private struct.
195  struct key {
196  // Here we define the conversion from a pint_vector iterator to int.
197  static const int& eval(const pint_vector::const_iterator & iter)
198  { return **iter; }
199  };
200 
201 public:
202  // To the public, we will look like a container of ints.
203  typedef util::iterator_extend <int, pint_vector, key, key> iterator;
204  typedef util::const_iterator_extend<int, pint_vector, key, key> const_iterator;
205  // This gives us iterators that dereference to _int_, but otherwise
206  // behave like iterators of _pint_vector_. The first _key_ defines
207  // how to dereference, while the second _key_ prevents others from
208  // accessing underlying iterators (because key is private).
209 
210 public:
211  // That's the basic definition. Let's move on to some uses, in the guise
212  // of giving others access to our data. But first, so this class is not
213  // completely useless, maybe we should be able to add data to it.
214  void push_back(int i)
215  {
216  data_.push_back(nullptr); // (This two-step approach is for exception safety.)
217  data_.back() = new int(i);
218  }
219 
220  // Now we give read-write access via iterators.
221  iterator begin() { return iterator(data_.begin()); } // Simple creation of iterators.
222  iterator end() { return iterator(data_.end()); }
223  // We won't bother with the const versions for now.
224 
225  // Almost done. To avoid leaking memory, we'll need a destructor.
226  ~int_vect()
227  {
228  // Free all the memory we allocated.
229  for ( iterator it = begin(); it != end(); ++it )
230  delete *it.get(key()); // Accessing the underlying iterator.
231  }
232 };
233 
234 */
235 
236 #endif // UTILS_ITERATOR_HPP_INCLUDED
const_iterator_extend operator--(int)
Definition: iterator.hpp:163
iterator_extend operator+(difference_type n) const
Definition: iterator.hpp:89
value_type & reference
Definition: iterator.hpp:58
base_iter_type iter_
The underlying base iterator.
Definition: iterator.hpp:101
reference operator[](difference_type n) const
Definition: iterator.hpp:94
pointer operator->() const
Definition: iterator.hpp:79
iterator_extend operator++(int)
Definition: iterator.hpp:84
const_iterator_extend operator+(difference_type n) const
Definition: iterator.hpp:167
Container::iterator base_iter_type
Definition: iterator.hpp:53
bool operator==(const const_iterator_extend &that) const
Definition: iterator.hpp:147
bool operator>(const const_iterator_extend &that) const
Definition: iterator.hpp:151
const_iterator_extend operator-(difference_type n) const
Definition: iterator.hpp:168
const_iterator_extend(const base_iter_type &iter)
Initialized constructor.
Definition: iterator.hpp:140
reference operator*() const
Definition: iterator.hpp:78
base_iter_type::difference_type difference_type
Definition: iterator.hpp:134
iterator_extend & operator+=(difference_type n)
Definition: iterator.hpp:87
iterator_extend operator-(difference_type n) const
Definition: iterator.hpp:90
const_iterator_extend & operator--()
Definition: iterator.hpp:161
Definition: lobject.h:387
const_iterator_extend & operator-=(difference_type n)
Definition: iterator.hpp:166
difference_type operator-(const const_iterator_extend< Value, Container, Deref, Key > &that) const
Definition: iterator.hpp:92
iterator_extend & operator--()
Definition: iterator.hpp:83
bool operator==(const iterator_extend &that) const
Definition: iterator.hpp:69
difference_type operator-(const iterator_extend &that) const
Definition: iterator.hpp:91
bool operator<(const iterator_extend &that) const
Definition: iterator.hpp:72
base_iter_type::iterator_category iterator_category
Definition: iterator.hpp:135
bool operator<(const const_iterator_extend &that) const
Definition: iterator.hpp:150
pointer operator->() const
Definition: iterator.hpp:157
iterator_extend(const base_iter_type &iter)
Initialized constructor.
Definition: iterator.hpp:65
reference operator[](difference_type n) const
Definition: iterator.hpp:170
Container::const_iterator base_iter_type
Definition: iterator.hpp:128
iterator_extend operator--(int)
Definition: iterator.hpp:85
bool operator!=(const iterator_extend &that) const
Definition: iterator.hpp:70
bool operator!=(const const_iterator_extend &that) const
Definition: iterator.hpp:148
base_iter_type iter_
The underlying base iterator.
Definition: iterator.hpp:177
iterator_extend & operator-=(difference_type n)
Definition: iterator.hpp:88
difference_type operator-(const const_iterator_extend &that) const
Definition: iterator.hpp:169
const_iterator_extend & operator+=(difference_type n)
Definition: iterator.hpp:165
const_iterator_extend operator++(int)
Definition: iterator.hpp:162
bool operator>(const iterator_extend &that) const
Definition: iterator.hpp:73
const_iterator_extend()
Default constructor.
Definition: iterator.hpp:138
bool operator<=(const const_iterator_extend &that) const
Definition: iterator.hpp:152
iterator_extend & operator++()
Definition: iterator.hpp:82
bool operator>=(const iterator_extend &that) const
Definition: iterator.hpp:75
const base_iter_type & get(const Key &) const
Definition: iterator.hpp:173
bool operator>=(const const_iterator_extend &that) const
Definition: iterator.hpp:153
const_iterator_extend & operator++()
Definition: iterator.hpp:160
GLclampd n
Definition: glew.h:5903
bool operator<=(const iterator_extend &that) const
Definition: iterator.hpp:74
value_type * pointer
Definition: iterator.hpp:57
iterator_extend()
Default constructor.
Definition: iterator.hpp:63
This is a const_iterator class that extends an existing const_iterator by overriding dereference...
Definition: iterator.hpp:27
const_iterator_extend(const iterator_extend< Value, Container, Deref, Key > &iter)
Conversion from iterator_extend (same parameters).
Definition: iterator.hpp:142
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
base_iter_type::difference_type difference_type
Definition: iterator.hpp:59
reference operator*() const
Definition: iterator.hpp:156
base_iter_type::iterator_category iterator_category
Definition: iterator.hpp:60
This is an iterator class that extends an existing iterator by overriding dereference.
Definition: iterator.hpp:49