]> git.saurik.com Git - apple/javascriptcore.git/blob - wtf/Deque.h
JavaScriptCore-721.26.tar.gz
[apple/javascriptcore.git] / wtf / Deque.h
1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Google Inc. All rights reserved.
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
36 #include "Vector.h"
37
38 namespace WTF {
39
40 template<typename T> class DequeIteratorBase;
41 template<typename T> class DequeIterator;
42 template<typename T> class DequeConstIterator;
43 template<typename T> class DequeReverseIterator;
44 template<typename T> class DequeConstReverseIterator;
45
46 template<typename T>
47 class Deque : public FastAllocBase {
48 public:
49 typedef DequeIterator<T> iterator;
50 typedef DequeConstIterator<T> const_iterator;
51 typedef DequeReverseIterator<T> reverse_iterator;
52 typedef DequeConstReverseIterator<T> const_reverse_iterator;
53
54 Deque();
55 Deque(const Deque<T>&);
56 Deque& operator=(const Deque<T>&);
57 ~Deque();
58
59 void swap(Deque<T>&);
60
61 size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + m_buffer.capacity() - m_start; }
62 bool isEmpty() const { return m_start == m_end; }
63
64 iterator begin() { return iterator(this, m_start); }
65 iterator end() { return iterator(this, m_end); }
66 const_iterator begin() const { return const_iterator(this, m_start); }
67 const_iterator end() const { return const_iterator(this, m_end); }
68 reverse_iterator rbegin() { return reverse_iterator(this, m_end); }
69 reverse_iterator rend() { return reverse_iterator(this, m_start); }
70 const_reverse_iterator rbegin() const { return const_reverse_iterator(this, m_end); }
71 const_reverse_iterator rend() const { return const_reverse_iterator(this, m_start); }
72
73 T& first() { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
74 const T& first() const { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; }
75
76 template<typename U> void append(const U&);
77 template<typename U> void prepend(const U&);
78 void removeFirst();
79 void remove(iterator&);
80 void remove(const_iterator&);
81
82 void clear();
83
84 template<typename Predicate>
85 iterator findIf(Predicate&);
86
87 private:
88 friend class DequeIteratorBase<T>;
89
90 typedef VectorBuffer<T, 0> Buffer;
91 typedef VectorTypeOperations<T> TypeOperations;
92 typedef DequeIteratorBase<T> IteratorBase;
93
94 void remove(size_t position);
95 void invalidateIterators();
96 void destroyAll();
97 void checkValidity() const;
98 void checkIndexValidity(size_t) const;
99 void expandCapacityIfNeeded();
100 void expandCapacity();
101
102 size_t m_start;
103 size_t m_end;
104 Buffer m_buffer;
105 #ifndef NDEBUG
106 mutable IteratorBase* m_iterators;
107 #endif
108 };
109
110 template<typename T>
111 class DequeIteratorBase {
112 private:
113 typedef DequeIteratorBase<T> Base;
114
115 protected:
116 DequeIteratorBase();
117 DequeIteratorBase(const Deque<T>*, size_t);
118 DequeIteratorBase(const Base&);
119 Base& operator=(const Base&);
120 ~DequeIteratorBase();
121
122 void assign(const Base& other) { *this = other; }
123
124 void increment();
125 void decrement();
126
127 T* before() const;
128 T* after() const;
129
130 bool isEqual(const Base&) const;
131
132 private:
133 void addToIteratorsList();
134 void removeFromIteratorsList();
135 void checkValidity() const;
136 void checkValidity(const Base&) const;
137
138 Deque<T>* m_deque;
139 size_t m_index;
140
141 friend class Deque<T>;
142
143 #ifndef NDEBUG
144 mutable DequeIteratorBase* m_next;
145 mutable DequeIteratorBase* m_previous;
146 #endif
147 };
148
149 template<typename T>
150 class DequeIterator : public DequeIteratorBase<T> {
151 private:
152 typedef DequeIteratorBase<T> Base;
153 typedef DequeIterator<T> Iterator;
154
155 public:
156 DequeIterator(Deque<T>* deque, size_t index) : Base(deque, index) { }
157
158 DequeIterator(const Iterator& other) : Base(other) { }
159 DequeIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
160
161 T& operator*() const { return *Base::after(); }
162 T* operator->() const { return Base::after(); }
163
164 bool operator==(const Iterator& other) const { return Base::isEqual(other); }
165 bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
166
167 Iterator& operator++() { Base::increment(); return *this; }
168 // postfix ++ intentionally omitted
169 Iterator& operator--() { Base::decrement(); return *this; }
170 // postfix -- intentionally omitted
171 };
172
173 template<typename T>
174 class DequeConstIterator : public DequeIteratorBase<T> {
175 private:
176 typedef DequeIteratorBase<T> Base;
177 typedef DequeConstIterator<T> Iterator;
178 typedef DequeIterator<T> NonConstIterator;
179
180 public:
181 DequeConstIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { }
182
183 DequeConstIterator(const Iterator& other) : Base(other) { }
184 DequeConstIterator(const NonConstIterator& other) : Base(other) { }
185 DequeConstIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
186 DequeConstIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; }
187
188 const T& operator*() const { return *Base::after(); }
189 const T* operator->() const { return Base::after(); }
190
191 bool operator==(const Iterator& other) const { return Base::isEqual(other); }
192 bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
193
194 Iterator& operator++() { Base::increment(); return *this; }
195 // postfix ++ intentionally omitted
196 Iterator& operator--() { Base::decrement(); return *this; }
197 // postfix -- intentionally omitted
198 };
199
200 template<typename T>
201 class DequeReverseIterator : public DequeIteratorBase<T> {
202 private:
203 typedef DequeIteratorBase<T> Base;
204 typedef DequeReverseIterator<T> Iterator;
205
206 public:
207 DequeReverseIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { }
208
209 DequeReverseIterator(const Iterator& other) : Base(other) { }
210 DequeReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
211
212 T& operator*() const { return *Base::before(); }
213 T* operator->() const { return Base::before(); }
214
215 bool operator==(const Iterator& other) const { return Base::isEqual(other); }
216 bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
217
218 Iterator& operator++() { Base::decrement(); return *this; }
219 // postfix ++ intentionally omitted
220 Iterator& operator--() { Base::increment(); return *this; }
221 // postfix -- intentionally omitted
222 };
223
224 template<typename T>
225 class DequeConstReverseIterator : public DequeIteratorBase<T> {
226 private:
227 typedef DequeIteratorBase<T> Base;
228 typedef DequeConstReverseIterator<T> Iterator;
229 typedef DequeReverseIterator<T> NonConstIterator;
230
231 public:
232 DequeConstReverseIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { }
233
234 DequeConstReverseIterator(const Iterator& other) : Base(other) { }
235 DequeConstReverseIterator(const NonConstIterator& other) : Base(other) { }
236 DequeConstReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; }
237 DequeConstReverseIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; }
238
239 const T& operator*() const { return *Base::before(); }
240 const T* operator->() const { return Base::before(); }
241
242 bool operator==(const Iterator& other) const { return Base::isEqual(other); }
243 bool operator!=(const Iterator& other) const { return !Base::isEqual(other); }
244
245 Iterator& operator++() { Base::decrement(); return *this; }
246 // postfix ++ intentionally omitted
247 Iterator& operator--() { Base::increment(); return *this; }
248 // postfix -- intentionally omitted
249 };
250
251 #ifdef NDEBUG
252 template<typename T> inline void Deque<T>::checkValidity() const { }
253 template<typename T> inline void Deque<T>::checkIndexValidity(size_t) const { }
254 template<typename T> inline void Deque<T>::invalidateIterators() { }
255 #else
256 template<typename T>
257 void Deque<T>::checkValidity() const
258 {
259 if (!m_buffer.capacity()) {
260 ASSERT(!m_start);
261 ASSERT(!m_end);
262 } else {
263 ASSERT(m_start < m_buffer.capacity());
264 ASSERT(m_end < m_buffer.capacity());
265 }
266 }
267
268 template<typename T>
269 void Deque<T>::checkIndexValidity(size_t index) const
270 {
271 ASSERT(index <= m_buffer.capacity());
272 if (m_start <= m_end) {
273 ASSERT(index >= m_start);
274 ASSERT(index <= m_end);
275 } else {
276 ASSERT(index >= m_start || index <= m_end);
277 }
278 }
279
280 template<typename T>
281 void Deque<T>::invalidateIterators()
282 {
283 IteratorBase* next;
284 for (IteratorBase* p = m_iterators; p; p = next) {
285 next = p->m_next;
286 p->m_deque = 0;
287 p->m_next = 0;
288 p->m_previous = 0;
289 }
290 m_iterators = 0;
291 }
292 #endif
293
294 template<typename T>
295 inline Deque<T>::Deque()
296 : m_start(0)
297 , m_end(0)
298 #ifndef NDEBUG
299 , m_iterators(0)
300 #endif
301 {
302 checkValidity();
303 }
304
305 template<typename T>
306 inline Deque<T>::Deque(const Deque<T>& other)
307 : m_start(other.m_start)
308 , m_end(other.m_end)
309 , m_buffer(other.m_buffer.capacity())
310 #ifndef NDEBUG
311 , m_iterators(0)
312 #endif
313 {
314 const T* otherBuffer = other.m_buffer.buffer();
315 if (m_start <= m_end)
316 TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_end, m_buffer.buffer() + m_start);
317 else {
318 TypeOperations::uninitializedCopy(otherBuffer, otherBuffer + m_end, m_buffer.buffer());
319 TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_buffer.capacity(), m_buffer.buffer() + m_start);
320 }
321 }
322
323 template<typename T>
324 void deleteAllValues(const Deque<T>& collection)
325 {
326 typedef typename Deque<T>::const_iterator iterator;
327 iterator end = collection.end();
328 for (iterator it = collection.begin(); it != end; ++it)
329 delete *it;
330 }
331
332 template<typename T>
333 inline Deque<T>& Deque<T>::operator=(const Deque<T>& other)
334 {
335 Deque<T> copy(other);
336 swap(copy);
337 return *this;
338 }
339
340 template<typename T>
341 inline void Deque<T>::destroyAll()
342 {
343 if (m_start <= m_end)
344 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_end);
345 else {
346 TypeOperations::destruct(m_buffer.buffer(), m_buffer.buffer() + m_end);
347 TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_buffer.capacity());
348 }
349 }
350
351 template<typename T>
352 inline Deque<T>::~Deque()
353 {
354 checkValidity();
355 invalidateIterators();
356 destroyAll();
357 }
358
359 template<typename T>
360 inline void Deque<T>::swap(Deque<T>& other)
361 {
362 checkValidity();
363 other.checkValidity();
364 invalidateIterators();
365 std::swap(m_start, other.m_start);
366 std::swap(m_end, other.m_end);
367 m_buffer.swap(other.m_buffer);
368 checkValidity();
369 other.checkValidity();
370 }
371
372 template<typename T>
373 inline void Deque<T>::clear()
374 {
375 checkValidity();
376 invalidateIterators();
377 destroyAll();
378 m_start = 0;
379 m_end = 0;
380 checkValidity();
381 }
382
383 template<typename T>
384 template<typename Predicate>
385 inline DequeIterator<T> Deque<T>::findIf(Predicate& predicate)
386 {
387 iterator end_iterator = end();
388 for (iterator it = begin(); it != end_iterator; ++it) {
389 if (predicate(*it))
390 return it;
391 }
392 return end_iterator;
393 }
394
395 template<typename T>
396 inline void Deque<T>::expandCapacityIfNeeded()
397 {
398 if (m_start) {
399 if (m_end + 1 != m_start)
400 return;
401 } else if (m_end) {
402 if (m_end != m_buffer.capacity() - 1)
403 return;
404 } else if (m_buffer.capacity())
405 return;
406
407 expandCapacity();
408 }
409
410 template<typename T>
411 void Deque<T>::expandCapacity()
412 {
413 checkValidity();
414 size_t oldCapacity = m_buffer.capacity();
415 size_t newCapacity = max(static_cast<size_t>(16), oldCapacity + oldCapacity / 4 + 1);
416 T* oldBuffer = m_buffer.buffer();
417 m_buffer.allocateBuffer(newCapacity);
418 if (m_start <= m_end)
419 TypeOperations::move(oldBuffer + m_start, oldBuffer + m_end, m_buffer.buffer() + m_start);
420 else {
421 TypeOperations::move(oldBuffer, oldBuffer + m_end, m_buffer.buffer());
422 size_t newStart = newCapacity - (oldCapacity - m_start);
423 TypeOperations::move(oldBuffer + m_start, oldBuffer + oldCapacity, m_buffer.buffer() + newStart);
424 m_start = newStart;
425 }
426 m_buffer.deallocateBuffer(oldBuffer);
427 checkValidity();
428 }
429
430 template<typename T> template<typename U>
431 inline void Deque<T>::append(const U& value)
432 {
433 checkValidity();
434 expandCapacityIfNeeded();
435 new (&m_buffer.buffer()[m_end]) T(value);
436 if (m_end == m_buffer.capacity() - 1)
437 m_end = 0;
438 else
439 ++m_end;
440 checkValidity();
441 }
442
443 template<typename T> template<typename U>
444 inline void Deque<T>::prepend(const U& value)
445 {
446 checkValidity();
447 expandCapacityIfNeeded();
448 if (!m_start)
449 m_start = m_buffer.capacity() - 1;
450 else
451 --m_start;
452 new (&m_buffer.buffer()[m_start]) T(value);
453 checkValidity();
454 }
455
456 template<typename T>
457 inline void Deque<T>::removeFirst()
458 {
459 checkValidity();
460 invalidateIterators();
461 ASSERT(!isEmpty());
462 TypeOperations::destruct(&m_buffer.buffer()[m_start], &m_buffer.buffer()[m_start + 1]);
463 if (m_start == m_buffer.capacity() - 1)
464 m_start = 0;
465 else
466 ++m_start;
467 checkValidity();
468 }
469
470 template<typename T>
471 inline void Deque<T>::remove(iterator& it)
472 {
473 it.checkValidity();
474 remove(it.m_index);
475 }
476
477 template<typename T>
478 inline void Deque<T>::remove(const_iterator& it)
479 {
480 it.checkValidity();
481 remove(it.m_index);
482 }
483
484 template<typename T>
485 inline void Deque<T>::remove(size_t position)
486 {
487 if (position == m_end)
488 return;
489
490 checkValidity();
491 invalidateIterators();
492
493 T* buffer = m_buffer.buffer();
494 TypeOperations::destruct(&buffer[position], &buffer[position + 1]);
495
496 // Find which segment of the circular buffer contained the remove element, and only move elements in that part.
497 if (position >= m_start) {
498 TypeOperations::moveOverlapping(buffer + m_start, buffer + position, buffer + m_start + 1);
499 m_start = (m_start + 1) % m_buffer.capacity();
500 } else {
501 TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_end, buffer + position);
502 m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity();
503 }
504 checkValidity();
505 }
506
507 #ifdef NDEBUG
508 template<typename T> inline void DequeIteratorBase<T>::checkValidity() const { }
509 template<typename T> inline void DequeIteratorBase<T>::checkValidity(const DequeIteratorBase<T>&) const { }
510 template<typename T> inline void DequeIteratorBase<T>::addToIteratorsList() { }
511 template<typename T> inline void DequeIteratorBase<T>::removeFromIteratorsList() { }
512 #else
513 template<typename T>
514 void DequeIteratorBase<T>::checkValidity() const
515 {
516 ASSERT(m_deque);
517 m_deque->checkIndexValidity(m_index);
518 }
519
520 template<typename T>
521 void DequeIteratorBase<T>::checkValidity(const Base& other) const
522 {
523 checkValidity();
524 other.checkValidity();
525 ASSERT(m_deque == other.m_deque);
526 }
527
528 template<typename T>
529 void DequeIteratorBase<T>::addToIteratorsList()
530 {
531 if (!m_deque)
532 m_next = 0;
533 else {
534 m_next = m_deque->m_iterators;
535 m_deque->m_iterators = this;
536 if (m_next)
537 m_next->m_previous = this;
538 }
539 m_previous = 0;
540 }
541
542 template<typename T>
543 void DequeIteratorBase<T>::removeFromIteratorsList()
544 {
545 if (!m_deque) {
546 ASSERT(!m_next);
547 ASSERT(!m_previous);
548 } else {
549 if (m_next) {
550 ASSERT(m_next->m_previous == this);
551 m_next->m_previous = m_previous;
552 }
553 if (m_previous) {
554 ASSERT(m_deque->m_iterators != this);
555 ASSERT(m_previous->m_next == this);
556 m_previous->m_next = m_next;
557 } else {
558 ASSERT(m_deque->m_iterators == this);
559 m_deque->m_iterators = m_next;
560 }
561 }
562 m_next = 0;
563 m_previous = 0;
564 }
565 #endif
566
567 template<typename T>
568 inline DequeIteratorBase<T>::DequeIteratorBase()
569 : m_deque(0)
570 {
571 }
572
573 template<typename T>
574 inline DequeIteratorBase<T>::DequeIteratorBase(const Deque<T>* deque, size_t index)
575 : m_deque(const_cast<Deque<T>*>(deque))
576 , m_index(index)
577 {
578 addToIteratorsList();
579 checkValidity();
580 }
581
582 template<typename T>
583 inline DequeIteratorBase<T>::DequeIteratorBase(const Base& other)
584 : m_deque(other.m_deque)
585 , m_index(other.m_index)
586 {
587 addToIteratorsList();
588 checkValidity();
589 }
590
591 template<typename T>
592 inline DequeIteratorBase<T>& DequeIteratorBase<T>::operator=(const Base& other)
593 {
594 checkValidity();
595 other.checkValidity();
596 removeFromIteratorsList();
597
598 m_deque = other.m_deque;
599 m_index = other.m_index;
600 addToIteratorsList();
601 checkValidity();
602 return *this;
603 }
604
605 template<typename T>
606 inline DequeIteratorBase<T>::~DequeIteratorBase()
607 {
608 #ifndef NDEBUG
609 removeFromIteratorsList();
610 m_deque = 0;
611 #endif
612 }
613
614 template<typename T>
615 inline bool DequeIteratorBase<T>::isEqual(const Base& other) const
616 {
617 checkValidity(other);
618 return m_index == other.m_index;
619 }
620
621 template<typename T>
622 inline void DequeIteratorBase<T>::increment()
623 {
624 checkValidity();
625 ASSERT(m_index != m_deque->m_end);
626 ASSERT(m_deque->m_buffer.capacity());
627 if (m_index == m_deque->m_buffer.capacity() - 1)
628 m_index = 0;
629 else
630 ++m_index;
631 checkValidity();
632 }
633
634 template<typename T>
635 inline void DequeIteratorBase<T>::decrement()
636 {
637 checkValidity();
638 ASSERT(m_index != m_deque->m_start);
639 ASSERT(m_deque->m_buffer.capacity());
640 if (!m_index)
641 m_index = m_deque->m_buffer.capacity() - 1;
642 else
643 --m_index;
644 checkValidity();
645 }
646
647 template<typename T>
648 inline T* DequeIteratorBase<T>::after() const
649 {
650 checkValidity();
651 ASSERT(m_index != m_deque->m_end);
652 return &m_deque->m_buffer.buffer()[m_index];
653 }
654
655 template<typename T>
656 inline T* DequeIteratorBase<T>::before() const
657 {
658 checkValidity();
659 ASSERT(m_index != m_deque->m_start);
660 if (!m_index)
661 return &m_deque->m_buffer.buffer()[m_deque->m_buffer.capacity() - 1];
662 return &m_deque->m_buffer.buffer()[m_index - 1];
663 }
664
665 } // namespace WTF
666
667 using WTF::Deque;
668
669 #endif // WTF_Deque_h