Page Speed Optimization Libraries  1.4.26.1
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 
00045 template<class T> class VectorDeque {
00046  public:
00049   VectorDeque()
00050       : start_position_(0),
00051         size_minus_1_(static_cast<size_t>(-1)),
00052         capacity_minus_1_(initial_capacity() - 1),
00053         data_(new T[initial_capacity()]) {
00054   }
00055   ~VectorDeque() {
00056     delete [] data_;
00057     data_ = NULL;
00058   }
00059 
00060   static size_t initial_capacity() { return 4; }
00061 
00062   void push_back(T value) {
00063     ExpandIfNecessary();
00064     ++size_minus_1_;
00065     *PointerAt(size_minus_1_) = value;
00066   }
00067 
00071 # define SPECIAL_CASE_POINTER_AT_0 1
00072 
00073   void push_front(T value) {
00074     ExpandIfNecessary();
00075     start_position_ = ModCapacity(start_position_ - 1);
00076 # if SPECIAL_CASE_POINTER_AT_0
00077     *PointerAt0() = value;
00078 # else
00079     *PointerAt(0) = value;
00080 # endif
00081     ++size_minus_1_;
00082   }
00083 
00084   void pop_back() {
00085     --size_minus_1_;
00086   }
00087 
00088   void pop_front() {
00089     start_position_ = ModCapacity(start_position_ + 1);
00090     --size_minus_1_;
00091   }
00092 
00093   T back() const {
00094     return *PointerAt(size_minus_1_);
00095   }
00096 
00097   T front() const {
00098 # if SPECIAL_CASE_POINTER_AT_0
00099     return *PointerAt0();
00100 # else
00101     return *PointerAt(0);
00102 # endif
00103   }
00104 
00105   size_t capacity() const { return capacity_minus_1_ + 1; }
00106   size_t size() const { return size_minus_1_ + 1; }
00107   bool empty() const { return size_minus_1_ == static_cast<size_t>(-1); }
00108 
00109  private:
00114   size_t ModCapacity(size_t index) const { return index & capacity_minus_1_; }
00115 
00117   T* PointerAt(size_t position) {
00118     return data_ + ModCapacity(start_position_ + position);
00119   }
00120 
00121   const T* PointerAt(size_t position) const {
00122     return data_ + ModCapacity(start_position_ + position);
00123   }
00124 
00125 # if SPECIAL_CASE_POINTER_AT_0
00126   T* PointerAt0() {
00127     return data_ + start_position_;
00128   }
00129 
00130   const T* PointerAt0() const {
00131     return data_ + start_position_;
00132   }
00133 # endif
00134 # undef SPECIAL_CASE_POINTER_AT_0
00135 
00138   void ExpandIfNecessary() {
00140     if (size_minus_1_ == capacity_minus_1_) {
00163       capacity_minus_1_ = 2 * capacity() - 1;
00164       T* old_data = data_;
00165       data_ = new T[capacity()];
00166       size_t sz = size();
00167       if (start_position_ == 0) {
00168         memcpy(data_, old_data, sz * sizeof(*data_));
00169       } else {
00172         memcpy(data_, old_data, start_position_ * sizeof(*data_));
00173         size_t size_of_right_chunk = sz - start_position_;
00174         size_t new_start_position = start_position_ + sz;
00175         memcpy(data_ + new_start_position,
00176                old_data + start_position_,
00177                size_of_right_chunk * sizeof(*data_));
00178         start_position_ = new_start_position;
00179       }
00180       delete [] old_data;
00181     }
00182   }
00183 
00184   size_t start_position_;
00185   size_t size_minus_1_;
00186   size_t capacity_minus_1_; 
00187   T* data_;
00188 
00189   DISALLOW_COPY_AND_ASSIGN(VectorDeque);
00190 };
00191 
00192 #endif  ///< NET_INSTAWEB_UTIL_PUBLIC_VECTOR_DEQUE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines