DSQSS  1.1
link.hpp
説明を見る。
00001 
00002 #ifndef LINK_H
00003 #define LINK_H
00004 
00005 #include <stdio.h>
00006 
00007 //######################################################################
00008 
00009 template <class C> class Linked;
00010 template <class C> class RingIterator;
00011 template <class C> class Ring;
00012 template <class C> class Pool;
00013 
00014 //######################################################################
00015 /*
00016 inline void abort() {
00017   printf("ERROR: Aborting...\n");
00018   exit(0);
00019 };
00020 */
00021 //######################################################################
00022 
00023 template <class C>
00024 class Linked : public C {
00025 
00026 private:
00027 
00028   Linked<C>* p;
00029   Linked<C>* n;
00030 
00031 public:
00032 
00033   void init() { C::init(); p = this; n = this; };
00034 
00035   Linked() { init(); };
00036 
00037   ~Linked() {};
00038 
00039   Linked<C>& prev() { return *p; };
00040 
00041   Linked<C>& next() { return *n; };
00042 
00043   void set_prev(Linked<C>& x) { p = &x; };
00044 
00045   void set_next(Linked<C>& x) { n = &x; };
00046 
00047   void insert_after(Linked<C>& x);
00048 
00049   void insert_before(Linked<C>& x);
00050 
00051   void remove();
00052 
00053   void dump();
00054 
00055 };
00056 
00057 //######################################################################
00058 
00059 // The class C must have the following member functions
00060 //   C& next() ... returns the reference to the next item
00061 //   C& prev() ... returns the reference to the previous item
00062 //   C& remove() ... connect prev() and next() and detatch
00063 //                   itself from the linked list
00064 
00065 template <class C>
00066 class RingIterator {
00067 
00068 private:
00069 
00070 public:
00071 
00072   C* org;
00073   C* cur;
00074 
00075   void init(C& x) {
00076     org = &x;
00077     cur = org;
00078   };
00079 
00080   void init(Ring<C>& r) {
00081     org = &r.root(); 
00082     cur = org;
00083   };
00084 
00085   RingIterator() {};
00086 
00087   RingIterator(const RingIterator& p) {
00088     org = p.org;
00089     cur = p.cur;
00090   };
00091 
00092   RingIterator(C& x) { init(x); };
00093 
00094   RingIterator(Ring<C>& r) { init(r); };
00095 
00096   bool atOrigin() {return cur == org;}; 
00097 
00098   RingIterator<C> operator +(int i) {
00099     RingIterator<C> p;
00100     p.org = org;
00101     p.cur = &(cur->next());
00102     return p; 
00103   };
00104 
00105   RingIterator<C>& operator ++() {
00106     cur = &(cur->next()); 
00107     return *this; 
00108   };
00109 
00110   RingIterator<C>& operator ++(int) { 
00111     cur = &(cur->next()); 
00112     return *this; 
00113   };
00114 
00115   RingIterator<C>& operator --() {
00116     cur = &(cur->prev()); 
00117     return *this; 
00118   };
00119 
00120   RingIterator<C>& operator --(int) { 
00121     cur = &(cur->prev()); 
00122     return *this; 
00123   };
00124 
00125   C* operator ->() { return cur; };
00126   C& operator *() { return *cur; };
00127   void operator =( const C* p ) { cur = p; };
00128   bool operator ==( const C* p ) { return cur == p; };
00129   bool operator !=( const C* p ) { return cur != p; };
00130 
00131 };
00132 
00133 //######################################################################
00134 
00135 // The class C must have the following member functions
00136 //   C::C() ... A newly created object must form a ring by itself
00137 //              (Its next (prev) object is itself.) 
00138 //   C& C::next() ... returns the reference to the next item
00139 //   C& C::prev() ... returns the reference to the previous item
00140 //   C& C::remove() ... connect prev() and next() and detatch
00141 //                   itself from the linked list
00142 
00143 template <class C>
00144 class Ring {
00145 
00146 friend class RingIterator<C>;
00147 
00148 private:
00149 
00150 //  C ROOT;
00151 public:
00152   C ROOT;
00153   C& head() { return ROOT.next(); };
00154   C& tail() { return ROOT.prev(); };
00155 
00156 
00157   typedef RingIterator<C> iterator;
00158 
00159   Ring() {};
00160 
00161   ~Ring() {};
00162 
00163   bool empty() { return ( &(ROOT.next()) == &ROOT ); };
00164 
00165   C& root() { return ROOT; };
00166 
00167   C& first() { return ROOT.next(); };
00168   
00169   void add_head(C& x) {
00170     ROOT.insert_after(x);
00171   };
00172 
00173   void add_tail(C& x) {
00174     ROOT.insert_before(x);
00175   };
00176 
00177   C& remove_head() {
00178     C& x = head();
00179     x.remove();
00180     return x;
00181   };
00182 
00183   C& remove_tail() {
00184     C& x = tail();
00185     x.remove();
00186     return x;
00187   };
00188 
00189   void push(C& x) { add_head(x); };
00190  
00191   C& pop() { return remove_head(); };
00192 
00193   int count();
00194 
00195   RingIterator<C> sort_min();
00196   
00197   void move_to_head(RingIterator<C>);
00198 
00199   void dump() {
00200     RingIterator<C> p(*this);
00201           printf("Root: ");
00202           printf(" %8d -> %8d -> %8d\n", &(p->prev()), &(*p), &(p->next()));
00203         while ( ! (++p).atOrigin() ) p->dump();
00204   }
00205 
00206 };
00207 
00208 //######################################################################
00209 
00210 template <class C>
00211 class Pool : public Ring<C> {
00212 
00213 private:
00214 
00215   int size_max;
00216   int size_min;
00217   int size;
00218 
00219 public:
00220 
00221   Pool() : Ring<C>() {
00222     size = 0;
00223   };
00224   
00225   ~Pool();
00226 
00227   void init(int N);
00228 
00229   void push(C& x) {
00230     size++;
00231     x.init();
00232     Ring<C>::push(x);
00233   };
00234 
00235   C& pop() {
00236     if ( size == 0 ) {
00237       printf("Pool> ERROR. Attempt to extract from an empty pool.\n");
00238       exit(0);
00239     }
00240   
00241     size--;
00242     if (size < size_min )  size_min = size;
00243     C& x = Ring<C>::pop();
00244 //  x.init();
00245     return x;
00246   };
00247 
00248   int number_of_used_elements() { return size_max - size_min; };
00249   void set_n_of_used_elements(int s_used){ size_min = size_max - s_used; };
00250 };
00251 
00252 //######################################################################
00253 //  Member Functions
00254 //######################################################################
00255 
00256 template <class C>
00257 inline void Linked<C>::insert_after(Linked<C>& x) { 
00258   // *p -> *this -> x -> *n
00259   x.set_prev(*this);
00260   x.set_next(this->next());
00261   next().set_prev(x);
00262   set_next(x);
00263 
00264 }
00265 
00266 template <class C>
00267 inline void Linked<C>::insert_before(Linked<C>& x) {
00268   x.set_prev(prev());
00269   x.set_next(*this);//thisは、ROOTインスタンスを指す。
00270   prev().set_next(x);
00271   set_prev(x);
00272 }
00273 
00274 template <class C>
00275 inline void Linked<C>::remove() {
00276   //if (ALERT) {
00277   //  printf("\nLinked::remove> BEFORE\n");
00278   //  printf("Linked::remove> *this:\n");
00279   //  this->dump();
00280   //  printf("Linked::remove> prev():\n");
00281   //  prev().dump();
00282   //  printf("Linked::remove> next():\n");
00283   //  next().dump();
00284   //}
00285   prev().set_next(next());
00286   next().set_prev(prev());
00287   //if (ALERT) {
00288   //  printf("\nLinked::remove> AFTER\n");
00289   //  printf("Linked::remove> *this:\n");
00290   //  this->dump();
00291   //  printf("Linked::remove> prev():\n");
00292   //  prev().dump();
00293   //  printf("Linked::remove> next():\n");
00294   //  next().dump();
00295   //}
00296 }
00297 
00298 template <class C>
00299 inline void Linked<C>::dump() {
00300   printf(" %10d ->%10d ->%10d : ", &prev(), this, &next() );
00301   C::dump();
00302 }
00303 
00304 //######################################################################
00305 
00306 template <class C>
00307 inline int Ring<C>::count() {
00308   int c = 0;
00309   RingIterator<C> p(*this);
00310   while ( ! (++p).atOrigin() ) c++;
00311   return c;
00312 }
00313 
00314 //######################################################################
00315 // C requre operation <
00316 
00317 template <class C>
00318 RingIterator<C> Ring<C>::sort_min(){
00319   RingIterator<C> p1(*this);
00320   RingIterator<C> p2(*this);
00321   ++p1;++p1;
00322   ++p2;
00323   while ( ! p1.atOrigin() ){
00324     if( ( (*p1) < (*p2) ) || ((*p1).V_x == (*p2).V_x ) ){
00325       p2 = p1;
00326       ++p1;
00327       move_to_head(p2) ;
00328     }else{
00329       ++p1;
00330     }
00331   }
00332   return p2;
00333 }
00334   
00335 template <class C>
00336 void Ring<C>::move_to_head(RingIterator<C> it) {
00337   C& Cmin = (*it);
00338   it->remove();
00339   add_head(Cmin);
00340 }
00341 
00342 //######################################################################
00343 
00344 template <class C>
00345 inline void Pool<C>::init(int N) {
00346 
00347 // +++ edit sakakura +++
00348 //if ( ! Ring<C>::empty() ) {
00349 //  printf("Pool: ERROR. Attempt to initialize the pool twice.\n");
00350 //  exit(0);
00351 //}
00352 // +++ edit sakakura +++
00353 
00354   for (int i=0; i<N; i++) {
00355     C& x = *(new C);
00356     add_tail(x);
00357   }
00358   size = N;
00359   size_max = N;
00360   size_min = N;
00361 }
00362 
00363 //======================================================================
00364 
00365 template <class C>
00366 inline Pool<C>::~Pool() {
00367   //  printf("*** Destroying Pool\n");
00368   while ( ! Ring<C>::empty() ) {
00369     C& x = pop();
00370     delete &x;
00371   }
00372 }
00373 
00374 #endif
 全て クラス ネームスペース ファイル 関数 変数 型定義 列挙型の値 フレンド マクロ定義