00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef SCPPNT_SLICE_POINTER_H
00020 #define SCPPNT_SLICE_POINTER_H
00021
00022 #ifdef SCPPNT_NO_DIR_PREFIX
00023 #include "scppnt.h"
00024 #include "scppnt_error.h"
00025 #else
00026 #include "scppnt/scppnt.h"
00027 #include "scppnt/scppnt_error.h"
00028 #endif
00029
00030 #include <iterator>
00031 namespace SCPPNT
00032 {
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 template<class T, class PTR, class REF> class slice_pointer_base
00075 {
00076
00077 public:
00078
00079
00080 typedef T value_type;
00081 typedef PTR pointer;
00082 typedef REF reference;
00083 typedef std::random_access_iterator_tag iterator_category;
00084 typedef Subscript difference_type;
00085
00086
00087 slice_pointer_base() :
00088 current(0), span(0)
00089 {
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 slice_pointer_base(pointer first, Subscript span, Subscript size)
00103 {
00104 set(first, span, size);
00105 }
00106
00107
00108 #ifdef SCPPNT_BOUNDS_CHECK
00109 slice_pointer_base(const slice_pointer_base<T, T*, T&> &p)
00110 {
00111 set(p.get_first(), p.get_span(), p.get_size());
00112 current = p.get_current();
00113 }
00114 #else
00115 slice_pointer_base(const slice_pointer_base<T, T*, T&> &p)
00116 {
00117 set(p.get_current(), p.get_span(), 0);
00118 }
00119 #endif
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 #ifdef SCPPNT_BOUNDS_CHECK
00132 void set(pointer first, Subscript span, Subscript size)
00133 #else
00134 void set(pointer first, Subscript span, Subscript)
00135
00136 #endif
00137 {
00138 current = first;
00139 this->span = span;
00140 #ifdef SCPPNT_BOUNDS_CHECK
00141 this->first = first;
00142 last = first + (size-1) * span;
00143 #endif
00144 }
00145
00146
00147
00148
00149 pointer get_current() const
00150 {
00151 return current;
00152 }
00153
00154
00155 Subscript get_span() const
00156 {
00157 return span;
00158 }
00159
00160 #ifdef SCPPNT_BOUNDS_CHECK
00161
00162 void set_size(Subscript size)
00163 {
00164 last = current + (size-1) * span;
00165 first = current;
00166 }
00167
00168
00169 Subscript get_size() const
00170 {
00171 return last-first+1;
00172 }
00173
00174
00175 pointer get_first() const
00176 {
00177 return first;
00178 }
00179 #endif
00180
00181
00182 reference operator*() const
00183 {
00184 #ifdef SCPPNT_BOUNDS_CHECK
00185 if (!current || current < first || current > last)
00186 throw BoundsError("SCPPNT::slice_pointer_base::operator*");
00187 #endif
00188 return *current;
00189 }
00190
00191
00192 pointer operator->() const
00193 {
00194 #ifdef SCPPNT_BOUNDS_CHECK
00195 if (!current || current < first || current > last)
00196 throw BoundsError("SCPPNT::const_slice_pointer_base::operator->");
00197 #endif
00198 return current;
00199 }
00200
00201
00202 reference operator[](Subscript i) const
00203 {
00204 #ifdef SCPPNT_BOUNDS_CHECK
00205 if (!current || (current+i) < first || (current+i) > last)
00206 throw BoundsError("SCPPNT::slice_pointer_base::operator[]");
00207 #endif
00208 return current[i];
00209 }
00210
00211
00212 slice_pointer_base& operator++()
00213 {
00214 current += span;
00215 return *this;
00216 }
00217
00218
00219 slice_pointer_base operator++(int)
00220 {
00221 slice_pointer_base t(*this);
00222 current += span;
00223 return t;
00224 }
00225
00226
00227 slice_pointer_base& operator--()
00228 {
00229 current -= span;
00230 return *this;
00231 }
00232
00233
00234 slice_pointer_base operator--(int)
00235 {
00236 slice_pointer_base t(*this);
00237 current -= span;
00238 return t;
00239 }
00240
00241
00242 slice_pointer_base& operator+=(Subscript i)
00243 {
00244 current += span*i;
00245 return *this;
00246 }
00247
00248
00249 slice_pointer_base& operator-=(Subscript i)
00250 {
00251 current -= span*i;
00252 return *this;
00253 }
00254
00255
00256 slice_pointer_base operator+(Subscript i) const
00257 {
00258 return slice_pointer_base<T,PTR,REF>(*this) += i;
00259 }
00260
00261
00262 slice_pointer_base operator-(Subscript i) const
00263 {
00264 return slice_pointer_base<T,PTR,REF>(*this) -= i;
00265 }
00266
00267 #ifdef SCPPNT_MEMBER_COMPARISONS
00268
00269
00270 Subscript operator-(const slice_pointer_base<T,PTR,REF> &rhs)
00271 {
00272 if (get_span() != rhs.get_span())
00273 throw InvalidArgument("Mismatching spans", "SCPPNT::slice_pointer_base::operator-()");
00274 return (get_current() - rhs.get_current()) / lhs.get_span();
00275 }
00276
00277
00278 bool operator==(const slice_pointer_base<T,PTR,REF> &rhs)
00279 {
00280 return current == rhs.current;
00281 }
00282
00283
00284 bool operator!=(const slice_pointer_base<T,PTR,REF> &rhs)
00285 {
00286 return current != rhs.current;
00287 }
00288
00289
00290 bool operator>(const slice_pointer_base<T,PTR,REF> &rhs)
00291 {
00292 return current > rhs.current;
00293 }
00294
00295
00296 bool operator>=(const slice_pointer_base<T,PTR,REF> &rhs)
00297 {
00298 return current >= rhs.current;
00299 }
00300
00301
00302 bool operator<(const slice_pointer_base<T,PTR,REF> &rhs)
00303 {
00304 return current < rhs.current;
00305 }
00306
00307
00308 bool operator<=(const slice_pointer_base<T,PTR,REF> &rhs)
00309 {
00310 return current <= rhs.current;
00311 }
00312
00313 #else
00314
00315
00316 friend Subscript operator-(const slice_pointer_base<T,PTR,REF> &lhs, const slice_pointer_base<T,PTR,REF> &rhs)
00317 {
00318 if (lhs.get_span() != rhs.get_span())
00319 throw InvalidArgument("Mismatching spans", "SCPPNT::slice_pointer_base::operator-()");
00320 return (lhs.get_current() - rhs.get_current()) / lhs.get_span();
00321 }
00322
00323
00324 friend bool operator==(const slice_pointer_base<T,PTR,REF> &lhs, const slice_pointer_base<T,PTR,REF> &rhs)
00325 {
00326 return lhs.current == rhs.current;
00327 }
00328
00329
00330 friend bool operator!=(const slice_pointer_base<T,PTR,REF> &lhs, const slice_pointer_base<T,PTR,REF> &rhs)
00331 {
00332 return lhs.current != rhs.current;
00333 }
00334
00335
00336 friend bool operator>(const slice_pointer_base<T,PTR,REF> &lhs, const slice_pointer_base<T,PTR,REF> &rhs)
00337 {
00338 return lhs.current > rhs.current;
00339 }
00340
00341
00342 friend bool operator>=(const slice_pointer_base<T,PTR,REF> &lhs, const slice_pointer_base<T,PTR,REF> &rhs)
00343 {
00344 return lhs.current >= rhs.current;
00345 }
00346
00347
00348 friend bool operator<(const slice_pointer_base<T,PTR,REF> &lhs, const slice_pointer_base<T,PTR,REF> &rhs)
00349 {
00350 return lhs.current < rhs.current;
00351 }
00352
00353
00354 friend bool operator<=(const slice_pointer_base<T,PTR,REF> &lhs, const slice_pointer_base<T,PTR,REF> &rhs)
00355 {
00356 return lhs.current <= rhs.current;
00357 }
00358
00359 #endif
00360
00361 private:
00362
00363
00364 pointer current;
00365
00366
00367 Subscript span;
00368
00369 #ifdef SCPPNT_BOUNDS_CHECK
00370 pointer first;
00371 pointer last;
00372 #endif
00373
00374 };
00375
00376 }
00377
00378 #endif // SCPPNT_SLICE_POINTER_H