2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Google Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
33 // FIXME: Could move what Vector and Deque share into a separate file.
34 // Deque doesn't actually use Vector.
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
;
47 class Deque
: public FastAllocBase
{
49 typedef DequeIterator
<T
> iterator
;
50 typedef DequeConstIterator
<T
> const_iterator
;
51 typedef DequeReverseIterator
<T
> reverse_iterator
;
52 typedef DequeConstReverseIterator
<T
> const_reverse_iterator
;
55 Deque(const Deque
<T
>&);
56 Deque
& operator=(const Deque
<T
>&);
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
; }
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
); }
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
]; }
76 template<typename U
> void append(const U
&);
77 template<typename U
> void prepend(const U
&);
79 void remove(iterator
&);
80 void remove(const_iterator
&);
84 template<typename Predicate
>
85 iterator
findIf(Predicate
&);
88 friend class DequeIteratorBase
<T
>;
90 typedef VectorBuffer
<T
, 0> Buffer
;
91 typedef VectorTypeOperations
<T
> TypeOperations
;
92 typedef DequeIteratorBase
<T
> IteratorBase
;
94 void remove(size_t position
);
95 void invalidateIterators();
97 void checkValidity() const;
98 void checkIndexValidity(size_t) const;
99 void expandCapacityIfNeeded();
100 void expandCapacity();
106 mutable IteratorBase
* m_iterators
;
111 class DequeIteratorBase
{
113 typedef DequeIteratorBase
<T
> Base
;
117 DequeIteratorBase(const Deque
<T
>*, size_t);
118 DequeIteratorBase(const Base
&);
119 Base
& operator=(const Base
&);
120 ~DequeIteratorBase();
122 void assign(const Base
& other
) { *this = other
; }
130 bool isEqual(const Base
&) const;
133 void addToIteratorsList();
134 void removeFromIteratorsList();
135 void checkValidity() const;
136 void checkValidity(const Base
&) const;
141 friend class Deque
<T
>;
144 mutable DequeIteratorBase
* m_next
;
145 mutable DequeIteratorBase
* m_previous
;
150 class DequeIterator
: public DequeIteratorBase
<T
> {
152 typedef DequeIteratorBase
<T
> Base
;
153 typedef DequeIterator
<T
> Iterator
;
156 DequeIterator(Deque
<T
>* deque
, size_t index
) : Base(deque
, index
) { }
158 DequeIterator(const Iterator
& other
) : Base(other
) { }
159 DequeIterator
& operator=(const Iterator
& other
) { Base::assign(other
); return *this; }
161 T
& operator*() const { return *Base::after(); }
162 T
* operator->() const { return Base::after(); }
164 bool operator==(const Iterator
& other
) const { return Base::isEqual(other
); }
165 bool operator!=(const Iterator
& other
) const { return !Base::isEqual(other
); }
167 Iterator
& operator++() { Base::increment(); return *this; }
168 // postfix ++ intentionally omitted
169 Iterator
& operator--() { Base::decrement(); return *this; }
170 // postfix -- intentionally omitted
174 class DequeConstIterator
: public DequeIteratorBase
<T
> {
176 typedef DequeIteratorBase
<T
> Base
;
177 typedef DequeConstIterator
<T
> Iterator
;
178 typedef DequeIterator
<T
> NonConstIterator
;
181 DequeConstIterator(const Deque
<T
>* deque
, size_t index
) : Base(deque
, index
) { }
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; }
188 const T
& operator*() const { return *Base::after(); }
189 const T
* operator->() const { return Base::after(); }
191 bool operator==(const Iterator
& other
) const { return Base::isEqual(other
); }
192 bool operator!=(const Iterator
& other
) const { return !Base::isEqual(other
); }
194 Iterator
& operator++() { Base::increment(); return *this; }
195 // postfix ++ intentionally omitted
196 Iterator
& operator--() { Base::decrement(); return *this; }
197 // postfix -- intentionally omitted
201 class DequeReverseIterator
: public DequeIteratorBase
<T
> {
203 typedef DequeIteratorBase
<T
> Base
;
204 typedef DequeReverseIterator
<T
> Iterator
;
207 DequeReverseIterator(const Deque
<T
>* deque
, size_t index
) : Base(deque
, index
) { }
209 DequeReverseIterator(const Iterator
& other
) : Base(other
) { }
210 DequeReverseIterator
& operator=(const Iterator
& other
) { Base::assign(other
); return *this; }
212 T
& operator*() const { return *Base::before(); }
213 T
* operator->() const { return Base::before(); }
215 bool operator==(const Iterator
& other
) const { return Base::isEqual(other
); }
216 bool operator!=(const Iterator
& other
) const { return !Base::isEqual(other
); }
218 Iterator
& operator++() { Base::decrement(); return *this; }
219 // postfix ++ intentionally omitted
220 Iterator
& operator--() { Base::increment(); return *this; }
221 // postfix -- intentionally omitted
225 class DequeConstReverseIterator
: public DequeIteratorBase
<T
> {
227 typedef DequeIteratorBase
<T
> Base
;
228 typedef DequeConstReverseIterator
<T
> Iterator
;
229 typedef DequeReverseIterator
<T
> NonConstIterator
;
232 DequeConstReverseIterator(const Deque
<T
>* deque
, size_t index
) : Base(deque
, index
) { }
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; }
239 const T
& operator*() const { return *Base::before(); }
240 const T
* operator->() const { return Base::before(); }
242 bool operator==(const Iterator
& other
) const { return Base::isEqual(other
); }
243 bool operator!=(const Iterator
& other
) const { return !Base::isEqual(other
); }
245 Iterator
& operator++() { Base::decrement(); return *this; }
246 // postfix ++ intentionally omitted
247 Iterator
& operator--() { Base::increment(); return *this; }
248 // postfix -- intentionally omitted
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() { }
257 void Deque
<T
>::checkValidity() const
259 if (!m_buffer
.capacity()) {
263 ASSERT(m_start
< m_buffer
.capacity());
264 ASSERT(m_end
< m_buffer
.capacity());
269 void Deque
<T
>::checkIndexValidity(size_t index
) const
271 ASSERT(index
<= m_buffer
.capacity());
272 if (m_start
<= m_end
) {
273 ASSERT(index
>= m_start
);
274 ASSERT(index
<= m_end
);
276 ASSERT(index
>= m_start
|| index
<= m_end
);
281 void Deque
<T
>::invalidateIterators()
284 for (IteratorBase
* p
= m_iterators
; p
; p
= next
) {
295 inline Deque
<T
>::Deque()
306 inline Deque
<T
>::Deque(const Deque
<T
>& other
)
307 : m_start(other
.m_start
)
309 , m_buffer(other
.m_buffer
.capacity())
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
);
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
);
324 void deleteAllValues(const Deque
<T
>& collection
)
326 typedef typename Deque
<T
>::const_iterator iterator
;
327 iterator end
= collection
.end();
328 for (iterator it
= collection
.begin(); it
!= end
; ++it
)
333 inline Deque
<T
>& Deque
<T
>::operator=(const Deque
<T
>& other
)
335 Deque
<T
> copy(other
);
341 inline void Deque
<T
>::destroyAll()
343 if (m_start
<= m_end
)
344 TypeOperations::destruct(m_buffer
.buffer() + m_start
, m_buffer
.buffer() + m_end
);
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());
352 inline Deque
<T
>::~Deque()
355 invalidateIterators();
360 inline void Deque
<T
>::swap(Deque
<T
>& other
)
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
);
369 other
.checkValidity();
373 inline void Deque
<T
>::clear()
376 invalidateIterators();
384 template<typename Predicate
>
385 inline DequeIterator
<T
> Deque
<T
>::findIf(Predicate
& predicate
)
387 iterator end_iterator
= end();
388 for (iterator it
= begin(); it
!= end_iterator
; ++it
) {
396 inline void Deque
<T
>::expandCapacityIfNeeded()
399 if (m_end
+ 1 != m_start
)
402 if (m_end
!= m_buffer
.capacity() - 1)
404 } else if (m_buffer
.capacity())
411 void Deque
<T
>::expandCapacity()
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
);
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
);
426 m_buffer
.deallocateBuffer(oldBuffer
);
430 template<typename T
> template<typename U
>
431 inline void Deque
<T
>::append(const U
& value
)
434 expandCapacityIfNeeded();
435 new (&m_buffer
.buffer()[m_end
]) T(value
);
436 if (m_end
== m_buffer
.capacity() - 1)
443 template<typename T
> template<typename U
>
444 inline void Deque
<T
>::prepend(const U
& value
)
447 expandCapacityIfNeeded();
449 m_start
= m_buffer
.capacity() - 1;
452 new (&m_buffer
.buffer()[m_start
]) T(value
);
457 inline void Deque
<T
>::removeFirst()
460 invalidateIterators();
462 TypeOperations::destruct(&m_buffer
.buffer()[m_start
], &m_buffer
.buffer()[m_start
+ 1]);
463 if (m_start
== m_buffer
.capacity() - 1)
471 inline void Deque
<T
>::remove(iterator
& it
)
478 inline void Deque
<T
>::remove(const_iterator
& it
)
485 inline void Deque
<T
>::remove(size_t position
)
487 if (position
== m_end
)
491 invalidateIterators();
493 T
* buffer
= m_buffer
.buffer();
494 TypeOperations::destruct(&buffer
[position
], &buffer
[position
+ 1]);
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();
501 TypeOperations::moveOverlapping(buffer
+ position
+ 1, buffer
+ m_end
, buffer
+ position
);
502 m_end
= (m_end
- 1 + m_buffer
.capacity()) % m_buffer
.capacity();
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() { }
514 void DequeIteratorBase
<T
>::checkValidity() const
517 m_deque
->checkIndexValidity(m_index
);
521 void DequeIteratorBase
<T
>::checkValidity(const Base
& other
) const
524 other
.checkValidity();
525 ASSERT(m_deque
== other
.m_deque
);
529 void DequeIteratorBase
<T
>::addToIteratorsList()
534 m_next
= m_deque
->m_iterators
;
535 m_deque
->m_iterators
= this;
537 m_next
->m_previous
= this;
543 void DequeIteratorBase
<T
>::removeFromIteratorsList()
550 ASSERT(m_next
->m_previous
== this);
551 m_next
->m_previous
= m_previous
;
554 ASSERT(m_deque
->m_iterators
!= this);
555 ASSERT(m_previous
->m_next
== this);
556 m_previous
->m_next
= m_next
;
558 ASSERT(m_deque
->m_iterators
== this);
559 m_deque
->m_iterators
= m_next
;
568 inline DequeIteratorBase
<T
>::DequeIteratorBase()
574 inline DequeIteratorBase
<T
>::DequeIteratorBase(const Deque
<T
>* deque
, size_t index
)
575 : m_deque(const_cast<Deque
<T
>*>(deque
))
578 addToIteratorsList();
583 inline DequeIteratorBase
<T
>::DequeIteratorBase(const Base
& other
)
584 : m_deque(other
.m_deque
)
585 , m_index(other
.m_index
)
587 addToIteratorsList();
592 inline DequeIteratorBase
<T
>& DequeIteratorBase
<T
>::operator=(const Base
& other
)
595 other
.checkValidity();
596 removeFromIteratorsList();
598 m_deque
= other
.m_deque
;
599 m_index
= other
.m_index
;
600 addToIteratorsList();
606 inline DequeIteratorBase
<T
>::~DequeIteratorBase()
609 removeFromIteratorsList();
615 inline bool DequeIteratorBase
<T
>::isEqual(const Base
& other
) const
617 checkValidity(other
);
618 return m_index
== other
.m_index
;
622 inline void DequeIteratorBase
<T
>::increment()
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)
635 inline void DequeIteratorBase
<T
>::decrement()
638 ASSERT(m_index
!= m_deque
->m_start
);
639 ASSERT(m_deque
->m_buffer
.capacity());
641 m_index
= m_deque
->m_buffer
.capacity() - 1;
648 inline T
* DequeIteratorBase
<T
>::after() const
651 ASSERT(m_index
!= m_deque
->m_end
);
652 return &m_deque
->m_buffer
.buffer()[m_index
];
656 inline T
* DequeIteratorBase
<T
>::before() const
659 ASSERT(m_index
!= m_deque
->m_start
);
661 return &m_deque
->m_buffer
.buffer()[m_deque
->m_buffer
.capacity() - 1];
662 return &m_deque
->m_buffer
.buffer()[m_index
- 1];
669 #endif // WTF_Deque_h