Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(753)

Side by Side Diff: Source/wtf/Deque.h

Issue 390983010: Fix Deque.swap for deques with inline capacity Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Use more fullnesses in test to improve coverage Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « Source/platform/heap/Heap.h ('k') | Source/wtf/DequeTest.cpp » ('j') | Source/wtf/DequeTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698