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