Page Speed Optimization Libraries  1.13.35.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vector_deque.h
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http:///www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #ifndef PAGESPEED_KERNEL_BASE_VECTOR_DEQUE_H_
20 #define PAGESPEED_KERNEL_BASE_VECTOR_DEQUE_H_
21 
22 #include <cstddef>
23 #include <cstring>
24 
26 
27 namespace net_instaweb {
28 
47 template<class T> class VectorDeque {
48  public:
52  : start_position_(0),
53  size_minus_1_(static_cast<size_t>(-1)),
54  capacity_minus_1_(initial_capacity() - 1),
55  data_(new T[initial_capacity()]) {
56  }
57  ~VectorDeque() {
58  delete [] data_;
59  data_ = NULL;
60  }
61 
62  static size_t initial_capacity() { return 4; }
63 
64  void push_back(T value) {
65  ExpandIfNecessary();
66  ++size_minus_1_;
67  *PointerAt(size_minus_1_) = value;
68  }
69 
73 # define SPECIAL_CASE_POINTER_AT_0 1
74 
75  void push_front(T value) {
76  ExpandIfNecessary();
77  start_position_ = ModCapacity(start_position_ - 1);
78 # if SPECIAL_CASE_POINTER_AT_0
79  *PointerAt0() = value;
80 # else
81  *PointerAt(0) = value;
82 # endif
83  ++size_minus_1_;
84  }
85 
86  void pop_back() {
87  --size_minus_1_;
88  }
89 
90  void pop_front() {
91  start_position_ = ModCapacity(start_position_ + 1);
92  --size_minus_1_;
93  }
94 
95  T back() const {
96  return *PointerAt(size_minus_1_);
97  }
98 
99  T front() const {
100 # if SPECIAL_CASE_POINTER_AT_0
101  return *PointerAt0();
102 # else
103  return *PointerAt(0);
104 # endif
105  }
106 
107  size_t capacity() const { return capacity_minus_1_ + 1; }
108  size_t size() const { return size_minus_1_ + 1; }
109  bool empty() const { return size_minus_1_ == static_cast<size_t>(-1); }
110 
111  private:
116  size_t ModCapacity(size_t index) const { return index & capacity_minus_1_; }
117 
119  T* PointerAt(size_t position) {
120  return data_ + ModCapacity(start_position_ + position);
121  }
122 
123  const T* PointerAt(size_t position) const {
124  return data_ + ModCapacity(start_position_ + position);
125  }
126 
127 # if SPECIAL_CASE_POINTER_AT_0
128  T* PointerAt0() {
129  return data_ + start_position_;
130  }
131 
132  const T* PointerAt0() const {
133  return data_ + start_position_;
134  }
135 # endif
136 # undef SPECIAL_CASE_POINTER_AT_0
137 
140  void ExpandIfNecessary() {
142  if (size_minus_1_ == capacity_minus_1_) {
165  capacity_minus_1_ = 2 * capacity() - 1;
166  T* old_data = data_;
167  data_ = new T[capacity()];
168  size_t sz = size();
169  if (start_position_ == 0) {
170  memcpy(data_, old_data, sz * sizeof(*data_));
171  } else {
174  memcpy(data_, old_data, start_position_ * sizeof(*data_));
175  size_t size_of_right_chunk = sz - start_position_;
176  size_t new_start_position = start_position_ + sz;
177  memcpy(data_ + new_start_position,
178  old_data + start_position_,
179  size_of_right_chunk * sizeof(*data_));
180  start_position_ = new_start_position;
181  }
182  delete [] old_data;
183  }
184  }
185 
186  size_t start_position_;
187  size_t size_minus_1_;
188  size_t capacity_minus_1_;
189  T* data_;
190 
191 
192 };
193 
194 }
195 
196 #endif
Definition: vector_deque.h:47
VectorDeque()
Definition: vector_deque.h:51