list.h
00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 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 #ifndef KJS_LIST_H 00024 #define KJS_LIST_H 00025 00026 #include "value.h" 00027 00028 namespace KJS { 00029 00030 struct ListImpBase { 00031 int size; 00032 int refCount; 00033 int valueRefCount; 00034 }; 00035 00036 class ListIterator; 00037 00048 class KJS_EXPORT List { 00049 public: 00050 List(); 00051 List(bool needsMarking); 00052 ~List() { deref(); } 00053 00054 List(const List &b) : _impBase(b._impBase), _needsMarking(false) { 00055 ++_impBase->refCount; 00056 if (!_impBase->valueRefCount) refValues(); 00057 ++_impBase->valueRefCount; 00058 } 00059 List &operator=(const List &); 00060 00066 void append(const Value& val) { append(val.imp()); } 00067 void append(ValueImp *val); 00071 void clear(); 00072 00076 List copy() const; 00077 00081 List copyTail() const; 00082 00086 bool isEmpty() const { return _impBase->size == 0; } 00090 int size() const { return _impBase->size; } 00094 ListIterator begin() const; 00098 ListIterator end() const; 00099 00108 Value at(int i) const { return Value(impAt(i)); } 00112 Value operator[](int i) const { return Value(impAt(i)); } 00113 00114 ValueImp *impAt(int i) const; 00115 00120 static const List &empty(); 00121 00122 void mark() { if (_impBase->valueRefCount == 0) markValues(); } 00123 private: 00124 ListImpBase *_impBase; 00125 bool _needsMarking; 00126 00127 void deref() { if (!_needsMarking && --_impBase->valueRefCount == 0) derefValues(); if (--_impBase->refCount == 0) release(); } 00128 00129 void release(); 00130 void refValues(); 00131 void derefValues(); 00132 void markValues(); 00133 }; 00134 00138 class ListIterator { 00139 public: 00144 ListIterator(const List &l) : _list(&l), _i(0) { } 00145 ListIterator(const List &l, int index) : _list(&l), _i(index) { } 00150 ValueImp *operator->() const { return _list->impAt(_i); } 00151 Value operator*() const { return Value(_list->impAt(_i)); } 00156 Value operator++() { return Value(_list->impAt(++_i)); } 00160 Value operator++(int) { return Value(_list->impAt(_i++)); } 00164 Value operator--() { return Value(_list->impAt(--_i)); } 00168 Value operator--(int) { return Value(_list->impAt(_i--)); } 00174 bool operator==(const ListIterator &it) const { return _i == it._i; } 00179 bool operator!=(const ListIterator &it) const { return _i != it._i; } 00180 00181 private: 00182 const List *_list; 00183 int _i; 00184 }; 00185 00186 inline ListIterator List::begin() const { return ListIterator(*this); } 00187 inline ListIterator List::end() const { return ListIterator(*this, size()); } 00188 00189 inline List &List::operator=(const List &b) 00190 { 00191 ListImpBase *bImpBase = b._impBase; 00192 ++bImpBase->refCount; 00193 deref(); 00194 _impBase = bImpBase; 00195 if (!_needsMarking) { 00196 if (!_impBase->valueRefCount) { 00197 refValues(); 00198 } 00199 _impBase->valueRefCount++; 00200 } 00201 00202 return *this; 00203 } 00204 00205 } // namespace KJS 00206 00207 #endif // KJS_LIST_H