You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/kjs/reference_list.cpp

154 lines
3.2 KiB

/*
* This file is part of the KDE libraries
* Copyright (C) 2003 Apple Computer, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include "reference_list.h"
namespace KJS {
class ReferenceListNode {
friend class ReferenceList;
friend class ReferenceListIterator;
protected:
ReferenceListNode(const Reference &ref) : reference(ref), next(NULL) {}
private:
Reference reference;
ReferenceListNode *next;
};
class ReferenceListHeadNode : private ReferenceListNode {
friend class ReferenceList;
friend class ReferenceListIterator;
ReferenceListHeadNode(const Reference &ref) : ReferenceListNode(ref), refcount(1), length(0) {}
int refcount;
int length;
};
}
using namespace KJS;
// ReferenceList
ReferenceList::ReferenceList() :
head(NULL),
tail(NULL)
{
}
ReferenceList::ReferenceList(const ReferenceList &list)
{
head = list.head;
tail = list.tail;
if (head != NULL) {
head->refcount++;
}
}
ReferenceList &ReferenceList::operator=(const ReferenceList &list)
{
ReferenceList tmp(list);
tmp.swap(*this);
return *this;
}
void ReferenceList::swap(ReferenceList &list)
{
ReferenceListHeadNode *tmpHead = list.head;
list.head = head;
head = tmpHead;
ReferenceListNode *tmpTail = list.tail;
list.tail = tail;
tail = tmpTail;
}
void ReferenceList::append(const Reference& ref)
{
if (tail == NULL) {
tail = head = new ReferenceListHeadNode(ref);
} else {
tail->next = new ReferenceListNode(ref);
tail = tail->next;
}
head->length++;
}
int ReferenceList::length()
{
return head ? head->length : 0;
}
ReferenceList::~ReferenceList()
{
if (head != NULL && --(head->refcount) == 0) {
ReferenceListNode *next;
for (ReferenceListNode *p = head; p != NULL; p = next) {
next = p->next;
if (p == head) {
delete (ReferenceListHeadNode *)p;
} else {
delete p;
}
}
}
}
ReferenceListIterator ReferenceList::begin() const
{
return ReferenceListIterator(head);
}
ReferenceListIterator ReferenceList::end() const
{
return ReferenceListIterator(NULL);
}
// ReferenceListIterator
ReferenceListIterator::ReferenceListIterator(ReferenceListNode *n) :
node(n)
{
}
bool ReferenceListIterator::operator!=(const ReferenceListIterator &it) const
{
return node != it.node;
}
const Reference *ReferenceListIterator::operator->() const
{
return &node->reference;
}
const Reference &ReferenceListIterator::operator++(int /*i*/)
{
const Reference &ref = node->reference;
node = node->next;
return ref;
}