Page Speed Optimization Libraries  1.2.24.1
net/instaweb/util/public/inline_slist.h
Go to the documentation of this file.
00001 // Copyright 2012 Google Inc.
00020 
00021 #ifndef NET_INSTAWEB_UTIL_PUBLIC_INLINE_SLIST_H_
00022 #define NET_INSTAWEB_UTIL_PUBLIC_INLINE_SLIST_H_
00023 
00024 #include <cstddef>
00025 
00026 #include "base/logging.h"  
00027 #include "net/instaweb/util/public/basictypes.h"
00028 
00029 namespace net_instaweb {
00030 
00033 template<class T> class InlineSList;
00034 
00038 template<class T>
00039 class InlineSListElement {
00040  protected:
00041   InlineSListElement() : next_(NULL) {}
00042 
00043  private:
00044   friend class InlineSList<T>;
00045   T* next() { return next_; }
00046   void set_next(T* new_next) { next_ = new_next; }
00047 
00048   T* next_;
00049   DISALLOW_COPY_AND_ASSIGN(InlineSListElement);
00050 };
00051 
00065 template<class T>
00066 class InlineSList {
00067  private:
00078   class IterBase {
00079    protected:
00080     IterBase(const InlineSList<T>* list, T* node)
00081         : list_(list), node_(node) {
00082     }
00083 
00084     bool AtEnd() const {
00085       return (node_ == NULL);
00086     }
00087 
00088     void Advance() {
00089       DCHECK(!AtEnd());
00090       node_ = node_->next();
00093       if (node_ == list_->tail_) {
00094         node_ = NULL;
00095       }
00096     }
00097 
00098     T* Data() {
00099       return node_->next();
00100     }
00101 
00102     bool Equals(const IterBase& other) const {
00103       return (node_ == other.node_) && (list_ == other.list_);
00104     }
00105 
00106    private:
00107     friend class InlineSList<T>;
00108     const InlineSList<T>* list_;
00109     T* node_;
00110   };
00111 
00112  public:
00134   class Iterator : public IterBase {
00135    public:
00136     Iterator& operator++() {
00137       this->Advance();
00138       return *this;
00139     }
00140 
00141     T* Get() { return this->Data(); }
00142     T* operator->() { return this->Data(); }
00143     T& operator*() { return *this->Data(); }
00144     bool operator==(const Iterator& other) const { return this->Equals(other); }
00145     bool operator!=(const Iterator& other) const {
00146       return !this->Equals(other);
00147     }
00149 
00150    private:
00151     friend class InlineSList<T>;
00152     Iterator(const InlineSList<T>* list, T* prev) : IterBase(list, prev) {}
00153   };
00154 
00155   typedef Iterator iterator;
00156 
00159   class ConstIterator : public IterBase {
00160    public:
00161     ConstIterator& operator++() {
00162       this->Advance();
00163       return *this;
00164     }
00165 
00166     const T* Get() { return this->Data(); }
00167     const T* operator->() { return this->Data(); }
00168     const T& operator*() { return *this->Data(); }
00169     bool operator==(const ConstIterator& other) const {
00170       return this->Equals(other);
00171     }
00172     bool operator!=(const ConstIterator& other) const {
00173       return !this->Equals(other);
00174     }
00176 
00177    private:
00178     friend class InlineSList<T>;
00179     ConstIterator(const InlineSList<T>* list, T* prev) : IterBase(list, prev) {}
00180   };
00181 
00182   typedef ConstIterator const_iterator;
00183 
00184   InlineSList() : tail_(NULL) {
00185   }
00186 
00188   ~InlineSList();
00189 
00190   bool IsEmpty() const {
00191     return (tail_ == NULL);
00192   }
00193 
00194   void Append(T* node);
00195 
00201   void Erase(Iterator* iter);
00202 
00204   T* Last() {
00205     DCHECK(!IsEmpty());
00206     return tail_;
00207   }
00208 
00209   const T* Last() const {
00210     DCHECK(!IsEmpty());
00211     return tail_;
00212   }
00213 
00215 
00218   iterator begin() { return Iterator(this, tail_); }
00219   const_iterator begin() const { return ConstIterator(this, tail_); }
00220 
00222   iterator end() { return Iterator(this, NULL); }
00223   const_iterator end() const { return ConstIterator(this, NULL); }
00224 
00225  private:
00229   T* tail_;
00230 
00231   DISALLOW_COPY_AND_ASSIGN(InlineSList);
00232 };
00233 
00234 template<class T>
00235 inline InlineSList<T>::~InlineSList() {
00236   if (tail_ != NULL) {
00237     T* node = tail_->next(); 
00238     while (true) {
00239       T* next = node->next();
00240       delete node;
00241       if (node == tail_) {  
00242         break;
00243       } else {
00244         node = next;
00245       }
00246     }
00247   }
00248   tail_ = NULL;
00249 }
00250 
00251 template<class T>
00252 inline void InlineSList<T>::Append(T* node) {
00253   if (tail_ == NULL) {
00254     tail_ = node;
00255     node->set_next(node);
00256   } else {
00257     node->set_next(tail_->next());
00258     tail_->set_next(node);
00259     tail_ = node;
00260   }
00261 }
00262 
00263 template<class T>
00264 inline void InlineSList<T>::Erase(Iterator* iter) {
00265   DCHECK(!iter->AtEnd());
00266 
00267   T* iter_node = iter->node_;
00268   T* target_node = iter_node->next();
00269 
00270   if (iter_node == target_node) {
00272     tail_ = NULL;
00273     iter->node_ = NULL;
00274   } else {
00275     iter_node->set_next(target_node->next());
00276     if (target_node == tail_) {
00278       tail_ = iter_node;
00280       iter->node_ = NULL;
00281     }
00282   }
00283   delete target_node;
00284 }
00285 
00286 }  
00287 
00288 #endif  ///< NET_INSTAWEB_UTIL_PUBLIC_INLINE_SLIST_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines