Page Speed Optimization Libraries
1.4.26.1
|
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_