| /* |
| * Copyright (C) 2001 Apple Computer, Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include <KWQValueListImpl.h> |
| |
| #ifndef USING_BORROWED_QVALUELIST |
| |
| #include <stdlib.h> |
| |
| KWQValueListNodeImpl::KWQValueListNodeImpl() : |
| prev(NULL), |
| next(NULL) |
| { |
| } |
| |
| KWQValueListNodeImpl::~KWQValueListNodeImpl() |
| { |
| } |
| |
| KWQValueListIteratorImpl::KWQValueListIteratorImpl() : |
| nodeImpl(NULL) |
| { |
| } |
| |
| KWQValueListIteratorImpl::KWQValueListIteratorImpl(const KWQValueListIteratorImpl &other) : |
| nodeImpl(other.nodeImpl) |
| { |
| } |
| |
| KWQValueListIteratorImpl::~KWQValueListIteratorImpl() |
| { |
| } |
| |
| KWQValueListIteratorImpl &KWQValueListIteratorImpl::operator=(const KWQValueListIteratorImpl &other) |
| { |
| nodeImpl = other.nodeImpl; |
| return *this; |
| } |
| |
| bool KWQValueListIteratorImpl::operator==(const KWQValueListIteratorImpl &other) |
| { |
| return nodeImpl == other.nodeImpl; |
| } |
| |
| bool KWQValueListIteratorImpl::operator!=(const KWQValueListIteratorImpl &other) |
| { |
| return nodeImpl != other.nodeImpl; |
| } |
| |
| KWQValueListNodeImpl *KWQValueListIteratorImpl::node() |
| { |
| return nodeImpl; |
| } |
| |
| const KWQValueListNodeImpl *KWQValueListIteratorImpl::node() const |
| { |
| return nodeImpl; |
| } |
| |
| KWQValueListIteratorImpl& KWQValueListIteratorImpl::operator++() |
| { |
| if (nodeImpl != NULL) { |
| nodeImpl = nodeImpl->next; |
| } |
| return *this; |
| } |
| |
| KWQValueListIteratorImpl KWQValueListIteratorImpl::operator++(int) |
| { |
| KWQValueListIteratorImpl tmp(*this); |
| |
| if (nodeImpl != NULL) { |
| nodeImpl = nodeImpl->next; |
| } |
| |
| return tmp; |
| } |
| |
| KWQValueListIteratorImpl& KWQValueListIteratorImpl::operator--() |
| { |
| if (nodeImpl != NULL) { |
| nodeImpl = nodeImpl->prev; |
| } |
| return *this; |
| } |
| |
| KWQValueListIteratorImpl::KWQValueListIteratorImpl(const KWQValueListNodeImpl *n) : |
| nodeImpl((KWQValueListNodeImpl *)n) |
| { |
| } |
| |
| |
| class KWQValueListImpl::KWQValueListPrivate |
| { |
| public: |
| KWQValueListPrivate(void (*deleteFunc)(KWQValueListNodeImpl *), KWQValueListNodeImpl *(*copyFunc)(KWQValueListNodeImpl *)); |
| KWQValueListPrivate(const KWQValueListPrivate &other); |
| |
| ~KWQValueListPrivate(); |
| |
| KWQValueListNodeImpl *copyList(KWQValueListNodeImpl *l) const; |
| void deleteList(KWQValueListNodeImpl *l); |
| |
| KWQValueListNodeImpl *head; |
| |
| void (*deleteNode)(KWQValueListNodeImpl *); |
| KWQValueListNodeImpl *(*copyNode)(KWQValueListNodeImpl *); |
| uint count; |
| |
| uint refCount; |
| }; |
| |
| |
| KWQValueListImpl::KWQValueListPrivate::KWQValueListPrivate(void (*deleteFunc)(KWQValueListNodeImpl *), |
| KWQValueListNodeImpl *(*copyFunc)(KWQValueListNodeImpl *)) : |
| head(NULL), |
| deleteNode(deleteFunc), |
| copyNode(copyFunc), |
| count(0), |
| refCount(0) |
| { |
| } |
| |
| KWQValueListImpl::KWQValueListPrivate::KWQValueListPrivate(const KWQValueListPrivate &other) : |
| head(other.copyList(other.head)), |
| deleteNode(other.deleteNode), |
| copyNode(other.copyNode), |
| count(other.count), |
| refCount(0) |
| { |
| } |
| |
| KWQValueListImpl::KWQValueListPrivate::~KWQValueListPrivate() |
| { |
| deleteList(head); |
| } |
| |
| KWQValueListNodeImpl *KWQValueListImpl::KWQValueListPrivate::copyList(KWQValueListNodeImpl *l) const |
| { |
| KWQValueListNodeImpl *prev = NULL; |
| KWQValueListNodeImpl *node = l; |
| KWQValueListNodeImpl *head = NULL; |
| |
| while (node != NULL) { |
| KWQValueListNodeImpl *copy = copyNode(node); |
| if (prev == NULL) { |
| head = copy; |
| } else { |
| prev->next = copy; |
| } |
| |
| copy->prev = prev; |
| copy->next = NULL; |
| |
| prev = copy; |
| node = node->next; |
| } |
| |
| return head; |
| } |
| |
| void KWQValueListImpl::KWQValueListPrivate::deleteList(KWQValueListNodeImpl *l) |
| { |
| KWQValueListNodeImpl *p = l; |
| |
| while (p != NULL) { |
| KWQValueListNodeImpl *next = p->next; |
| deleteNode(p); |
| p = next; |
| } |
| } |
| |
| |
| |
| KWQValueListImpl::KWQValueListImpl(void (*deleteFunc)(KWQValueListNodeImpl *), KWQValueListNodeImpl *(*copyFunc)(KWQValueListNodeImpl *)) : |
| d(new KWQValueListImpl::KWQValueListPrivate(deleteFunc, copyFunc)) |
| { |
| } |
| |
| KWQValueListImpl::KWQValueListImpl(const KWQValueListImpl &other) : |
| d(other.d) |
| { |
| } |
| |
| KWQValueListImpl::~KWQValueListImpl() |
| { |
| } |
| |
| void KWQValueListImpl::clear() |
| { |
| d->deleteList(d->head); |
| d->head = NULL; |
| d->count = 0; |
| } |
| |
| uint KWQValueListImpl::count() const |
| { |
| return d->count; |
| } |
| |
| bool KWQValueListImpl::isEmpty() const |
| { |
| return d->count == 0; |
| } |
| |
| void KWQValueListImpl::appendNode(KWQValueListNodeImpl *node) |
| { |
| copyOnWrite(); |
| |
| // FIXME: maintain tail pointer to make this fast |
| |
| if (d->head == NULL) { |
| d->head = node; |
| } else { |
| KWQValueListNodeImpl *p = d->head; |
| |
| while (p->next != NULL) { |
| p = p->next; |
| } |
| |
| p->next = node; |
| node->prev = p; |
| node->next = NULL; |
| } |
| |
| d->count++; |
| } |
| |
| void KWQValueListImpl::prependNode(KWQValueListNodeImpl *node) |
| { |
| copyOnWrite(); |
| |
| node->next = d->head; |
| node->prev = NULL; |
| d->head = node; |
| |
| if (node->next != NULL) { |
| node->next->prev = node; |
| } |
| |
| d->count++; |
| } |
| |
| void KWQValueListImpl::removeEqualNodes(KWQValueListNodeImpl *node, bool (*equalFunc)(const KWQValueListNodeImpl *, const KWQValueListNodeImpl *)) |
| { |
| copyOnWrite(); |
| |
| KWQValueListNodeImpl *p = d->head; |
| |
| while (p != NULL) { |
| KWQValueListNodeImpl *next = p->next; |
| if (equalFunc(node, p)) { |
| if (p->next != NULL) { |
| p->next->prev = p->prev; |
| } |
| |
| if (p->prev != NULL) { |
| p->prev->next = p->next; |
| } else { |
| d->head = p->next; |
| } |
| |
| d->deleteNode(p); |
| |
| d->count--; |
| } |
| p = next; |
| } |
| } |
| |
| uint KWQValueListImpl::containsEqualNodes(KWQValueListNodeImpl *node, bool (*equalFunc)(const KWQValueListNodeImpl *, const KWQValueListNodeImpl *)) const |
| { |
| KWQValueListNodeImpl *p = d->head; |
| unsigned contains = 0; |
| |
| while (p != NULL) { |
| if (equalFunc(node, p)) { |
| ++contains; |
| } |
| p = p->next; |
| } |
| |
| return contains; |
| } |
| |
| KWQValueListIteratorImpl KWQValueListImpl::removeIterator(KWQValueListIteratorImpl &iterator) |
| { |
| copyOnWrite(); |
| |
| if (iterator.nodeImpl == NULL) { |
| return iterator; |
| } |
| |
| KWQValueListNodeImpl *next = iterator.nodeImpl->next; |
| |
| // detach node |
| if (iterator.nodeImpl->next != NULL) { |
| iterator.nodeImpl->next->prev = iterator.nodeImpl->prev; |
| } |
| if (iterator.nodeImpl->prev != NULL) { |
| iterator.nodeImpl->prev->next = iterator.nodeImpl->next; |
| } else { |
| d->head = iterator.nodeImpl->next; |
| } |
| |
| d->deleteNode(iterator.nodeImpl); |
| d->count--; |
| |
| return KWQValueListIteratorImpl(next); |
| } |
| |
| KWQValueListIteratorImpl KWQValueListImpl::fromLast() |
| { |
| return KWQValueListIteratorImpl(lastNode()); |
| } |
| |
| KWQValueListNodeImpl *KWQValueListImpl::firstNode() |
| { |
| copyOnWrite(); |
| return ((const KWQValueListImpl *)this)->firstNode(); |
| } |
| |
| KWQValueListNodeImpl *KWQValueListImpl::lastNode() |
| { |
| copyOnWrite(); |
| return ((const KWQValueListImpl *)this)->lastNode(); |
| } |
| |
| KWQValueListNodeImpl *KWQValueListImpl::firstNode() const |
| { |
| return d->head; |
| } |
| |
| KWQValueListNodeImpl *KWQValueListImpl::lastNode() const |
| { |
| // FIXME: use tail pointer |
| |
| KWQValueListNodeImpl *p = d->head; |
| |
| if (p == NULL) { |
| return NULL; |
| } |
| |
| while (p->next != NULL) { |
| p = p->next; |
| } |
| |
| return p; |
| } |
| |
| KWQValueListIteratorImpl KWQValueListImpl::begin() |
| { |
| copyOnWrite(); |
| return ((const KWQValueListImpl *)this)->begin(); |
| } |
| |
| KWQValueListIteratorImpl KWQValueListImpl::end() |
| { |
| copyOnWrite(); |
| return ((const KWQValueListImpl *)this)->end(); |
| } |
| |
| |
| KWQValueListIteratorImpl KWQValueListImpl::begin() const |
| { |
| return KWQValueListIteratorImpl(firstNode()); |
| } |
| |
| KWQValueListIteratorImpl KWQValueListImpl::end() const |
| { |
| return KWQValueListIteratorImpl(NULL); |
| } |
| |
| |
| KWQValueListNodeImpl *KWQValueListImpl::nodeAt(uint index) |
| { |
| copyOnWrite(); |
| |
| if (d->count <= index) { |
| return NULL; |
| } |
| |
| KWQValueListNodeImpl *p = d->head; |
| |
| for (uint i = 0; i < index; i++) { |
| p = p->next; |
| } |
| |
| return p; |
| } |
| |
| KWQValueListNodeImpl *KWQValueListImpl::nodeAt(uint index) const |
| { |
| if (d->count <= index) { |
| return NULL; |
| } |
| |
| KWQValueListNodeImpl *p = d->head; |
| |
| for (uint i = 0; i < index; i++) { |
| p = p->next; |
| } |
| |
| return p; |
| } |
| |
| KWQValueListImpl KWQValueListImpl::operator=(const KWQValueListImpl &other) |
| { |
| KWQValueListImpl tmp(other); |
| KWQRefPtr<KWQValueListImpl::KWQValueListPrivate> tmpD = tmp.d; |
| |
| tmp.d = d; |
| d = tmpD; |
| |
| return *this; |
| } |
| |
| void KWQValueListImpl::copyOnWrite() |
| { |
| if (d->refCount > 1) { |
| d = KWQRefPtr<KWQValueListImpl::KWQValueListPrivate>(new KWQValueListImpl::KWQValueListPrivate(*d)); |
| } |
| } |
| |
| #endif |