reference_list.cpp
00001 // -*- c-basic-offset: 2 -*- 00002 /* 00003 * This file is part of the KDE libraries 00004 * Copyright (C) 2003 Apple Computer, Inc 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Library General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Library General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Library General Public License 00017 * along with this library; see the file COPYING.LIB. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 */ 00022 00023 #include "reference_list.h" 00024 00025 namespace KJS { 00026 class ReferenceListNode { 00027 friend class ReferenceList; 00028 friend class ReferenceListIterator; 00029 00030 protected: 00031 ReferenceListNode(const Reference &ref) : reference(ref), next(NULL) {} 00032 00033 private: 00034 Reference reference; 00035 ReferenceListNode *next; 00036 }; 00037 00038 class ReferenceListHeadNode : private ReferenceListNode { 00039 friend class ReferenceList; 00040 friend class ReferenceListIterator; 00041 00042 ReferenceListHeadNode(const Reference &ref) : ReferenceListNode(ref), refcount(1), length(0) {} 00043 int refcount; 00044 int length; 00045 }; 00046 00047 } 00048 00049 using namespace KJS; 00050 00051 // ReferenceList 00052 00053 ReferenceList::ReferenceList() : 00054 head(NULL), 00055 tail(NULL) 00056 { 00057 } 00058 00059 ReferenceList::ReferenceList(const ReferenceList &list) 00060 { 00061 head = list.head; 00062 tail = list.tail; 00063 if (head != NULL) { 00064 head->refcount++; 00065 } 00066 } 00067 00068 ReferenceList &ReferenceList::operator=(const ReferenceList &list) 00069 { 00070 ReferenceList tmp(list); 00071 tmp.swap(*this); 00072 00073 return *this; 00074 } 00075 00076 void ReferenceList::swap(ReferenceList &list) 00077 { 00078 ReferenceListHeadNode *tmpHead = list.head; 00079 list.head = head; 00080 head = tmpHead; 00081 00082 ReferenceListNode *tmpTail = list.tail; 00083 list.tail = tail; 00084 tail = tmpTail; 00085 } 00086 00087 00088 void ReferenceList::append(const Reference& ref) 00089 { 00090 if (tail == NULL) { 00091 tail = head = new ReferenceListHeadNode(ref); 00092 } else { 00093 tail->next = new ReferenceListNode(ref); 00094 tail = tail->next; 00095 } 00096 head->length++; 00097 } 00098 00099 int ReferenceList::length() 00100 { 00101 return head ? head->length : 0; 00102 } 00103 00104 ReferenceList::~ReferenceList() 00105 { 00106 if (head != NULL && --(head->refcount) == 0) { 00107 ReferenceListNode *next; 00108 00109 for (ReferenceListNode *p = head; p != NULL; p = next) { 00110 next = p->next; 00111 if (p == head) { 00112 delete (ReferenceListHeadNode *)p; 00113 } else { 00114 delete p; 00115 } 00116 } 00117 } 00118 } 00119 00120 ReferenceListIterator ReferenceList::begin() const 00121 { 00122 return ReferenceListIterator(head); 00123 } 00124 00125 ReferenceListIterator ReferenceList::end() const 00126 { 00127 return ReferenceListIterator(NULL); 00128 } 00129 00130 00131 // ReferenceListIterator 00132 00133 00134 ReferenceListIterator::ReferenceListIterator(ReferenceListNode *n) : 00135 node(n) 00136 { 00137 } 00138 00139 bool ReferenceListIterator::operator!=(const ReferenceListIterator &it) const 00140 { 00141 return node != it.node; 00142 } 00143 00144 const Reference *ReferenceListIterator::operator->() const 00145 { 00146 return &node->reference; 00147 } 00148 00149 const Reference &ReferenceListIterator::operator++(int /*i*/) 00150 { 00151 const Reference &ref = node->reference; 00152 node = node->next; 00153 return ref; 00154 }