00001
00002
00008 #if !defined(__ads_array_IndexIterator_h__)
00009 #define __ads_array_IndexIterator_h__
00010
00011
00012 #if defined(DEBUG_ads) && !defined(DEBUG_IndexIterator)
00013 #define DEBUG_IndexIterator
00014 #endif
00015
00016 #include "IndexRange.h"
00017
00018 #include <iterator>
00019
00020
00021 BEGIN_NAMESPACE_ADS
00022
00023
00025 template<int N, typename T = int>
00026 class IndexIterator :
00027 public std::iterator<std::bidirectional_iterator_tag,
00028 FixedArray<N,T>,
00029 std::ptrdiff_t,
00030 const FixedArray<N,T>*,
00031 const FixedArray<N,T>&> {
00032
00033
00034
00035
00036 private:
00037
00038 typedef
00039 std::iterator<std::bidirectional_iterator_tag,
00040 FixedArray<N,T>,
00041 std::ptrdiff_t,
00042 const FixedArray<N,T>*,
00043 const FixedArray<N,T>&>
00044 Base;
00045
00046
00047
00048
00049
00050 public:
00051
00053 typedef typename Base::iterator_category iterator_category;
00055 typedef typename Base::value_type value_type;
00057 typedef typename Base::difference_type difference_type;
00059 typedef typename Base::pointer pointer;
00061 typedef typename Base::reference reference;
00062
00064 typedef iterator_category IteratorCategory;
00066 typedef value_type Value;
00068 typedef difference_type Difference;
00070 typedef pointer Pointer;
00072 typedef reference Reference;
00073
00075 typedef ads::IndexRange<N,T> IndexRange;
00076
00077
00078
00079
00080
00081 private:
00082
00083 Value _index;
00084 IndexRange _index_range;
00085
00086
00087
00088
00089
00090 private:
00091
00092
00093 IndexIterator();
00094
00095 public:
00096
00097
00099
00100
00102
00105 IndexIterator(const IndexRange& index_range) :
00106 Base(),
00107 _index(index_range.lbounds()),
00108 _index_range(index_range)
00109 {}
00110
00112 IndexIterator(const IndexIterator& x) :
00113 Base(),
00114 _index(x._index),
00115 _index_range(x._index_range)
00116 {}
00117
00119 IndexIterator&
00120 operator=(const IndexIterator& other) {
00121 if (&other != this) {
00122 _index = other._index;
00123 _index_range = other._index_range;
00124 }
00125
00126 return *this;
00127 }
00128
00130 ~IndexIterator()
00131 {}
00132
00134
00136
00137
00139 Reference
00140 operator*() const {
00141
00142 return _index;
00143 }
00144
00146 Pointer
00147 operator->() const {
00148
00149 return &_index;
00150 }
00151
00153 IndexIterator&
00154 operator++() {
00155 increment();
00156 return *this;
00157 }
00158
00160
00164 IndexIterator
00165 operator++(int ) {
00166 IndexIterator x(*this);
00167 ++*this;
00168 return x;
00169 }
00170
00172
00174
00175
00177 IndexIterator&
00178 operator--() {
00179 decrement();
00180 return *this;
00181 }
00182
00184
00188 IndexIterator
00189 operator--(int) {
00190 IndexIterator x(*this);
00191 --*this;
00192 return x;
00193 }
00195
00197
00198
00200 Reference
00201 index() const {
00202 return _index;
00203 }
00204
00206 const IndexRange&
00207 index_range() const {
00208 return _index_range;
00209 }
00210
00212
00214
00215
00217 void
00218 set_begin() {
00219 _index = _index_range.lbounds();
00220 }
00221
00223 void
00224 set_end() {
00225 _index = _index_range.lbounds();
00226 _index[N-1] = _index_range.ubound(N - 1);
00227 }
00228
00230
00231 private:
00232
00233 void
00234 increment() {
00235 ++_index[0];
00236 for (int n = 0; n != N-1; ++n) {
00237 if (_index[n] == _index_range.ubound(n)) {
00238 _index[n] = _index_range.lbound(n);
00239 ++_index[n+1];
00240 }
00241 }
00242 }
00243
00244 void
00245 decrement() {
00246 --_index[0];
00247 for (int n = 0; n != N-1; ++n) {
00248 if (_index[n] == _index_range.lbound(n) - 1) {
00249 _index[n] = _index_range.ubound(n) - 1;
00250 --_index[n+1];
00251 }
00252 }
00253 }
00254
00255 };
00256
00257
00258
00259
00260
00261
00263
00266 template<int N, typename T>
00267 inline
00268 bool
00269 operator==(const IndexIterator<N,T>& x, const IndexIterator<N,T>& y) {
00270 #ifdef DEBUG_IndexIterator
00271 assert(x.index_range() == y.index_range());
00272 #endif
00273 return x.index() == y.index();
00274 }
00275
00277
00280 template<int N, typename T>
00281 inline
00282 bool
00283 operator!=(const IndexIterator<N,T>& x, const IndexIterator<N,T>& y) {
00284 return !(x == y);
00285 }
00286
00287
00288 END_NAMESPACE_ADS
00289
00290 #endif