fd7fa6bd3426c48ccce7bbc8a38c483e2c645781
[WebKit-https.git] / JavaScriptCore / kjs / list.h
1 /*
2  *  This file is part of the KDE libraries
3  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
4  *  Copyright (C) 2003 Apple Computer, Inc.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifndef KJS_LIST_H
24 #define KJS_LIST_H
25
26 #include "value.h"
27
28 namespace KJS {
29
30     struct ListImpBase {
31         int size;
32         int refCount;
33         int valueRefCount; // FIXME: Get rid of this.
34     };
35     
36     class ListIterator;
37
38     /**
39      * @short Native list type.
40      *
41      * List is a native ECMAScript type. List values are only used for
42      * intermediate results of expression evaluation and cannot be stored
43      * as properties of objects.
44      */
45     class List : Noncopyable {
46     public:
47         List();
48         ~List() { deref(); }
49
50         /**
51          * Append an object to the end of the list.
52          *
53          * @param val Pointer to object.
54          */
55         void append(JSValue *val);
56         /**
57          * Remove all elements from the list.
58          */
59         void clear();
60
61         void reset() { deref(); ++(_impBase = empty()._impBase)->refCount; }
62
63         /**
64          * Make a copy of the list, starting from startIndex.
65          */
66         void slice(int startIndex, List& result) const;
67         /**
68          * @return true if the list is empty. false otherwise.
69          */
70         bool isEmpty() const { return _impBase->size == 0; }
71         /**
72          * @return the current size of the list.
73          */
74         int size() const { return _impBase->size; }
75         /**
76          * @return A KJS::ListIterator pointing to the first element.
77          */
78         ListIterator begin() const;
79         /**
80          * @return A KJS::ListIterator pointing to the last element.
81          */
82         ListIterator end() const;
83         
84         /**
85          * Retrieve an element at an indexed position. If you want to iterate
86          * trough the whole list using KJS::ListIterator will be faster.
87          *
88          * @param i List index.
89          * @return Return the element at position i. KJS::Undefined if the
90          * index is out of range.
91          */
92         JSValue *at(int i) const;
93         /**
94          * Equivalent to at.
95          */
96         JSValue *operator[](int i) const { return at(i); }
97     
98         /**
99          * Returns a pointer to a static instance of an empty list. Useful if a
100          * function has a KJS::List parameter.
101          */
102         static const List &empty();
103         
104         static void markProtectedLists();
105     private:
106         ListImpBase *_impBase;
107         
108         void deref() { --_impBase->valueRefCount; if (--_impBase->refCount == 0) release(); }
109
110         void release();
111         void markValues();
112     };
113   
114     /**
115      * @short Iterator for KJS::List objects.
116      */
117     class ListIterator {
118     public:
119         /**
120          * Construct an iterator that points to the first element of the list.
121          * @param l The list the iterator will operate on.
122          */
123         ListIterator(const List &l) : _list(&l), _i(0) { }
124         ListIterator(const List &l, int index) : _list(&l), _i(index) { }
125         /**
126          * Dereference the iterator.
127          * @return A pointer to the element the iterator operates on.
128          */
129         JSValue *operator->() const { return _list->at(_i); }
130         JSValue *operator*() const { return _list->at(_i); }
131         /**
132          * Prefix increment operator.
133          * @return The element after the increment.
134          */
135         JSValue *operator++() { return _list->at(++_i); }
136         /**
137          * Postfix increment operator.
138          */
139         JSValue *operator++(int) { return _list->at(_i++); }
140         /**
141          * Prefix decrement operator.
142          */
143         JSValue *operator--() { return _list->at(--_i); }
144         /**
145          * Postfix decrement operator.
146          */
147         JSValue *operator--(int) { return _list->at(_i--); }
148         /**
149          * Compare the iterator with another one.
150          * @return True if the two iterators operate on the same list element.
151          * False otherwise.
152          */
153         bool operator==(const ListIterator &it) const { return _i == it._i; }
154         /**
155          * Check for inequality with another iterator.
156          * @return True if the two iterators operate on different list elements.
157          */
158         bool operator!=(const ListIterator &it) const { return _i != it._i; }
159
160     private:
161         const List *_list;
162         int _i;
163     };
164
165     inline ListIterator List::begin() const { return ListIterator(*this); }
166     inline ListIterator List::end() const { return ListIterator(*this, size()); }
167  
168 } // namespace KJS
169
170 #endif // KJS_LIST_H