File indexing completed on 2024-05-12 15:43:26
0001 /* 0002 * This file is part of the KDE libraries 0003 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 0004 * Copyright (C) 2003 Apple Computer, Inc. 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this library; see the file COPYING.LIB. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 * 0021 */ 0022 0023 #ifndef KJS_LIST_H 0024 #define KJS_LIST_H 0025 0026 #include "value.h" 0027 #include "LocalStorage.h" 0028 0029 namespace KJS 0030 { 0031 0032 const int inlineListValuesSize = 5; 0033 0034 struct ListImpBase { 0035 int size; 0036 int refCount; 0037 LocalStorageEntry *data; // points either to inline or out-of-line buffer 0038 }; 0039 0040 class ListIterator; 0041 0042 /** 0043 * @short Native list type. 0044 * 0045 * List is a native ECMAScript type. List values are only used for 0046 * intermediate results of expression evaluation and cannot be stored 0047 * as properties of objects. 0048 * 0049 * The list is explicitly shared. Note that while copyTail() returns a 0050 * copy of the list the referenced objects are still shared. 0051 */ 0052 class KJS_EXPORT List 0053 { 0054 public: 0055 List(); 0056 ~List() 0057 { 0058 deref(); 0059 } 0060 0061 List(const List &b) : _impBase(b._impBase) 0062 { 0063 ++_impBase->refCount; 0064 } 0065 List &operator=(const List &); 0066 0067 /** 0068 * Append an object to the end of the list. 0069 * 0070 * @param val Pointer to object. 0071 */ 0072 void append(JSValue *val); 0073 0074 /** 0075 * Remove all elements from the list. 0076 */ 0077 void clear() 0078 { 0079 _impBase->size = 0; 0080 } 0081 0082 /* 0083 * Resets this List to point to the default empty list 0084 */ 0085 void reset() 0086 { 0087 deref(); 0088 ++(_impBase = empty()._impBase)->refCount; 0089 } 0090 0091 /** 0092 * Make a copy of the list 0093 */ 0094 List copy() const; 0095 0096 /** 0097 * Make a copy of the list, omitting the first element. 0098 */ 0099 List copyTail() const; 0100 0101 /** 0102 * @return true if the list is empty. false otherwise. 0103 */ 0104 bool isEmpty() const 0105 { 0106 return _impBase->size == 0; 0107 } 0108 0109 /** 0110 * @return the current size of the list. 0111 */ 0112 int size() const 0113 { 0114 return _impBase->size; 0115 } 0116 0117 /** 0118 * @return A KJS::ListIterator pointing to the first element. 0119 */ 0120 ListIterator begin() const; 0121 0122 /** 0123 * @return A KJS::ListIterator pointing to the last element. 0124 */ 0125 ListIterator end() const; 0126 0127 /** 0128 * Retrieve an element at an indexed position. 0129 * 0130 * @param i List index. 0131 * @return Return the element at position i. KJS::Undefined if the 0132 * index is out of range. 0133 */ 0134 JSValue *at(int i) const; 0135 0136 // As above but omits the range change 0137 JSValue *atUnchecked(int i) const 0138 { 0139 return _impBase->data[i].val.valueVal; 0140 } 0141 0142 /** 0143 * Equivalent to at. 0144 */ 0145 JSValue *operator[](int i) const 0146 { 0147 return at(i); 0148 } 0149 0150 /** 0151 * Returns a pointer to a static instance of an empty list. Useful if a 0152 * function has a KJS::List parameter. 0153 */ 0154 static const List &empty(); 0155 0156 static void markProtectedLists(); 0157 private: 0158 /** 0159 * Copy all elements from the second list here 0160 */ 0161 void copyFrom(const List &other); 0162 0163 void appendSlowCase(JSValue *val); 0164 0165 ListImpBase *_impBase; 0166 0167 void deref() 0168 { 0169 if (--_impBase->refCount == 0) { 0170 release(); 0171 } 0172 } 0173 0174 void release(); 0175 }; 0176 0177 inline JSValue *List::at(int i) const 0178 { 0179 if (i < _impBase->size) { 0180 return _impBase->data[i].val.valueVal; 0181 } else { 0182 return jsUndefined(); 0183 } 0184 } 0185 0186 inline void List::append(JSValue *val) 0187 { 0188 int size = _impBase->size; 0189 int newSize = size + 1; 0190 if (newSize < inlineListValuesSize) { 0191 // Can just write to the inline buffer 0192 _impBase->data[size].val.valueVal = val; 0193 _impBase->size = newSize; 0194 } else { 0195 appendSlowCase(val); 0196 } 0197 } 0198 0199 /** 0200 * @short Iterator for KJS::List objects. 0201 */ 0202 class ListIterator 0203 { 0204 public: 0205 /** 0206 * Construct an iterator that points to the first element of the list. 0207 * @param l The list the iterator will operate on. 0208 */ 0209 ListIterator(const List &l) : _list(&l), _i(0) { } 0210 ListIterator(const List &l, int index) : _list(&l), _i(index) { } 0211 /** 0212 * Dereference the iterator. 0213 * @return A pointer to the element the iterator operates on. 0214 */ 0215 JSValue *operator->() const 0216 { 0217 return _list->at(_i); 0218 } 0219 JSValue *operator*() const 0220 { 0221 return _list->at(_i); 0222 } 0223 /** 0224 * Prefix increment operator. 0225 * @return The element after the increment. 0226 */ 0227 JSValue *operator++() 0228 { 0229 return _list->at(++_i); 0230 } 0231 /** 0232 * Postfix increment operator. 0233 */ 0234 JSValue *operator++(int) 0235 { 0236 return _list->at(_i++); 0237 } 0238 /** 0239 * Prefix decrement operator. 0240 */ 0241 JSValue *operator--() 0242 { 0243 return _list->at(--_i); 0244 } 0245 /** 0246 * Postfix decrement operator. 0247 */ 0248 JSValue *operator--(int) 0249 { 0250 return _list->at(_i--); 0251 } 0252 /** 0253 * Compare the iterator with another one. 0254 * @return True if the two iterators operate on the same list element. 0255 * False otherwise. 0256 */ 0257 bool operator==(const ListIterator &it) const 0258 { 0259 return _i == it._i; 0260 } 0261 /** 0262 * Check for inequality with another iterator. 0263 * @return True if the two iterators operate on different list elements. 0264 */ 0265 bool operator!=(const ListIterator &it) const 0266 { 0267 return _i != it._i; 0268 } 0269 0270 private: 0271 const List *_list; 0272 int _i; 0273 }; 0274 0275 inline ListIterator List::begin() const 0276 { 0277 return ListIterator(*this); 0278 } 0279 inline ListIterator List::end() const 0280 { 0281 return ListIterator(*this, size()); 0282 } 0283 0284 } // namespace KJS 0285 0286 #endif // KJS_LIST_H 0287