OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2009 Google Inc. All rights reserved. | 3 * Copyright (C) 2009 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 25 matching lines...) Expand all Loading... | |
36 #include "wtf/PassTraits.h" | 36 #include "wtf/PassTraits.h" |
37 #include "wtf/Vector.h" | 37 #include "wtf/Vector.h" |
38 #include <iterator> | 38 #include <iterator> |
39 | 39 |
40 namespace WTF { | 40 namespace WTF { |
41 template<typename T, size_t inlineCapacity, typename Allocator> class DequeI teratorBase; | 41 template<typename T, size_t inlineCapacity, typename Allocator> class DequeI teratorBase; |
42 template<typename T, size_t inlineCapacity, typename Allocator> class DequeI terator; | 42 template<typename T, size_t inlineCapacity, typename Allocator> class DequeI terator; |
43 template<typename T, size_t inlineCapacity, typename Allocator> class DequeC onstIterator; | 43 template<typename T, size_t inlineCapacity, typename Allocator> class DequeC onstIterator; |
44 | 44 |
45 template<typename T, size_t inlineCapacity = 0, typename Allocator = Default Allocator> | 45 template<typename T, size_t inlineCapacity = 0, typename Allocator = Default Allocator> |
46 class Deque : public VectorDestructorBase<Deque<T, inlineCapacity, Allocator >, T, (inlineCapacity > 0), Allocator::isGarbageCollected> { | 46 class Deque : private VectorBuffer<T, inlineCapacity, Allocator>, public Vec torDestructorBase<Deque<T, inlineCapacity, Allocator>, T, (inlineCapacity > 0), Allocator::isGarbageCollected> { |
47 WTF_USE_ALLOCATOR(Deque, Allocator); | 47 WTF_USE_ALLOCATOR(Deque, Allocator); |
48 private: | |
49 private: | |
Mads Ager (chromium)
2014/07/18 11:03:14
Remove this line.
| |
50 typedef VectorBuffer<T, inlineCapacity, Allocator> Base; | |
51 typedef typename Base::Range Range; | |
52 | |
48 public: | 53 public: |
49 typedef DequeIterator<T, inlineCapacity, Allocator> iterator; | 54 typedef DequeIterator<T, inlineCapacity, Allocator> iterator; |
50 typedef DequeConstIterator<T, inlineCapacity, Allocator> const_iterator; | 55 typedef DequeConstIterator<T, inlineCapacity, Allocator> const_iterator; |
51 typedef std::reverse_iterator<iterator> reverse_iterator; | 56 typedef std::reverse_iterator<iterator> reverse_iterator; |
52 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | 57 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
53 typedef PassTraits<T> Pass; | 58 typedef PassTraits<T> Pass; |
54 typedef typename PassTraits<T>::PassType PassType; | 59 typedef typename PassTraits<T>::PassType PassType; |
55 | 60 |
56 Deque(); | 61 Deque(); |
57 Deque(const Deque<T, inlineCapacity, Allocator>&); | 62 Deque(const Deque<T, inlineCapacity, Allocator>&); |
58 // FIXME: Doesn't work if there is an inline buffer, due to crbug.com/36 0572 | 63 Deque<T, inlineCapacity, Allocator>& operator=(const Deque&); |
59 Deque<T, 0, Allocator>& operator=(const Deque&); | |
60 | 64 |
61 void finalize(); | 65 void finalize(); |
62 void finalizeGarbageCollectedObject() { finalize(); } | 66 void finalizeGarbageCollectedObject() { finalize(); } |
63 | 67 |
64 // We hard wire the inlineCapacity to zero here, due to crbug.com/360572 | 68 void swap(Deque&); |
65 void swap(Deque<T, 0, Allocator>&); | |
66 | 69 |
67 size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + m_buffer.capacity() - m_start; } | 70 size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + capacity() - m_start; } |
68 bool isEmpty() const { return m_start == m_end; } | 71 bool isEmpty() const { return m_start == m_end; } |
69 | 72 |
70 iterator begin() { return iterator(this, m_start); } | 73 iterator begin() { return iterator(this, m_start); } |
71 iterator end() { return iterator(this, m_end); } | 74 iterator end() { return iterator(this, m_end); } |
72 const_iterator begin() const { return const_iterator(this, m_start); } | 75 const_iterator begin() const { return const_iterator(this, m_start); } |
73 const_iterator end() const { return const_iterator(this, m_end); } | 76 const_iterator end() const { return const_iterator(this, m_end); } |
74 reverse_iterator rbegin() { return reverse_iterator(end()); } | 77 reverse_iterator rbegin() { return reverse_iterator(end()); } |
75 reverse_iterator rend() { return reverse_iterator(begin()); } | 78 reverse_iterator rend() { return reverse_iterator(begin()); } |
76 const_reverse_iterator rbegin() const { return const_reverse_iterator(en d()); } | 79 const_reverse_iterator rbegin() const { return const_reverse_iterator(en d()); } |
77 const_reverse_iterator rend() const { return const_reverse_iterator(begi n()); } | 80 const_reverse_iterator rend() const { return const_reverse_iterator(begi n()); } |
78 | 81 |
79 T& first() { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start] ; } | 82 T& first() { ASSERT(m_start != m_end); return buffer()[m_start]; } |
80 const T& first() const { ASSERT(m_start != m_end); return m_buffer.buffe r()[m_start]; } | 83 const T& first() const { ASSERT(m_start != m_end); return buffer()[m_sta rt]; } |
81 PassType takeFirst(); | 84 PassType takeFirst(); |
82 | 85 |
83 T& last() { ASSERT(m_start != m_end); return *(--end()); } | 86 T& last() { ASSERT(m_start != m_end); return *(--end()); } |
84 const T& last() const { ASSERT(m_start != m_end); return *(--end()); } | 87 const T& last() const { ASSERT(m_start != m_end); return *(--end()); } |
85 PassType takeLast(); | 88 PassType takeLast(); |
86 | 89 |
87 template<typename U> void append(const U&); | 90 template<typename U> void append(const U&); |
88 template<typename U> void prepend(const U&); | 91 template<typename U> void prepend(const U&); |
89 void removeFirst(); | 92 void removeFirst(); |
90 void removeLast(); | 93 void removeLast(); |
91 void remove(iterator&); | 94 void remove(iterator&); |
92 void remove(const_iterator&); | 95 void remove(const_iterator&); |
93 | 96 |
94 void clear(); | 97 void clear(); |
95 | 98 |
96 template<typename Predicate> | 99 template<typename Predicate> |
97 iterator findIf(Predicate&); | 100 iterator findIf(Predicate&); |
98 | 101 |
99 void trace(typename Allocator::Visitor*); | 102 void trace(typename Allocator::Visitor*); |
100 | 103 |
101 private: | 104 private: |
105 using Base::buffer; | |
106 using Base::capacity; | |
107 using Base::allocateBuffer; | |
108 using Base::clearUnusedSlots; | |
109 using Base::hasOutOfLineBuffer; | |
110 | |
102 friend class DequeIteratorBase<T, inlineCapacity, Allocator>; | 111 friend class DequeIteratorBase<T, inlineCapacity, Allocator>; |
112 friend class VectorBuffer<T, inlineCapacity, Allocator>; | |
Mads Ager (chromium)
2014/07/18 11:03:14
Is this needed? When is the VectorBuffer super cla
Erik Corry
2014/07/22 15:49:26
Not needed yet, removed.
| |
103 | 113 |
104 typedef VectorBuffer<T, inlineCapacity, Allocator> Buffer; | |
105 typedef VectorTypeOperations<T> TypeOperations; | 114 typedef VectorTypeOperations<T> TypeOperations; |
106 typedef DequeIteratorBase<T, inlineCapacity, Allocator> IteratorBase; | 115 typedef DequeIteratorBase<T, inlineCapacity, Allocator> IteratorBase; |
107 | 116 |
108 void remove(size_t position); | 117 void remove(size_t position); |
109 void destroyAll(); | 118 void destroyAll(); |
110 void expandCapacityIfNeeded(); | 119 void expandCapacityIfNeeded(); |
111 void expandCapacity(); | 120 void expandCapacity(); |
112 | 121 |
113 Buffer m_buffer; | |
114 unsigned m_start; | 122 unsigned m_start; |
115 unsigned m_end; | 123 unsigned m_end; |
116 }; | 124 }; |
117 | 125 |
118 template<typename T, size_t inlineCapacity, typename Allocator> | 126 template<typename T, size_t inlineCapacity, typename Allocator> |
119 class DequeIteratorBase { | 127 class DequeIteratorBase { |
120 protected: | 128 protected: |
121 DequeIteratorBase(); | 129 DequeIteratorBase(); |
122 DequeIteratorBase(const Deque<T, inlineCapacity, Allocator>*, size_t); | 130 DequeIteratorBase(const Deque<T, inlineCapacity, Allocator>*, size_t); |
123 DequeIteratorBase(const DequeIteratorBase&); | 131 DequeIteratorBase(const DequeIteratorBase&); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 | 214 |
207 template<typename T, size_t inlineCapacity, typename Allocator> | 215 template<typename T, size_t inlineCapacity, typename Allocator> |
208 inline Deque<T, inlineCapacity, Allocator>::Deque() | 216 inline Deque<T, inlineCapacity, Allocator>::Deque() |
209 : m_start(0) | 217 : m_start(0) |
210 , m_end(0) | 218 , m_end(0) |
211 { | 219 { |
212 } | 220 } |
213 | 221 |
214 template<typename T, size_t inlineCapacity, typename Allocator> | 222 template<typename T, size_t inlineCapacity, typename Allocator> |
215 inline Deque<T, inlineCapacity, Allocator>::Deque(const Deque<T, inlineCapac ity, Allocator>& other) | 223 inline Deque<T, inlineCapacity, Allocator>::Deque(const Deque<T, inlineCapac ity, Allocator>& other) |
216 : m_buffer(other.m_buffer.capacity()) | 224 : VectorBuffer<T, inlineCapacity, Allocator>(other.capacity()) |
217 , m_start(other.m_start) | 225 , m_start(other.m_start) |
218 , m_end(other.m_end) | 226 , m_end(other.m_end) |
219 { | 227 { |
220 const T* otherBuffer = other.m_buffer.buffer(); | 228 const T* otherBuffer = other.buffer(); |
221 if (m_start <= m_end) | 229 if (m_start <= m_end) |
222 TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_end, m_buffer.buffer() + m_start); | 230 TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_end, buffer() + m_start); |
223 else { | 231 else { |
224 TypeOperations::uninitializedCopy(otherBuffer, otherBuffer + m_end, m_buffer.buffer()); | 232 TypeOperations::uninitializedCopy(otherBuffer, otherBuffer + m_end, buffer()); |
225 TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_buffer.capacity(), m_buffer.buffer() + m_start); | 233 TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + capacity(), buffer() + m_start); |
226 } | 234 } |
227 } | 235 } |
228 | 236 |
229 template<typename T, size_t inlineCapacity, typename Allocator> | 237 template<typename T, size_t inlineCapacity, typename Allocator> |
230 void deleteAllValues(const Deque<T, inlineCapacity, Allocator>& collection) | 238 void deleteAllValues(const Deque<T, inlineCapacity, Allocator>& collection) |
231 { | 239 { |
232 typedef typename Deque<T, inlineCapacity, Allocator>::const_iterator ite rator; | 240 typedef typename Deque<T, inlineCapacity, Allocator>::const_iterator ite rator; |
233 iterator end = collection.end(); | 241 iterator end = collection.end(); |
234 for (iterator it = collection.begin(); it != end; ++it) | 242 for (iterator it = collection.begin(); it != end; ++it) |
235 delete *it; | 243 delete *it; |
236 } | 244 } |
237 | 245 |
238 template<typename T, size_t inlineCapacity, typename Allocator> | 246 template<typename T, size_t inlineCapacity, typename Allocator> |
239 inline Deque<T, 0, Allocator>& Deque<T, inlineCapacity, Allocator>::operator =(const Deque& other) | 247 inline Deque<T, inlineCapacity, Allocator>& Deque<T, inlineCapacity, Allocat or>::operator=(const Deque& other) |
240 { | 248 { |
241 Deque<T> copy(other); | 249 Deque copy(other); |
242 swap(copy); | 250 swap(copy); |
243 return *this; | 251 return *this; |
244 } | 252 } |
245 | 253 |
246 template<typename T, size_t inlineCapacity, typename Allocator> | 254 template<typename T, size_t inlineCapacity, typename Allocator> |
247 inline void Deque<T, inlineCapacity, Allocator>::destroyAll() | 255 inline void Deque<T, inlineCapacity, Allocator>::destroyAll() |
248 { | 256 { |
249 if (m_start <= m_end) { | 257 if (m_start <= m_end) { |
250 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffe r() + m_end); | 258 TypeOperations::destruct(buffer() + m_start, buffer() + m_end); |
251 m_buffer.clearUnusedSlots(m_buffer.buffer() + m_start, m_buffer.buff er() + m_end); | 259 clearUnusedSlots(buffer() + m_start, buffer() + m_end); |
252 } else { | 260 } else { |
253 TypeOperations::destruct(m_buffer.buffer(), m_buffer.buffer() + m_en d); | 261 TypeOperations::destruct(buffer(), buffer() + m_end); |
254 m_buffer.clearUnusedSlots(m_buffer.buffer(), m_buffer.buffer() + m_e nd); | 262 clearUnusedSlots(buffer(), buffer() + m_end); |
255 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffe r() + m_buffer.capacity()); | 263 TypeOperations::destruct(buffer() + m_start, buffer() + capacity()); |
256 m_buffer.clearUnusedSlots(m_buffer.buffer() + m_start, m_buffer.buff er() + m_buffer.capacity()); | 264 clearUnusedSlots(buffer() + m_start, buffer() + capacity()); |
257 } | 265 } |
258 } | 266 } |
259 | 267 |
260 // Off-GC-heap deques: Destructor should be called. | 268 // Off-GC-heap deques: Destructor should be called. |
261 // On-GC-heap deques: Destructor should be called for inline buffers | 269 // On-GC-heap deques: Destructor should be called for inline buffers |
262 // (if any) but destructor shouldn't be called for vector backing since | 270 // (if any) but destructor shouldn't be called for vector backing since |
263 // it is managed by the traced GC heap. | 271 // it is managed by the traced GC heap. |
264 template<typename T, size_t inlineCapacity, typename Allocator> | 272 template<typename T, size_t inlineCapacity, typename Allocator> |
265 inline void Deque<T, inlineCapacity, Allocator>::finalize() | 273 inline void Deque<T, inlineCapacity, Allocator>::finalize() |
266 { | 274 { |
267 if (!inlineCapacity && !m_buffer.buffer()) | 275 if (!inlineCapacity && !buffer()) |
268 return; | 276 return; |
269 if (!isEmpty() && !(Allocator::isGarbageCollected && m_buffer.hasOutOfLi neBuffer())) | 277 if (!isEmpty() && !(Allocator::isGarbageCollected && hasOutOfLineBuffer( ))) |
270 destroyAll(); | 278 destroyAll(); |
271 | 279 |
272 m_buffer.destruct(); | 280 Base::destruct(); |
273 } | |
274 | |
275 // FIXME: Doesn't work if there is an inline buffer, due to crbug.com/360572 | |
276 template<typename T, size_t inlineCapacity, typename Allocator> | |
277 inline void Deque<T, inlineCapacity, Allocator>::swap(Deque<T, 0, Allocator> & other) | |
278 { | |
279 std::swap(m_start, other.m_start); | |
280 std::swap(m_end, other.m_end); | |
281 m_buffer.swapVectorBuffer(other.m_buffer); | |
282 } | 281 } |
283 | 282 |
284 template<typename T, size_t inlineCapacity, typename Allocator> | 283 template<typename T, size_t inlineCapacity, typename Allocator> |
Ken Russell (switch to Gerrit)
2014/07/21 20:44:09
Throughout this class, member function templates a
Erik Corry
2014/07/22 15:49:26
This is just because they are defined out of line.
| |
284 inline void Deque<T, inlineCapacity, Allocator>::swap(Deque<T, inlineCapacit y, Allocator>& other) | |
285 { | |
286 Range thisRange = (m_start != m_end && m_end == 0) ? Range(m_start, capa city()) : Range(m_start, m_end); | |
287 Range otherRange = (other.m_start != other.m_end && other.m_end == 0) ? Range(other.m_start, other.capacity()) : Range(other.m_start, other.m_end); | |
288 Base::swapVectorBuffer(other, thisRange, otherRange); | |
289 std::swap(m_start, other.m_start); | |
290 std::swap(m_end, other.m_end); | |
291 } | |
292 | |
293 template<typename T, size_t inlineCapacity, typename Allocator> | |
285 inline void Deque<T, inlineCapacity, Allocator>::clear() | 294 inline void Deque<T, inlineCapacity, Allocator>::clear() |
286 { | 295 { |
287 destroyAll(); | 296 destroyAll(); |
288 m_start = 0; | 297 m_start = 0; |
289 m_end = 0; | 298 m_end = 0; |
290 m_buffer.deallocateBuffer(m_buffer.buffer()); | 299 Base::deallocateBuffer(buffer()); |
291 m_buffer.resetBufferPointer(); | 300 Base::resetBufferPointer(); |
292 } | 301 } |
293 | 302 |
294 template<typename T, size_t inlineCapacity, typename Allocator> | 303 template<typename T, size_t inlineCapacity, typename Allocator> |
295 template<typename Predicate> | 304 template<typename Predicate> |
296 inline DequeIterator<T, inlineCapacity, Allocator> Deque<T, inlineCapacity, Allocator>::findIf(Predicate& predicate) | 305 inline DequeIterator<T, inlineCapacity, Allocator> Deque<T, inlineCapacity, Allocator>::findIf(Predicate& predicate) |
297 { | 306 { |
298 iterator end_iterator = end(); | 307 iterator end_iterator = end(); |
299 for (iterator it = begin(); it != end_iterator; ++it) { | 308 for (iterator it = begin(); it != end_iterator; ++it) { |
300 if (predicate(*it)) | 309 if (predicate(*it)) |
301 return it; | 310 return it; |
302 } | 311 } |
303 return end_iterator; | 312 return end_iterator; |
304 } | 313 } |
305 | 314 |
315 // Because start == end indicates an empty deque, we can never use the last | |
316 // element in the backing. | |
306 template<typename T, size_t inlineCapacity, typename Allocator> | 317 template<typename T, size_t inlineCapacity, typename Allocator> |
307 inline void Deque<T, inlineCapacity, Allocator>::expandCapacityIfNeeded() | 318 inline void Deque<T, inlineCapacity, Allocator>::expandCapacityIfNeeded() |
308 { | 319 { |
309 if (m_start) { | 320 if (m_start) { |
310 if (m_end + 1 != m_start) | 321 if (m_end + 1 != m_start) |
311 return; | 322 return; |
312 } else if (m_end) { | 323 } else if (m_end) { |
313 if (m_end != m_buffer.capacity() - 1) | 324 if (m_end != capacity() - 1) |
314 return; | 325 return; |
315 } else if (m_buffer.capacity()) | 326 } else if (capacity()) |
316 return; | 327 return; |
317 | 328 |
318 expandCapacity(); | 329 expandCapacity(); |
319 } | 330 } |
320 | 331 |
321 template<typename T, size_t inlineCapacity, typename Allocator> | 332 template<typename T, size_t inlineCapacity, typename Allocator> |
322 void Deque<T, inlineCapacity, Allocator>::expandCapacity() | 333 void Deque<T, inlineCapacity, Allocator>::expandCapacity() |
323 { | 334 { |
324 size_t oldCapacity = m_buffer.capacity(); | 335 size_t oldCapacity = capacity(); |
325 T* oldBuffer = m_buffer.buffer(); | 336 T* oldBuffer = buffer(); |
326 m_buffer.allocateBuffer(std::max(static_cast<size_t>(16), oldCapacity + oldCapacity / 4 + 1)); | 337 Base::allocateBuffer(std::max(static_cast<size_t>(16), oldCapacity + old Capacity / 4 + 1)); |
327 if (m_start <= m_end) | 338 if (m_start <= m_end) |
328 TypeOperations::move(oldBuffer + m_start, oldBuffer + m_end, m_buffe r.buffer() + m_start); | 339 TypeOperations::move(oldBuffer + m_start, oldBuffer + m_end, buffer( ) + m_start); |
329 else { | 340 else { |
330 TypeOperations::move(oldBuffer, oldBuffer + m_end, m_buffer.buffer() ); | 341 TypeOperations::move(oldBuffer, oldBuffer + m_end, buffer()); |
331 size_t newStart = m_buffer.capacity() - (oldCapacity - m_start); | 342 size_t newStart = capacity() - (oldCapacity - m_start); |
332 TypeOperations::move(oldBuffer + m_start, oldBuffer + oldCapacity, m _buffer.buffer() + newStart); | 343 TypeOperations::move(oldBuffer + m_start, oldBuffer + oldCapacity, b uffer() + newStart); |
333 m_start = newStart; | 344 m_start = newStart; |
334 } | 345 } |
335 m_buffer.deallocateBuffer(oldBuffer); | 346 Base::deallocateBuffer(oldBuffer); |
336 } | 347 } |
337 | 348 |
338 template<typename T, size_t inlineCapacity, typename Allocator> | 349 template<typename T, size_t inlineCapacity, typename Allocator> |
339 inline typename Deque<T, inlineCapacity, Allocator>::PassType Deque<T, inlin eCapacity, Allocator>::takeFirst() | 350 inline typename Deque<T, inlineCapacity, Allocator>::PassType Deque<T, inlin eCapacity, Allocator>::takeFirst() |
340 { | 351 { |
341 T oldFirst = Pass::transfer(first()); | 352 T oldFirst = Pass::transfer(first()); |
342 removeFirst(); | 353 removeFirst(); |
343 return Pass::transfer(oldFirst); | 354 return Pass::transfer(oldFirst); |
344 } | 355 } |
345 | 356 |
346 template<typename T, size_t inlineCapacity, typename Allocator> | 357 template<typename T, size_t inlineCapacity, typename Allocator> |
347 inline typename Deque<T, inlineCapacity, Allocator>::PassType Deque<T, inlin eCapacity, Allocator>::takeLast() | 358 inline typename Deque<T, inlineCapacity, Allocator>::PassType Deque<T, inlin eCapacity, Allocator>::takeLast() |
348 { | 359 { |
349 T oldLast = Pass::transfer(last()); | 360 T oldLast = Pass::transfer(last()); |
350 removeLast(); | 361 removeLast(); |
351 return Pass::transfer(oldLast); | 362 return Pass::transfer(oldLast); |
352 } | 363 } |
353 | 364 |
354 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> | 365 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> |
355 inline void Deque<T, inlineCapacity, Allocator>::append(const U& value) | 366 inline void Deque<T, inlineCapacity, Allocator>::append(const U& value) |
356 { | 367 { |
357 expandCapacityIfNeeded(); | 368 expandCapacityIfNeeded(); |
358 new (NotNull, &m_buffer.buffer()[m_end]) T(value); | 369 new (NotNull, &buffer()[m_end]) T(value); |
359 if (m_end == m_buffer.capacity() - 1) | 370 if (m_end == capacity() - 1) |
360 m_end = 0; | 371 m_end = 0; |
361 else | 372 else |
362 ++m_end; | 373 ++m_end; |
363 } | 374 } |
364 | 375 |
365 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> | 376 template<typename T, size_t inlineCapacity, typename Allocator> template<typ ename U> |
366 inline void Deque<T, inlineCapacity, Allocator>::prepend(const U& value) | 377 inline void Deque<T, inlineCapacity, Allocator>::prepend(const U& value) |
367 { | 378 { |
368 expandCapacityIfNeeded(); | 379 expandCapacityIfNeeded(); |
369 if (!m_start) | 380 if (!m_start) |
370 m_start = m_buffer.capacity() - 1; | 381 m_start = capacity() - 1; |
371 else | 382 else |
372 --m_start; | 383 --m_start; |
373 new (NotNull, &m_buffer.buffer()[m_start]) T(value); | 384 new (NotNull, &buffer()[m_start]) T(value); |
374 } | 385 } |
375 | 386 |
376 template<typename T, size_t inlineCapacity, typename Allocator> | 387 template<typename T, size_t inlineCapacity, typename Allocator> |
377 inline void Deque<T, inlineCapacity, Allocator>::removeFirst() | 388 inline void Deque<T, inlineCapacity, Allocator>::removeFirst() |
378 { | 389 { |
379 ASSERT(!isEmpty()); | 390 ASSERT(!isEmpty()); |
380 TypeOperations::destruct(&m_buffer.buffer()[m_start], &m_buffer.buffer() [m_start + 1]); | 391 TypeOperations::destruct(&buffer()[m_start], &buffer()[m_start + 1]); |
381 m_buffer.clearUnusedSlots(&m_buffer.buffer()[m_start], &m_buffer.buffer( )[m_start + 1]); | 392 clearUnusedSlots(&buffer()[m_start], &buffer()[m_start + 1]); |
382 if (m_start == m_buffer.capacity() - 1) | 393 if (m_start == capacity() - 1) |
383 m_start = 0; | 394 m_start = 0; |
384 else | 395 else |
385 ++m_start; | 396 ++m_start; |
386 } | 397 } |
387 | 398 |
388 template<typename T, size_t inlineCapacity, typename Allocator> | 399 template<typename T, size_t inlineCapacity, typename Allocator> |
389 inline void Deque<T, inlineCapacity, Allocator>::removeLast() | 400 inline void Deque<T, inlineCapacity, Allocator>::removeLast() |
390 { | 401 { |
391 ASSERT(!isEmpty()); | 402 ASSERT(!isEmpty()); |
392 if (!m_end) | 403 if (!m_end) |
393 m_end = m_buffer.capacity() - 1; | 404 m_end = capacity() - 1; |
394 else | 405 else |
395 --m_end; | 406 --m_end; |
396 TypeOperations::destruct(&m_buffer.buffer()[m_end], &m_buffer.buffer()[m _end + 1]); | 407 TypeOperations::destruct(&buffer()[m_end], &buffer()[m_end + 1]); |
397 m_buffer.clearUnusedSlots(&m_buffer.buffer()[m_end], &m_buffer.buffer()[ m_end + 1]); | 408 clearUnusedSlots(&buffer()[m_end], &buffer()[m_end + 1]); |
398 } | 409 } |
399 | 410 |
400 template<typename T, size_t inlineCapacity, typename Allocator> | 411 template<typename T, size_t inlineCapacity, typename Allocator> |
401 inline void Deque<T, inlineCapacity, Allocator>::remove(iterator& it) | 412 inline void Deque<T, inlineCapacity, Allocator>::remove(iterator& it) |
402 { | 413 { |
403 remove(it.m_index); | 414 remove(it.m_index); |
404 } | 415 } |
405 | 416 |
406 template<typename T, size_t inlineCapacity, typename Allocator> | 417 template<typename T, size_t inlineCapacity, typename Allocator> |
407 inline void Deque<T, inlineCapacity, Allocator>::remove(const_iterator& it) | 418 inline void Deque<T, inlineCapacity, Allocator>::remove(const_iterator& it) |
408 { | 419 { |
409 remove(it.m_index); | 420 remove(it.m_index); |
410 } | 421 } |
411 | 422 |
412 template<typename T, size_t inlineCapacity, typename Allocator> | 423 template<typename T, size_t inlineCapacity, typename Allocator> |
413 inline void Deque<T, inlineCapacity, Allocator>::remove(size_t position) | 424 inline void Deque<T, inlineCapacity, Allocator>::remove(size_t position) |
414 { | 425 { |
415 if (position == m_end) | 426 if (position == m_end) |
416 return; | 427 return; |
417 | 428 |
418 T* buffer = m_buffer.buffer(); | 429 T* buf = buffer(); |
419 TypeOperations::destruct(&buffer[position], &buffer[position + 1]); | 430 TypeOperations::destruct(&buf[position], &buf[position + 1]); |
420 | 431 |
421 // Find which segment of the circular buffer contained the remove elemen t, and only move elements in that part. | 432 // Find which segment of the circular buffer contained the remove elemen t, and only move elements in that part. |
422 if (position >= m_start) { | 433 if (position >= m_start) { |
423 TypeOperations::moveOverlapping(buffer + m_start, buffer + position, buffer + m_start + 1); | 434 TypeOperations::moveOverlapping(buf + m_start, buf + position, buf + m_start + 1); |
424 m_buffer.clearUnusedSlots(buffer + m_start, buffer + m_start + 1); | 435 clearUnusedSlots(buf + m_start, buf + m_start + 1); |
425 m_start = (m_start + 1) % m_buffer.capacity(); | 436 m_start = (m_start + 1) % capacity(); |
426 } else { | 437 } else { |
427 TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_en d, buffer + position); | 438 TypeOperations::moveOverlapping(buf + position + 1, buf + m_end, buf + position); |
428 m_buffer.clearUnusedSlots(buffer + m_end - 1, buffer + m_end); | 439 clearUnusedSlots(buf + m_end - 1, buf + m_end); |
429 m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity(); | 440 m_end = (m_end - 1 + capacity()) % capacity(); |
430 } | 441 } |
431 } | 442 } |
432 | 443 |
433 template<typename T, size_t inlineCapacity, typename Allocator> | 444 template<typename T, size_t inlineCapacity, typename Allocator> |
434 inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase() | 445 inline DequeIteratorBase<T, inlineCapacity, Allocator>::DequeIteratorBase() |
435 : m_deque(0) | 446 : m_deque(0) |
436 { | 447 { |
437 } | 448 } |
438 | 449 |
439 template<typename T, size_t inlineCapacity, typename Allocator> | 450 template<typename T, size_t inlineCapacity, typename Allocator> |
(...skipping 26 matching lines...) Expand all Loading... | |
466 template<typename T, size_t inlineCapacity, typename Allocator> | 477 template<typename T, size_t inlineCapacity, typename Allocator> |
467 inline bool DequeIteratorBase<T, inlineCapacity, Allocator>::isEqual(const D equeIteratorBase& other) const | 478 inline bool DequeIteratorBase<T, inlineCapacity, Allocator>::isEqual(const D equeIteratorBase& other) const |
468 { | 479 { |
469 return m_index == other.m_index; | 480 return m_index == other.m_index; |
470 } | 481 } |
471 | 482 |
472 template<typename T, size_t inlineCapacity, typename Allocator> | 483 template<typename T, size_t inlineCapacity, typename Allocator> |
473 inline void DequeIteratorBase<T, inlineCapacity, Allocator>::increment() | 484 inline void DequeIteratorBase<T, inlineCapacity, Allocator>::increment() |
474 { | 485 { |
475 ASSERT(m_index != m_deque->m_end); | 486 ASSERT(m_index != m_deque->m_end); |
476 ASSERT(m_deque->m_buffer.capacity()); | 487 ASSERT(m_deque->capacity()); |
477 if (m_index == m_deque->m_buffer.capacity() - 1) | 488 if (m_index == m_deque->capacity() - 1) |
478 m_index = 0; | 489 m_index = 0; |
479 else | 490 else |
480 ++m_index; | 491 ++m_index; |
481 } | 492 } |
482 | 493 |
483 template<typename T, size_t inlineCapacity, typename Allocator> | 494 template<typename T, size_t inlineCapacity, typename Allocator> |
484 inline void DequeIteratorBase<T, inlineCapacity, Allocator>::decrement() | 495 inline void DequeIteratorBase<T, inlineCapacity, Allocator>::decrement() |
485 { | 496 { |
486 ASSERT(m_index != m_deque->m_start); | 497 ASSERT(m_index != m_deque->m_start); |
487 ASSERT(m_deque->m_buffer.capacity()); | 498 ASSERT(m_deque->capacity()); |
488 if (!m_index) | 499 if (!m_index) |
489 m_index = m_deque->m_buffer.capacity() - 1; | 500 m_index = m_deque->capacity() - 1; |
490 else | 501 else |
491 --m_index; | 502 --m_index; |
492 } | 503 } |
493 | 504 |
494 template<typename T, size_t inlineCapacity, typename Allocator> | 505 template<typename T, size_t inlineCapacity, typename Allocator> |
495 inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::after() const | 506 inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::after() const |
496 { | 507 { |
497 ASSERT(m_index != m_deque->m_end); | 508 ASSERT(m_index != m_deque->m_end); |
498 return &m_deque->m_buffer.buffer()[m_index]; | 509 return &m_deque->buffer()[m_index]; |
499 } | 510 } |
500 | 511 |
501 template<typename T, size_t inlineCapacity, typename Allocator> | 512 template<typename T, size_t inlineCapacity, typename Allocator> |
502 inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::before() const | 513 inline T* DequeIteratorBase<T, inlineCapacity, Allocator>::before() const |
503 { | 514 { |
504 ASSERT(m_index != m_deque->m_start); | 515 ASSERT(m_index != m_deque->m_start); |
505 if (!m_index) | 516 if (!m_index) |
506 return &m_deque->m_buffer.buffer()[m_deque->m_buffer.capacity() - 1] ; | 517 return &m_deque->buffer()[m_deque->capacity() - 1]; |
507 return &m_deque->m_buffer.buffer()[m_index - 1]; | 518 return &m_deque->buffer()[m_index - 1]; |
508 } | 519 } |
509 | 520 |
510 // This is only called if the allocator is a HeapAllocator. It is used when | 521 // This is only called if the allocator is a HeapAllocator. It is used when |
511 // visiting during a tracing GC. | 522 // visiting during a tracing GC. |
512 template<typename T, size_t inlineCapacity, typename Allocator> | 523 template<typename T, size_t inlineCapacity, typename Allocator> |
513 void Deque<T, inlineCapacity, Allocator>::trace(typename Allocator::Visitor* visitor) | 524 void Deque<T, inlineCapacity, Allocator>::trace(typename Allocator::Visitor* visitor) |
514 { | 525 { |
515 ASSERT(Allocator::isGarbageCollected); // Garbage collector must be enab led. | 526 ASSERT(Allocator::isGarbageCollected); // Garbage collector must be enab led. |
516 const T* bufferBegin = m_buffer.buffer(); | 527 const T* bufferBegin = buffer(); |
517 const T* end = bufferBegin + m_end; | 528 const T* end = bufferBegin + m_end; |
518 if (ShouldBeTraced<VectorTraits<T> >::value) { | 529 if (ShouldBeTraced<VectorTraits<T> >::value) { |
519 if (m_start <= m_end) { | 530 if (m_start <= m_end) { |
520 for (const T* bufferEntry = bufferBegin + m_start; bufferEntry ! = end; bufferEntry++) | 531 for (const T* bufferEntry = bufferBegin + m_start; bufferEntry ! = end; bufferEntry++) |
521 Allocator::template trace<T, VectorTraits<T> >(visitor, *con st_cast<T*>(bufferEntry)); | 532 Allocator::template trace<T, VectorTraits<T> >(visitor, *con st_cast<T*>(bufferEntry)); |
522 } else { | 533 } else { |
523 for (const T* bufferEntry = bufferBegin; bufferEntry != end; buf ferEntry++) | 534 for (const T* bufferEntry = bufferBegin; bufferEntry != end; buf ferEntry++) |
524 Allocator::template trace<T, VectorTraits<T> >(visitor, *con st_cast<T*>(bufferEntry)); | 535 Allocator::template trace<T, VectorTraits<T> >(visitor, *con st_cast<T*>(bufferEntry)); |
525 const T* bufferEnd = m_buffer.buffer() + m_buffer.capacity(); | 536 const T* bufferEnd = buffer() + capacity(); |
526 for (const T* bufferEntry = bufferBegin + m_start; bufferEntry ! = bufferEnd; bufferEntry++) | 537 for (const T* bufferEntry = bufferBegin + m_start; bufferEntry ! = bufferEnd; bufferEntry++) |
527 Allocator::template trace<T, VectorTraits<T> >(visitor, *con st_cast<T*>(bufferEntry)); | 538 Allocator::template trace<T, VectorTraits<T> >(visitor, *con st_cast<T*>(bufferEntry)); |
528 } | 539 } |
529 } | 540 } |
530 if (m_buffer.hasOutOfLineBuffer()) | 541 if (hasOutOfLineBuffer()) |
531 Allocator::markNoTracing(visitor, m_buffer.buffer()); | 542 Allocator::markNoTracing(visitor, buffer()); |
532 } | 543 } |
533 | 544 |
534 #if !ENABLE(OILPAN) | 545 #if !ENABLE(OILPAN) |
535 template<typename T, size_t N> | 546 template<typename T, size_t N> |
536 struct NeedsTracing<Deque<T, N> > { | 547 struct NeedsTracing<Deque<T, N> > { |
537 static const bool value = false; | 548 static const bool value = false; |
538 }; | 549 }; |
539 #endif | 550 #endif |
540 | 551 |
541 } // namespace WTF | 552 } // namespace WTF |
542 | 553 |
543 using WTF::Deque; | 554 using WTF::Deque; |
544 | 555 |
545 #endif // WTF_Deque_h | 556 #endif // WTF_Deque_h |
OLD | NEW |