]> git.saurik.com Git - apple/javascriptcore.git/blame - wtf/Deque.h
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / wtf / Deque.h
CommitLineData
b37bf2e1
A
1/*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
ba379fdc 3 * Copyright (C) 2009 Google Inc. All rights reserved.
b37bf2e1
A
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#ifndef WTF_Deque_h
31#define WTF_Deque_h
32
33// FIXME: Could move what Vector and Deque share into a separate file.
34// Deque doesn't actually use Vector.
35
14957cd0 36#include "PassTraits.h"
b37bf2e1
A
37#include "Vector.h"
38
39namespace WTF {
40
14957cd0
A
41 template<typename T, size_t inlineCapacity> class DequeIteratorBase;
42 template<typename T, size_t inlineCapacity> class DequeIterator;
43 template<typename T, size_t inlineCapacity> class DequeConstIterator;
44 template<typename T, size_t inlineCapacity> class DequeReverseIterator;
45 template<typename T, size_t inlineCapacity> class DequeConstReverseIterator;
b37bf2e1 46
14957cd0
A
47 template<typename T, size_t inlineCapacity = 0>
48 class Deque {
49 WTF_MAKE_FAST_ALLOCATED;
b37bf2e1 50 public:
14957cd0
A
51 typedef DequeIterator<T, inlineCapacity> iterator;
52 typedef DequeConstIterator<T, inlineCapacity> const_iterator;
53 typedef DequeReverseIterator<T, inlineCapacity> reverse_iterator;
54 typedef DequeConstReverseIterator<T, inlineCapacity> const_reverse_iterator;
55 typedef PassTraits<T> Pass;
56 typedef typename PassTraits<T>::PassType PassType;
b37bf2e1
A
57
58 Deque();
14957cd0
A
59 Deque(const Deque<T, inlineCapacity>&);
60 Deque& operator=(const Deque<T, inlineCapacity>&);
b37bf2e1
A
61 ~Deque();
62
14957cd0 63 void swap(Deque<T, inlineCapacity>&);
b37bf2e1
A
64
65 size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + m_buffer.capacity() - m_start; }
66 bool isEmpty() const { return m_start == m_end; }
67
68 iterator begin() { return iterator(this, m_start); }
69 iterator end() { return iterator(this, m_end); }
70 const_iterator begin() const { return const_iterator(this, m_start); }
71 const_iterator end() const { return const_iterator(this, m_end); }
72 reverse_iterator rbegin() { return reverse_iterator(this, m_end); }
73 reverse_iterator rend() { return reverse_iterator(this, m_start); }
74 const_reverse_iterator rbegin() const { return const_reverse_iterator(this, m_end); }
75 const_reverse_iterator rend() const { return const_reverse_iterator(this, m_start); }
76
77 T& first() { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
78 const T& first() const { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
14957cd0 79 PassType takeFirst();
b37bf2e1
A
80
81 template<typename U> void append(const U&);
82 template<typename U> void prepend(const U&);
83 void removeFirst();
ba379fdc
A
84 void remove(iterator&);
85 void remove(const_iterator&);
b37bf2e1
A
86
87 void clear();
88
ba379fdc
A
89 template<typename Predicate>
90 iterator findIf(Predicate&);
91
b37bf2e1 92 private:
14957cd0 93 friend class DequeIteratorBase<T, inlineCapacity>;
b37bf2e1 94
14957cd0 95 typedef VectorBuffer<T, inlineCapacity> Buffer;
b37bf2e1 96 typedef VectorTypeOperations<T> TypeOperations;
14957cd0 97 typedef DequeIteratorBase<T, inlineCapacity> IteratorBase;
b37bf2e1 98
ba379fdc 99 void remove(size_t position);
b37bf2e1
A
100 void invalidateIterators();
101 void destroyAll();
102 void checkValidity() const;
103 void checkIndexValidity(size_t) const;
104 void expandCapacityIfNeeded();
105 void expandCapacity();
106
107 size_t m_start;
108 size_t m_end;
109 Buffer m_buffer;
110#ifndef NDEBUG
111 mutable IteratorBase* m_iterators;
112#endif
113 };
114
14957cd0 115 template<typename T, size_t inlineCapacity = 0>
b37bf2e1
A
116 class DequeIteratorBase {
117 private:
14957cd0 118 typedef DequeIteratorBase<T, inlineCapacity> Base;
b37bf2e1
A
119
120 protected:
121 DequeIteratorBase();
14957cd0 122 DequeIteratorBase(const Deque<T, inlineCapacity>*, size_t);
b37bf2e1
A
123 DequeIteratorBase(const Base&);
124 Base& operator=(const Base&);
125 ~DequeIteratorBase();
126
127 void assign(const Base& other) { *this = other; }
128
129 void increment();
130 void decrement();
131
132 T* before() const;
133 T* after() const;
134
135 bool isEqual(const Base&) const;
136
137 private:
138 void addToIteratorsList();
ba379fdc 139 void removeFromIteratorsList();
b37bf2e1
A
140 void checkValidity() const;
141 void checkValidity(const Base&) const;
142
14957cd0 143 Deque<T, inlineCapacity>* m_deque;
b37bf2e1
A
144 size_t m_index;
145
14957cd0 146 friend class Deque<T, inlineCapacity>;
b37bf2e1
A
147
148#ifndef NDEBUG
149 mutable DequeIteratorBase* m_next;
150 mutable DequeIteratorBase* m_previous;
151#endif
152 };
153
14957cd0
A
154 template<typename T, size_t inlineCapacity = 0>
155 class DequeIterator : public DequeIteratorBase<T, inlineCapacity> {
b37bf2e1 156 private:
14957cd0
A
157 typedef DequeIteratorBase<T, inlineCapacity> Base;
158 typedef DequeIterator<T, inlineCapacity> Iterator;
b37bf2e1
A
159
160 public:
14957cd0 161 DequeIterator(Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
b37bf2e1
A
162
163 DequeIterator(const Iterator& other) : Base(other) { }
164 DequeIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
165
166 T& operator*() const { return *Base::after(); }
167 T* operator->() const { return Base::after(); }
168
169 bool operator==(const Iterator& other) const { return Base::isEqual(other); }
170 bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
171
172 Iterator& operator++() { Base::increment(); return *this; }
173 // postfix ++ intentionally omitted
174 Iterator& operator--() { Base::decrement(); return *this; }
175 // postfix -- intentionally omitted
176 };
177
14957cd0
A
178 template<typename T, size_t inlineCapacity = 0>
179 class DequeConstIterator : public DequeIteratorBase<T, inlineCapacity> {
b37bf2e1 180 private:
14957cd0
A
181 typedef DequeIteratorBase<T, inlineCapacity> Base;
182 typedef DequeConstIterator<T, inlineCapacity> Iterator;
183 typedef DequeIterator<T, inlineCapacity> NonConstIterator;
b37bf2e1
A
184
185 public:
14957cd0 186 DequeConstIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
b37bf2e1
A
187
188 DequeConstIterator(const Iterator& other) : Base(other) { }
189 DequeConstIterator(const NonConstIterator& other) : Base(other) { }
190 DequeConstIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
191 DequeConstIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; }
192
193 const T& operator*() const { return *Base::after(); }
194 const T* operator->() const { return Base::after(); }
195
196 bool operator==(const Iterator& other) const { return Base::isEqual(other); }
197 bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
198
199 Iterator& operator++() { Base::increment(); return *this; }
200 // postfix ++ intentionally omitted
201 Iterator& operator--() { Base::decrement(); return *this; }
202 // postfix -- intentionally omitted
203 };
204
14957cd0
A
205 template<typename T, size_t inlineCapacity = 0>
206 class DequeReverseIterator : public DequeIteratorBase<T, inlineCapacity> {
b37bf2e1 207 private:
14957cd0
A
208 typedef DequeIteratorBase<T, inlineCapacity> Base;
209 typedef DequeReverseIterator<T, inlineCapacity> Iterator;
b37bf2e1
A
210
211 public:
14957cd0 212 DequeReverseIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
b37bf2e1
A
213
214 DequeReverseIterator(const Iterator& other) : Base(other) { }
215 DequeReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
216
217 T& operator*() const { return *Base::before(); }
218 T* operator->() const { return Base::before(); }
219
220 bool operator==(const Iterator& other) const { return Base::isEqual(other); }
221 bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
222
223 Iterator& operator++() { Base::decrement(); return *this; }
224 // postfix ++ intentionally omitted
225 Iterator& operator--() { Base::increment(); return *this; }
226 // postfix -- intentionally omitted
227 };
228
14957cd0
A
229 template<typename T, size_t inlineCapacity = 0>
230 class DequeConstReverseIterator : public DequeIteratorBase<T, inlineCapacity> {
b37bf2e1 231 private:
14957cd0
A
232 typedef DequeIteratorBase<T, inlineCapacity> Base;
233 typedef DequeConstReverseIterator<T, inlineCapacity> Iterator;
234 typedef DequeReverseIterator<T, inlineCapacity> NonConstIterator;
b37bf2e1
A
235
236 public:
14957cd0 237 DequeConstReverseIterator(const Deque<T, inlineCapacity>* deque, size_t index) : Base(deque, index) { }
b37bf2e1
A
238
239 DequeConstReverseIterator(const Iterator& other) : Base(other) { }
240 DequeConstReverseIterator(const NonConstIterator& other) : Base(other) { }
241 DequeConstReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
242 DequeConstReverseIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; }
243
244 const T& operator*() const { return *Base::before(); }
245 const T* operator->() const { return Base::before(); }
246
247 bool operator==(const Iterator& other) const { return Base::isEqual(other); }
248 bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
249
250 Iterator& operator++() { Base::decrement(); return *this; }
251 // postfix ++ intentionally omitted
252 Iterator& operator--() { Base::increment(); return *this; }
253 // postfix -- intentionally omitted
254 };
255
256#ifdef NDEBUG
14957cd0
A
257 template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkValidity() const { }
258 template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::checkIndexValidity(size_t) const { }
259 template<typename T, size_t inlineCapacity> inline void Deque<T, inlineCapacity>::invalidateIterators() { }
b37bf2e1 260#else
14957cd0
A
261 template<typename T, size_t inlineCapacity>
262 void Deque<T, inlineCapacity>::checkValidity() const
b37bf2e1 263 {
14957cd0
A
264 // In this implementation a capacity of 1 would confuse append() and
265 // other places that assume the index after capacity - 1 is 0.
266 ASSERT(m_buffer.capacity() != 1);
267
b37bf2e1
A
268 if (!m_buffer.capacity()) {
269 ASSERT(!m_start);
270 ASSERT(!m_end);
271 } else {
272 ASSERT(m_start < m_buffer.capacity());
273 ASSERT(m_end < m_buffer.capacity());
274 }
275 }
276
14957cd0
A
277 template<typename T, size_t inlineCapacity>
278 void Deque<T, inlineCapacity>::checkIndexValidity(size_t index) const
b37bf2e1
A
279 {
280 ASSERT(index <= m_buffer.capacity());
281 if (m_start <= m_end) {
282 ASSERT(index >= m_start);
283 ASSERT(index <= m_end);
284 } else {
285 ASSERT(index >= m_start || index <= m_end);
286 }
287 }
288
14957cd0
A
289 template<typename T, size_t inlineCapacity>
290 void Deque<T, inlineCapacity>::invalidateIterators()
b37bf2e1
A
291 {
292 IteratorBase* next;
293 for (IteratorBase* p = m_iterators; p; p = next) {
294 next = p->m_next;
295 p->m_deque = 0;
296 p->m_next = 0;
297 p->m_previous = 0;
298 }
299 m_iterators = 0;
300 }
301#endif
302
14957cd0
A
303 template<typename T, size_t inlineCapacity>
304 inline Deque<T, inlineCapacity>::Deque()
b37bf2e1
A
305 : m_start(0)
306 , m_end(0)
307#ifndef NDEBUG
308 , m_iterators(0)
309#endif
310 {
311 checkValidity();
312 }
313
14957cd0
A
314 template<typename T, size_t inlineCapacity>
315 inline Deque<T, inlineCapacity>::Deque(const Deque<T, inlineCapacity>& other)
b37bf2e1
A
316 : m_start(other.m_start)
317 , m_end(other.m_end)
318 , m_buffer(other.m_buffer.capacity())
319#ifndef NDEBUG
320 , m_iterators(0)
321#endif
322 {
323 const T* otherBuffer = other.m_buffer.buffer();
324 if (m_start <= m_end)
325 TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_end, m_buffer.buffer() + m_start);
326 else {
327 TypeOperations::uninitializedCopy(otherBuffer, otherBuffer + m_end, m_buffer.buffer());
328 TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_buffer.capacity(), m_buffer.buffer() + m_start);
329 }
330 }
331
14957cd0
A
332 template<typename T, size_t inlineCapacity>
333 void deleteAllValues(const Deque<T, inlineCapacity>& collection)
9dae56ea 334 {
14957cd0 335 typedef typename Deque<T, inlineCapacity>::const_iterator iterator;
9dae56ea
A
336 iterator end = collection.end();
337 for (iterator it = collection.begin(); it != end; ++it)
338 delete *it;
339 }
340
14957cd0
A
341 template<typename T, size_t inlineCapacity>
342 inline Deque<T, inlineCapacity>& Deque<T, inlineCapacity>::operator=(const Deque<T, inlineCapacity>& other)
b37bf2e1 343 {
14957cd0
A
344 // FIXME: This is inefficient if we're using an inline buffer and T is
345 // expensive to copy since it will copy the buffer twice instead of once.
b37bf2e1
A
346 Deque<T> copy(other);
347 swap(copy);
348 return *this;
349 }
350
14957cd0
A
351 template<typename T, size_t inlineCapacity>
352 inline void Deque<T, inlineCapacity>::destroyAll()
b37bf2e1
A
353 {
354 if (m_start <= m_end)
355 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_end);
356 else {
357 TypeOperations::destruct(m_buffer.buffer(), m_buffer.buffer() + m_end);
358 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_buffer.capacity());
359 }
360 }
361
14957cd0
A
362 template<typename T, size_t inlineCapacity>
363 inline Deque<T, inlineCapacity>::~Deque()
b37bf2e1
A
364 {
365 checkValidity();
366 invalidateIterators();
367 destroyAll();
368 }
369
14957cd0
A
370 template<typename T, size_t inlineCapacity>
371 inline void Deque<T, inlineCapacity>::swap(Deque<T, inlineCapacity>& other)
b37bf2e1
A
372 {
373 checkValidity();
374 other.checkValidity();
375 invalidateIterators();
376 std::swap(m_start, other.m_start);
377 std::swap(m_end, other.m_end);
378 m_buffer.swap(other.m_buffer);
379 checkValidity();
380 other.checkValidity();
381 }
382
14957cd0
A
383 template<typename T, size_t inlineCapacity>
384 inline void Deque<T, inlineCapacity>::clear()
b37bf2e1
A
385 {
386 checkValidity();
387 invalidateIterators();
388 destroyAll();
389 m_start = 0;
390 m_end = 0;
391 checkValidity();
392 }
393
14957cd0 394 template<typename T, size_t inlineCapacity>
ba379fdc 395 template<typename Predicate>
14957cd0 396 inline DequeIterator<T, inlineCapacity> Deque<T, inlineCapacity>::findIf(Predicate& predicate)
ba379fdc
A
397 {
398 iterator end_iterator = end();
399 for (iterator it = begin(); it != end_iterator; ++it) {
400 if (predicate(*it))
401 return it;
402 }
403 return end_iterator;
404 }
405
14957cd0
A
406 template<typename T, size_t inlineCapacity>
407 inline void Deque<T, inlineCapacity>::expandCapacityIfNeeded()
b37bf2e1
A
408 {
409 if (m_start) {
410 if (m_end + 1 != m_start)
411 return;
412 } else if (m_end) {
413 if (m_end != m_buffer.capacity() - 1)
414 return;
415 } else if (m_buffer.capacity())
416 return;
417
418 expandCapacity();
419 }
420
14957cd0
A
421 template<typename T, size_t inlineCapacity>
422 void Deque<T, inlineCapacity>::expandCapacity()
b37bf2e1
A
423 {
424 checkValidity();
425 size_t oldCapacity = m_buffer.capacity();
426 size_t newCapacity = max(static_cast<size_t>(16), oldCapacity + oldCapacity / 4 + 1);
427 T* oldBuffer = m_buffer.buffer();
428 m_buffer.allocateBuffer(newCapacity);
429 if (m_start <= m_end)
430 TypeOperations::move(oldBuffer + m_start, oldBuffer + m_end, m_buffer.buffer() + m_start);
431 else {
432 TypeOperations::move(oldBuffer, oldBuffer + m_end, m_buffer.buffer());
433 size_t newStart = newCapacity - (oldCapacity - m_start);
434 TypeOperations::move(oldBuffer + m_start, oldBuffer + oldCapacity, m_buffer.buffer() + newStart);
435 m_start = newStart;
436 }
437 m_buffer.deallocateBuffer(oldBuffer);
438 checkValidity();
439 }
440
14957cd0
A
441 template<typename T, size_t inlineCapacity>
442 inline typename Deque<T, inlineCapacity>::PassType Deque<T, inlineCapacity>::takeFirst()
443 {
444 T oldFirst = Pass::transfer(first());
445 removeFirst();
446 return Pass::transfer(oldFirst);
447 }
448
449 template<typename T, size_t inlineCapacity> template<typename U>
450 inline void Deque<T, inlineCapacity>::append(const U& value)
b37bf2e1
A
451 {
452 checkValidity();
453 expandCapacityIfNeeded();
454 new (&m_buffer.buffer()[m_end]) T(value);
455 if (m_end == m_buffer.capacity() - 1)
456 m_end = 0;
457 else
458 ++m_end;
459 checkValidity();
460 }
461
14957cd0
A
462 template<typename T, size_t inlineCapacity> template<typename U>
463 inline void Deque<T, inlineCapacity>::prepend(const U& value)
b37bf2e1
A
464 {
465 checkValidity();
466 expandCapacityIfNeeded();
467 if (!m_start)
468 m_start = m_buffer.capacity() - 1;
469 else
470 --m_start;
471 new (&m_buffer.buffer()[m_start]) T(value);
472 checkValidity();
473 }
474
14957cd0
A
475 template<typename T, size_t inlineCapacity>
476 inline void Deque<T, inlineCapacity>::removeFirst()
b37bf2e1
A
477 {
478 checkValidity();
479 invalidateIterators();
480 ASSERT(!isEmpty());
481 TypeOperations::destruct(&m_buffer.buffer()[m_start], &m_buffer.buffer()[m_start + 1]);
482 if (m_start == m_buffer.capacity() - 1)
483 m_start = 0;
484 else
485 ++m_start;
486 checkValidity();
487 }
488
14957cd0
A
489 template<typename T, size_t inlineCapacity>
490 inline void Deque<T, inlineCapacity>::remove(iterator& it)
ba379fdc
A
491 {
492 it.checkValidity();
493 remove(it.m_index);
494 }
495
14957cd0
A
496 template<typename T, size_t inlineCapacity>
497 inline void Deque<T, inlineCapacity>::remove(const_iterator& it)
ba379fdc
A
498 {
499 it.checkValidity();
500 remove(it.m_index);
501 }
502
14957cd0
A
503 template<typename T, size_t inlineCapacity>
504 inline void Deque<T, inlineCapacity>::remove(size_t position)
ba379fdc
A
505 {
506 if (position == m_end)
507 return;
508
509 checkValidity();
510 invalidateIterators();
511
512 T* buffer = m_buffer.buffer();
513 TypeOperations::destruct(&buffer[position], &buffer[position + 1]);
514
515 // Find which segment of the circular buffer contained the remove element, and only move elements in that part.
516 if (position >= m_start) {
517 TypeOperations::moveOverlapping(buffer + m_start, buffer + position, buffer + m_start + 1);
518 m_start = (m_start + 1) % m_buffer.capacity();
519 } else {
520 TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_end, buffer + position);
521 m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity();
522 }
523 checkValidity();
524 }
525
b37bf2e1 526#ifdef NDEBUG
14957cd0
A
527 template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity() const { }
528 template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::checkValidity(const DequeIteratorBase<T, inlineCapacity>&) const { }
529 template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList() { }
530 template<typename T, size_t inlineCapacity> inline void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList() { }
b37bf2e1 531#else
14957cd0
A
532 template<typename T, size_t inlineCapacity>
533 void DequeIteratorBase<T, inlineCapacity>::checkValidity() const
b37bf2e1
A
534 {
535 ASSERT(m_deque);
536 m_deque->checkIndexValidity(m_index);
537 }
538
14957cd0
A
539 template<typename T, size_t inlineCapacity>
540 void DequeIteratorBase<T, inlineCapacity>::checkValidity(const Base& other) const
b37bf2e1
A
541 {
542 checkValidity();
543 other.checkValidity();
544 ASSERT(m_deque == other.m_deque);
545 }
546
14957cd0
A
547 template<typename T, size_t inlineCapacity>
548 void DequeIteratorBase<T, inlineCapacity>::addToIteratorsList()
b37bf2e1
A
549 {
550 if (!m_deque)
551 m_next = 0;
552 else {
553 m_next = m_deque->m_iterators;
554 m_deque->m_iterators = this;
555 if (m_next)
556 m_next->m_previous = this;
557 }
558 m_previous = 0;
559 }
ba379fdc 560
14957cd0
A
561 template<typename T, size_t inlineCapacity>
562 void DequeIteratorBase<T, inlineCapacity>::removeFromIteratorsList()
ba379fdc
A
563 {
564 if (!m_deque) {
565 ASSERT(!m_next);
566 ASSERT(!m_previous);
567 } else {
568 if (m_next) {
569 ASSERT(m_next->m_previous == this);
570 m_next->m_previous = m_previous;
571 }
572 if (m_previous) {
573 ASSERT(m_deque->m_iterators != this);
574 ASSERT(m_previous->m_next == this);
575 m_previous->m_next = m_next;
576 } else {
577 ASSERT(m_deque->m_iterators == this);
578 m_deque->m_iterators = m_next;
579 }
580 }
581 m_next = 0;
582 m_previous = 0;
583 }
b37bf2e1
A
584#endif
585
14957cd0
A
586 template<typename T, size_t inlineCapacity>
587 inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase()
b37bf2e1
A
588 : m_deque(0)
589 {
590 }
591
14957cd0
A
592 template<typename T, size_t inlineCapacity>
593 inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const Deque<T, inlineCapacity>* deque, size_t index)
594 : m_deque(const_cast<Deque<T, inlineCapacity>*>(deque))
b37bf2e1
A
595 , m_index(index)
596 {
597 addToIteratorsList();
598 checkValidity();
599 }
600
14957cd0
A
601 template<typename T, size_t inlineCapacity>
602 inline DequeIteratorBase<T, inlineCapacity>::DequeIteratorBase(const Base& other)
b37bf2e1
A
603 : m_deque(other.m_deque)
604 , m_index(other.m_index)
605 {
606 addToIteratorsList();
607 checkValidity();
608 }
609
14957cd0
A
610 template<typename T, size_t inlineCapacity>
611 inline DequeIteratorBase<T, inlineCapacity>& DequeIteratorBase<T, inlineCapacity>::operator=(const Base& other)
ba379fdc
A
612 {
613 checkValidity();
614 other.checkValidity();
615 removeFromIteratorsList();
616
617 m_deque = other.m_deque;
618 m_index = other.m_index;
619 addToIteratorsList();
620 checkValidity();
621 return *this;
622 }
623
14957cd0
A
624 template<typename T, size_t inlineCapacity>
625 inline DequeIteratorBase<T, inlineCapacity>::~DequeIteratorBase()
b37bf2e1
A
626 {
627#ifndef NDEBUG
ba379fdc 628 removeFromIteratorsList();
b37bf2e1 629 m_deque = 0;
b37bf2e1
A
630#endif
631 }
632
14957cd0
A
633 template<typename T, size_t inlineCapacity>
634 inline bool DequeIteratorBase<T, inlineCapacity>::isEqual(const Base& other) const
b37bf2e1
A
635 {
636 checkValidity(other);
637 return m_index == other.m_index;
638 }
639
14957cd0
A
640 template<typename T, size_t inlineCapacity>
641 inline void DequeIteratorBase<T, inlineCapacity>::increment()
b37bf2e1
A
642 {
643 checkValidity();
644 ASSERT(m_index != m_deque->m_end);
645 ASSERT(m_deque->m_buffer.capacity());
646 if (m_index == m_deque->m_buffer.capacity() - 1)
647 m_index = 0;
648 else
649 ++m_index;
650 checkValidity();
651 }
652
14957cd0
A
653 template<typename T, size_t inlineCapacity>
654 inline void DequeIteratorBase<T, inlineCapacity>::decrement()
b37bf2e1
A
655 {
656 checkValidity();
657 ASSERT(m_index != m_deque->m_start);
658 ASSERT(m_deque->m_buffer.capacity());
659 if (!m_index)
660 m_index = m_deque->m_buffer.capacity() - 1;
661 else
662 --m_index;
663 checkValidity();
664 }
665
14957cd0
A
666 template<typename T, size_t inlineCapacity>
667 inline T* DequeIteratorBase<T, inlineCapacity>::after() const
b37bf2e1
A
668 {
669 checkValidity();
670 ASSERT(m_index != m_deque->m_end);
671 return &m_deque->m_buffer.buffer()[m_index];
672 }
673
14957cd0
A
674 template<typename T, size_t inlineCapacity>
675 inline T* DequeIteratorBase<T, inlineCapacity>::before() const
b37bf2e1
A
676 {
677 checkValidity();
678 ASSERT(m_index != m_deque->m_start);
679 if (!m_index)
680 return &m_deque->m_buffer.buffer()[m_deque->m_buffer.capacity() - 1];
681 return &m_deque->m_buffer.buffer()[m_index - 1];
682 }
683
684} // namespace WTF
685
686using WTF::Deque;
687
688#endif // WTF_Deque_h