Page Speed Optimization Libraries  1.6.29.3
net/instaweb/util/public/vector_deque.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2012 Google Inc.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http:///www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00018 
00019 #ifndef NET_INSTAWEB_UTIL_PUBLIC_VECTOR_DEQUE_H_
00020 #define NET_INSTAWEB_UTIL_PUBLIC_VECTOR_DEQUE_H_
00021 
00022 #include <cstddef>    
00023 #include <cstring>    
00024 
00025 #include "net/instaweb/util/public/basictypes.h"
00026 
00027 namespace net_instaweb {
00028 
00047 template<class T> class VectorDeque {
00048  public:
00051   VectorDeque()
00052       : start_position_(0),
00053         size_minus_1_(static_cast<size_t>(-1)),
00054         capacity_minus_1_(initial_capacity() - 1),
00055         data_(new T[initial_capacity()]) {
00056   }
00057   ~VectorDeque() {
00058     delete [] data_;
00059     data_ = NULL;
00060   }
00061 
00062   static size_t initial_capacity() { return 4; }
00063 
00064   void push_back(T value) {
00065     ExpandIfNecessary();
00066     ++size_minus_1_;
00067     *PointerAt(size_minus_1_) = value;
00068   }
00069 
00073 # define SPECIAL_CASE_POINTER_AT_0 1
00074 
00075   void push_front(T value) {
00076     ExpandIfNecessary();
00077     start_position_ = ModCapacity(start_position_ - 1);
00078 # if SPECIAL_CASE_POINTER_AT_0
00079     *PointerAt0() = value;
00080 # else
00081     *PointerAt(0) = value;
00082 # endif
00083     ++size_minus_1_;
00084   }
00085 
00086   void pop_back() {
00087     --size_minus_1_;
00088   }
00089 
00090   void pop_front() {
00091     start_position_ = ModCapacity(start_position_ + 1);
00092     --size_minus_1_;
00093   }
00094 
00095   T back() const {
00096     return *PointerAt(size_minus_1_);
00097   }
00098 
00099   T front() const {
00100 # if SPECIAL_CASE_POINTER_AT_0
00101     return *PointerAt0();
00102 # else
00103     return *PointerAt(0);
00104 # endif
00105   }
00106 
00107   size_t capacity() const { return capacity_minus_1_ + 1; }
00108   size_t size() const { return size_minus_1_ + 1; }
00109   bool empty() const { return size_minus_1_ == static_cast<size_t>(-1); }
00110 
00111  private:
00116   size_t ModCapacity(size_t index) const { return index & capacity_minus_1_; }
00117 
00119   T* PointerAt(size_t position) {
00120     return data_ + ModCapacity(start_position_ + position);
00121   }
00122 
00123   const T* PointerAt(size_t position) const {
00124     return data_ + ModCapacity(start_position_ + position);
00125   }
00126 
00127 # if SPECIAL_CASE_POINTER_AT_0
00128   T* PointerAt0() {
00129     return data_ + start_position_;
00130   }
00131 
00132   const T* PointerAt0() const {
00133     return data_ + start_position_;
00134   }
00135 # endif
00136 # undef SPECIAL_CASE_POINTER_AT_0
00137 
00140   void ExpandIfNecessary() {
00142     if (size_minus_1_ == capacity_minus_1_) {
00165       capacity_minus_1_ = 2 * capacity() - 1;
00166       T* old_data = data_;
00167       data_ = new T[capacity()];
00168       size_t sz = size();
00169       if (start_position_ == 0) {
00170         memcpy(data_, old_data, sz * sizeof(*data_));
00171       } else {
00174         memcpy(data_, old_data, start_position_ * sizeof(*data_));
00175         size_t size_of_right_chunk = sz - start_position_;
00176         size_t new_start_position = start_position_ + sz;
00177         memcpy(data_ + new_start_position,
00178                old_data + start_position_,
00179                size_of_right_chunk * sizeof(*data_));
00180         start_position_ = new_start_position;
00181       }
00182       delete [] old_data;
00183     }
00184   }
00185 
00186   size_t start_position_;
00187   size_t size_minus_1_;
00188   size_t capacity_minus_1_; 
00189   T* data_;
00190 
00191   DISALLOW_COPY_AND_ASSIGN(VectorDeque);
00192 };
00193 
00194 }  
00195 
00196 #endif  ///< NET_INSTAWEB_UTIL_PUBLIC_VECTOR_DEQUE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines