JavaScriptCore:
[WebKit-https.git] / JavaScriptCore / kjs / list.h
1 /*
2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2003, 2007 Apple Computer, Inc.
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Library General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Library General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Library General Public License
16  *  along with this library; see the file COPYING.LIB.  If not, write to
17  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  *  Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef KJS_LIST_H
23 #define KJS_LIST_H
24
25 #include <kjs/value.h>
26 #include <wtf/HashSet.h>
27 #include <wtf/Noncopyable.h>
28 #include <wtf/Vector.h>
29
30 namespace KJS {
31
32     class JSValue;
33     class List;
34     
35     class List : Noncopyable {
36     private:
37         typedef Vector<JSValue*, 8> VectorType;
38         typedef HashSet<List*> ListSet;
39
40     public:
41         typedef VectorType::iterator iterator;
42         typedef VectorType::const_iterator const_iterator;
43
44         List()
45             : m_isInMarkSet(false)
46         {
47         }
48
49         ~List()
50         {
51             if (m_isInMarkSet)
52                 markSet().remove(this);
53         }
54
55         int size() const { return m_vector.size(); }
56         bool isEmpty() const { return m_vector.isEmpty(); }
57
58         JSValue* at(size_t i) const
59         {
60             if (i < m_vector.size())
61                 return m_vector.at(i);
62             return jsUndefined();
63         }
64
65         JSValue* operator[](int i) const { return at(i); }
66
67         void clear() { m_vector.clear(); }
68
69         void append(JSValue* v)
70         {
71             if (m_vector.size() < m_vector.capacity())
72                 m_vector.uncheckedAppend(v);
73             else
74                 // Putting the slow "expand and append" case all in one 
75                 // function measurably improves the performance of the fast 
76                 // "just append" case.
77                 expandAndAppend(v);
78         }
79
80         void getSlice(int startIndex, List& result) const;
81
82         iterator begin() { return m_vector.begin(); }
83         iterator end() { return m_vector.end(); }
84
85         const_iterator begin() const { return m_vector.begin(); }
86         const_iterator end() const { return m_vector.end(); }
87
88         static void markProtectedLists()
89         {
90             if (!markSet().size())
91                 return;
92             markProtectedListsSlowCase();
93         }
94
95         static const List& empty(); // Fast path for an empty list.
96
97     private:
98         static ListSet& markSet();
99         static void markProtectedListsSlowCase();
100
101         void expandAndAppend(JSValue*);
102
103         VectorType m_vector;
104         bool m_isInMarkSet;
105
106     private:
107         // Prohibits new / delete, which would break GC.
108         void* operator new(size_t);
109         void operator delete(void*);
110
111         void* operator new[](size_t);
112         void operator delete[](void*);
113
114         void* operator new(size_t, void*);
115         void operator delete(void*, size_t);
116     };
117     
118 } // namespace KJS
119
120 #endif // KJS_LIST_H