00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef RPTR_RVEC_HDR
00022 #define RPTR_RVEC_HDR
00023
00024 #include "rptr.h"
00025
00026 #include <vector>
00027 #include <stdexcept>
00028
00029 namespace rptr {
00031
00053 template<class T>
00054 class Rvec {
00055 public:
00056 typedef T value_type;
00057 private:
00058 struct Node {
00059 Rptr<T> ptr;
00060 typename std::vector<Node>::difference_type prev;
00061 typename std::vector<Node>::difference_type next;
00062 Node(): prev(0), next(0) {}
00063 };
00064 public:
00065 typedef value_type &reference;
00066 typedef const value_type &const_reference;
00067 typedef Rptr<T> pointer;
00068 typedef Rptr<const T> const_pointer;
00069 typedef typename std::vector<Node>::difference_type difference_type;
00070 typedef typename std::vector<Node>::size_type size_type;
00071 private:
00072 size_type begn;
00073 size_type rbegn;
00074 size_type sze;
00075 std::vector<Node> v;
00076 public:
00077 class const_iterator;
00078
00080 class iterator {
00081 typename std::vector<Node>::iterator vi;
00082 friend class Rvec;
00083 friend class const_iterator;
00084 inline iterator(typename std::vector<Node>::iterator vi0):
00085 vi(vi0) {}
00086
00087 public:
00088 typedef std::bidirectional_iterator_tag iterator_category;
00089
00090 typedef Rvec::value_type value_type;
00091 typedef Rvec::difference_type difference_type;
00092
00093 typedef Rvec::pointer pointer;
00094 typedef Rvec::reference reference;
00095
00097 inline reference operator *() const {
00098 return *vi->ptr;
00099 }
00101 inline pointer operator ->() const {
00102 return vi->ptr;
00103 }
00105 inline pointer ptr() const {
00106 return vi->ptr;
00107 }
00109 inline bool operator ==(const iterator &right) const {
00110 return vi==right.vi;
00111 }
00113 inline bool operator !=(const iterator &right) const {
00114 return vi!=right.vi;
00115 }
00117 inline bool operator <(const iterator &right) const {
00118 return vi<right.vi;
00119 }
00121 inline iterator & operator ++() {
00122 vi += vi->next;
00123 return *this;
00124 }
00126 inline iterator operator ++(int) {
00127 iterator tmp(*this);
00128 operator++();
00129 return tmp;
00130 }
00132 inline iterator & operator --() {
00133 vi += vi->prev;
00134 return *this;
00135 }
00137 inline iterator operator --(int) {
00138 iterator tmp(*this);
00139 operator--();
00140 return tmp;
00141 }
00142 };
00144 class const_iterator {
00145 typename std::vector<Node>::const_iterator vi;
00146 friend class Rvec;
00147 friend class iterator;
00148 inline const_iterator(typename std::vector<Node>::const_iterator vi0):
00149 vi(vi0) {}
00150
00151 public:
00152 inline const_iterator(const iterator &src): vi(src.vi) {}
00153 typedef std::bidirectional_iterator_tag iterator_category;
00154
00155 typedef Rvec::value_type value_type;
00156 typedef Rvec::difference_type difference_type;
00157
00158 typedef Rvec::const_pointer pointer;
00159 typedef Rvec::const_reference reference;
00160
00162 inline reference operator *() const {
00163 return *vi->ptr;
00164 }
00166 inline pointer operator ->() const {
00167 return vi->ptr;
00168 }
00170 inline pointer ptr() const {
00171 return vi->ptr;
00172 }
00174 inline bool operator ==(const const_iterator &right) const {
00175 return vi==right.vi;
00176 }
00178 inline bool operator !=(const const_iterator &right) const {
00179 return vi!=right.vi;
00180 }
00182 inline bool operator <(const const_iterator &right) const {
00183 return vi<right.vi;
00184 }
00186 inline const_iterator & operator ++() {
00187 vi += vi->next;
00188 return *this;
00189 }
00191 inline const_iterator operator ++(int) {
00192 const_iterator tmp(*this);
00193 operator++();
00194 return tmp;
00195 }
00197 inline const_iterator & operator --() {
00198 vi += vi->prev;
00199 return *this;
00200 }
00202 inline const_iterator operator --(int) {
00203 const_iterator tmp(*this);
00204 operator--();
00205 return tmp;
00206 }
00207 };
00209
00210
00211 inline Rvec(): begn(0), rbegn(0), sze(0), v(1) {
00212 }
00214
00215
00216
00218 inline const_reference operator[](size_type n) const {
00219 if(!defined(n)) {
00220 throw std::out_of_range
00221 ("Rvec - attempt to access undefined element");
00222 }
00223 return *v[n+1].ptr;
00224 }
00227 inline const_pointer ptr(size_type n) const {
00228 if(!defined(n)) {
00229 throw std::out_of_range
00230 ("Rvec - attempt to access undefined element");
00231 }
00232 return v[n+1].ptr;
00233 }
00236 inline const_iterator begin() const {
00237 return const_iterator(v.begin()+begn);
00238 }
00240 inline const_iterator end() const {
00241 return const_iterator(v.begin());
00242 }
00244 inline int ibegin() const {
00245 return begn-1;
00246 }
00248 inline int inext(int id) const {
00249 return id + v[id+1].next;
00250 }
00252 inline int iprev(int id) const {
00253 return id + v[id+1].prev;
00254 }
00256 inline size_type id(const iterator &it) const {
00257 return it.vi-v.begin()-1;
00258 }
00260 inline size_type id(const const_iterator &it) const {
00261 return it.vi-v.begin()-1;
00262 }
00264 inline size_type size() const {
00265 return sze;
00266 }
00268 inline bool defined(size_type n) const {
00269 return n+1>0 && n+1<v.size() && v[n+1].next!=0;
00270 }
00272 inline bool empty() const {
00273 return begn==0;
00274 }
00276
00277
00278
00280 inline iterator begin() {
00281 return iterator(v.begin()+begn);
00282 }
00284 inline iterator end() {
00285 return iterator(v.begin());
00286 }
00289 inline pointer ptr(size_type n) {
00290 if(!defined(n)) {
00291 throw std::out_of_range
00292 ("Rvec - attempt to access undefined position");
00293 }
00294 return v[n+1].ptr;
00295 }
00298 inline reference operator[](size_type n) {
00299 if(!defined(n)) {
00300 throw std::out_of_range
00301 ("Rvec - attempt to access undefined position");
00302 }
00303 return *v[n+1].ptr;
00304 }
00306 inline void swap(const Rvec &src) {
00307 v.swap(src.v);
00308 size_type tmp = src.sze;
00309 src.sze = sze;
00310 sze = tmp;
00311 tmp = src.begn;
00312 src.begn = begn;
00313 begn = tmp;
00314 }
00317 inline size_type insert(pointer x) {
00318 size_type pos;
00319 for(pos=1; pos<v.size(); ++pos) {
00320 if(v[pos].next==0) {
00321 break;
00322 }
00323 }
00324 return set(pos-1,x);
00325 }
00333 size_type set(size_type pos, pointer x);
00335 inline void erase(size_type pos) {
00336 erase(iterator(v.begin()+pos+1));
00337 }
00339 void erase(const iterator &i);
00341 void clear() {
00342 v.resize(1);
00343 sze = rbegn = begn = 0;
00344 }
00346 };
00347
00348 template<class T>
00349 typename Rvec<T>::size_type Rvec<T>::set(size_type pos, pointer x) {
00350 if(x==0) {
00351 if(defined(pos))
00352 erase(pos);
00353 return -1;
00354 }
00355 pos+=1;
00356 if(pos>=v.size()) {
00357
00358 v.resize(pos+1);
00359 }
00360 if(v[pos].next==0) {
00361 size_type prev;
00362
00363 for(prev=pos-1; prev>0; --prev) {
00364 if(v[prev].next!=0) {
00365 break;
00366 }
00367 }
00368 v[pos].prev=prev-pos;
00369 if(prev) {
00370
00371 size_type next = prev+v[prev].next;
00372 v[pos].next=next-pos;
00373 v[prev].next=pos-prev;
00374 if(next) {
00375
00376 v[next].prev=pos-next;
00377 } else {
00378
00379 rbegn = pos;
00380 }
00381 } else {
00382
00383 begn = pos;
00384 size_type next;
00385
00386 for(next=pos+1; next<v.size(); ++next) {
00387 if(v[next].next!=0) {
00388 break;
00389 }
00390 }
00391 if(next<v.size()) {
00392
00393 v[pos].next = next-pos;
00394 v[next].prev = pos-next;
00395 } else {
00396
00397 v[pos].next = -pos;
00398 rbegn=pos;
00399 }
00400 }
00401 ++sze;
00402 }
00403 v[pos].ptr = x;
00404 return pos-1;
00405 }
00406
00407 template<class T>
00408 void Rvec<T>::erase(const iterator &i) {
00409 size_type pos = id(i)+1;
00410 if(pos==0) {
00411 throw std::out_of_range
00412 ("Rvec - attempt to erase 'end()' iterator");
00413 }
00414 if(pos>v.size()) {
00415 throw std::out_of_range
00416 ("Rvec - attempt to erase element out of range");
00417 }
00418 if(v[pos].next==0) {
00419 throw std::out_of_range
00420 ("Rvec - attempt to erase undefined element");
00421 }
00422 size_type next = pos+v[pos].next;
00423 size_type prev = pos+v[pos].prev;
00424 --sze;
00425 if(next) {
00426 if(prev) {
00427 v[next].prev = prev-next;
00428 v[prev].next = next-prev;
00429 } else {
00430
00431 v[next].prev = -next;
00432 begn = next;
00433 }
00434 } else {
00435
00436 if(prev) {
00437 v[prev].next = -prev;
00438 rbegn = prev;
00439 } else {
00440
00441 rbegn = begn = 0;
00442 }
00443 v.resize(rbegn+1);
00444 }
00445 v[pos].ptr = 0;
00446 v[pos].next=v[pos].prev=0;
00447 }
00448 }
00449 #endif