cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
proxy_iterator.h
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2022 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 
4 #ifndef PROXY_ITERATOR_H_
5 #define PROXY_ITERATOR_H_
6 #include <algorithm> // For std::swap
7 
8 //
9 // Smart pointer class extends a proxy class on a list to provide
10 // random_access_iterator functionality
11 //
12 // Requirements: base class P has members
13 // list_type => typedef for type of base list class
14 // m_list => pointer to base list class
15 // m_index => offset to current list item
16 // ProxyIterator<P,C> is a friend class
17 //
18 // Iterator functionality alters the value of m_index
19 //
20 
21 template<bool, class T>
22 struct EnableIf_c
23 {
24  // In general just pass through type
25  typedef T type;
26 };
27 template<class T>
28 struct EnableIf_c<false, T>
29 {
30  // unless argument is false, in which case map to private internal
31  // type
32 private:
33  class Invalid {};
34 public:
35  typedef Invalid type;
36 };
37 template <class Cond, class T>
38  struct EnableIf: EnableIf_c<Cond::value, T>
39 {
40 };
41 template <class T, class U>
42 struct IsSame
43 {
44  static const bool value = false;
45 };
46 template <class T>
47 struct IsSame<T,T>
48 {
49  static const bool value = true;
50 };
51 template <class T>
52 struct Not
53 {
54  static const bool value = ! T::value;
55 };
56 
57 template<class P, class C>
59 {
60  P proxy;
61  typedef EnableIf<Not<IsSame<P,C> >,
64 public:
65  typedef P value_type;
66  typedef int difference_type;
67  typedef random_access_iterator_tag iterator_category;
68  typedef const value_type &reference;
69  typedef const value_type *pointer;
70  // Construction
71  explicit ProxyIterator(typename P::list_type* list, int index) :
72  proxy(list, index) {}
73  ProxyIterator(const ProxyIterator &other) :
74  proxy(other.proxy.m_list, other.proxy.m_index) {}
75  explicit ProxyIterator(void) : proxy(NULL, 0) {}
76  ProxyIterator &operator=(ProxyIterator other) // Temporary is intentional
77  {
78  swap(other);
79  return *this;
80  }
81  operator const_iterator_type() const
82  {
83  return const_iterator_type(proxy.m_list, proxy.m_index);
84  }
85  // swap member function (to implement canonical exception-safe assignment)
86  void swap(ProxyIterator other)
87  {
88  std::swap(proxy.m_list,other.proxy.m_list);
89  std::swap(proxy.m_index,other.proxy.m_index);
90  }
91  // Associated test (not required)
92  bool associated() const
93  {
94  return proxy.m_list != NULL;
95  }
96  // Equality
97  bool equals(const ProxyIterator &other) const
98  {
99  return other.proxy.m_list == proxy.m_list &&
100  other.proxy.m_index == proxy.m_index;
101  }
102  // Dereference
104  {
105  return proxy;
106  }
108  {
109  // Return a pointer to the contained proxy, so dereferencing
110  // this gives proxy not iterator behaviour.
111  return &proxy;
112  }
113  // Incrementation
115  {
116  ++proxy.m_index;
117  return *this;
118  }
120  {
121  ProxyIterator old(*this);
122  ++*this;
123  return old;
124  }
126  {
127  --proxy.m_index;
128  return *this;
129  }
131  {
132  ProxyIterator old(*this);
133  --*this;
134  return old;
135  }
136  // Member functions to implement standard out-of-line operators
137  // Arithmetic
139  {
140  return ProxyIterator(proxy.m_list,proxy.m_index+i);
141  }
142  // Number of steps between (not required)
143  difference_type diff(const ProxyIterator &other) const
144  {
145  return proxy.m_index - other.proxy.m_index;
146  }
147  // Comparison
148  int cmp(const ProxyIterator &other) const
149  {
150  if (proxy.m_index == other.proxy.m_index)
151  return 0;
152  else if (proxy.m_index > other.proxy.m_index)
153  return 1;
154  else
155  return -1;
156  }
157  // Compound assignment
159  {
160  proxy.m_index += i;
161  return *this;
162  }
164  {
165  proxy.m_index -= i;
166  return *this;
167  }
168  // Offset dereference
170  {
171  return P(proxy.m_list,proxy.m_index+i);
172  }
173 };
174 // Identity
175 template<class P1, class P2, class C>
176  inline bool operator==(const ProxyIterator<P1,C> &a,
177  const ProxyIterator<P2,C> &b)
178 {
179  return ProxyIterator<C,C>(a).equals(ProxyIterator<C,C>(b));
180 }
181 template<class P1,class P2, class C>
182 inline bool operator!=(const ProxyIterator<P1,C> &a,
183  const ProxyIterator<P2,C> &b)
184 {
185  return !(a == b);
186 }
187 // Arithmetic
188 template<class P, class C>
191 {
192  return a.add(i);
193 }
194 template<class P, class C>
197 {
198  return a.add(i);
199 }
200 template<class P, class C>
203 {
204  return a.add(-i);
205 }
206 // Comparison
207 template<class P, class C>
208 inline bool operator>(const ProxyIterator<P,C> &a,
209  const ProxyIterator<P,C> &b)
210 {
211  return a.cmp(b) > 0;
212 }
213 template<class P, class C>
214 inline bool operator>=(const ProxyIterator<P,C> &a,
215  const ProxyIterator<P,C> &b)
216 {
217  return a.cmp(b) >= 0;
218 }
219 template<class P, class C>
220 inline bool operator<(const ProxyIterator<P,C> &a,
221  const ProxyIterator<P,C> &b)
222 {
223  return a.cmp(b) < 0;
224 }
225 template<class P, class C>
226 inline bool operator<=(const ProxyIterator<P,C> &a,
227  const ProxyIterator<P,C> &b)
228 {
229  return a.cmp(b) <= 0;
230 }
231 // Iterator difference (not required)
232 template<class P, class C>
234  const ProxyIterator<P,C> &a, const ProxyIterator<P,C> &b)
235 {
236  return a.diff(b);
237 }
238 
239 #endif
ProxyIterator & operator+=(difference_type i)
reference operator*() const
ProxyIterator & operator=(ProxyIterator other)
static const bool value
const value_type operator[](difference_type i) const
bool associated() const
const ProxyIterator< P, C > operator-(const ProxyIterator< P, C > &a, typename ProxyIterator< P, C >::difference_type i)
random_access_iterator_tag iterator_category
bool operator!=(const count_ptr< T > &a, const count_ptr< T > &b)
Definition: count_ptr.h:113
ProxyIterator operator--(int)
ProxyIterator(typename P::list_type *list, int index)
const value_type & reference
void swap(count_ptr< T > &a, count_ptr< T > &b)
Definition: count_ptr.h:82
void swap(ProxyIterator other)
const pntr< T, lgBC > operator+(const ptrdiff_t n, const pntr< T, lgBC > &t)
ProxyIterator & operator-=(difference_type i)
static const bool value
difference_type diff(const ProxyIterator &other) const
ProxyIterator & operator++()
const_iterator_type_1::type const_iterator_type
int cmp(const ProxyIterator &other) const
bool operator>=(const count_ptr< T > &a, const count_ptr< T > &b)
Definition: count_ptr.h:103
ProxyIterator operator++(int)
const value_type * pointer
ProxyIterator(const ProxyIterator &other)
const ProxyIterator add(difference_type i) const
bool operator==(const count_ptr< T > &a, const count_ptr< T > &b)
Definition: count_ptr.h:108
EnableIf< Not< IsSame< P, C > >, ProxyIterator< C, C > > const_iterator_type_1
bool operator>(const count_ptr< T > &a, const count_ptr< T > &b)
Definition: count_ptr.h:93
ProxyIterator & operator--()
bool equals(const ProxyIterator &other) const
pointer operator->() const