blob: 143c830ee92ad3d11fe62372dc2a6947557ef8c3 [file] [log] [blame]
ager@chromium.org5ec48922009-05-05 07:25:34 +00001// Copyright 2006-2009 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_LIST_INL_H_
29#define V8_LIST_INL_H_
30
31#include "list.h"
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000032#include "platform.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000033
kasperl@chromium.org71affb52009-05-26 05:44:31 +000034namespace v8 {
35namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036
37
38template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +000039void List<T, P>::Add(const T& element, P alloc) {
kasperl@chromium.org7be3c992009-03-12 07:19:55 +000040 if (length_ < capacity_) {
41 data_[length_++] = element;
42 } else {
rossberg@chromium.org400388e2012-06-06 09:29:22 +000043 List<T, P>::ResizeAdd(element, alloc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045}
46
47
kasperl@chromium.org71affb52009-05-26 05:44:31 +000048template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +000049void List<T, P>::AddAll(const List<T, P>& other, P alloc) {
50 AddAll(other.ToVector(), alloc);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +000051}
52
53
54template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +000055void List<T, P>::AddAll(const Vector<T>& other, P alloc) {
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +000056 int result_length = length_ + other.length();
rossberg@chromium.org400388e2012-06-06 09:29:22 +000057 if (capacity_ < result_length) Resize(result_length, alloc);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +000058 for (int i = 0; i < other.length(); i++) {
59 data_[length_ + i] = other.at(i);
kasperl@chromium.org71affb52009-05-26 05:44:31 +000060 }
61 length_ = result_length;
62}
63
64
ager@chromium.org5ec48922009-05-05 07:25:34 +000065// Use two layers of inlining so that the non-inlined function can
66// use the same implementation as the inlined version.
67template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +000068void List<T, P>::ResizeAdd(const T& element, P alloc) {
69 ResizeAddInternal(element, alloc);
ager@chromium.org5ec48922009-05-05 07:25:34 +000070}
71
72
73template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +000074void List<T, P>::ResizeAddInternal(const T& element, P alloc) {
ager@chromium.org5ec48922009-05-05 07:25:34 +000075 ASSERT(length_ >= capacity_);
jkummerow@chromium.orgab7dad42012-02-07 12:07:34 +000076 // Grow the list capacity by 100%, but make sure to let it grow
ager@chromium.org5ec48922009-05-05 07:25:34 +000077 // even when the capacity is zero (possible initial case).
jkummerow@chromium.orgab7dad42012-02-07 12:07:34 +000078 int new_capacity = 1 + 2 * capacity_;
kasperl@chromium.org71affb52009-05-26 05:44:31 +000079 // Since the element reference could be an element of the list, copy
80 // it out of the old backing storage before resizing.
81 T temp = element;
rossberg@chromium.org400388e2012-06-06 09:29:22 +000082 Resize(new_capacity, alloc);
kasperl@chromium.org71affb52009-05-26 05:44:31 +000083 data_[length_++] = temp;
84}
85
86
87template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +000088void List<T, P>::Resize(int new_capacity, P alloc) {
yangguo@chromium.org46a2a512013-01-18 16:29:40 +000089 ASSERT_LE(length_, new_capacity);
rossberg@chromium.org400388e2012-06-06 09:29:22 +000090 T* new_data = NewData(new_capacity, alloc);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +000091 OS::MemCopy(new_data, data_, length_ * sizeof(T));
ager@chromium.org5ec48922009-05-05 07:25:34 +000092 List<T, P>::DeleteData(data_);
93 data_ = new_data;
94 capacity_ = new_capacity;
95}
96
97
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000098template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +000099Vector<T> List<T, P>::AddBlock(T value, int count, P alloc) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000100 int start = length_;
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000101 for (int i = 0; i < count; i++) Add(value, alloc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000102 return Vector<T>(&data_[start], count);
103}
104
105
106template<typename T, class P>
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000107void List<T, P>::Set(int index, const T& elm) {
108 ASSERT(index >= 0 && index <= length_);
109 data_[index] = elm;
110}
111
112
113template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000114void List<T, P>::InsertAt(int index, const T& elm, P alloc) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 ASSERT(index >= 0 && index <= length_);
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000116 Add(elm, alloc);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 for (int i = length_ - 1; i > index; --i) {
118 data_[i] = data_[i - 1];
119 }
120 data_[index] = elm;
121}
122
123
124template<typename T, class P>
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000125T List<T, P>::Remove(int i) {
126 T element = at(i);
127 length_--;
128 while (i < length_) {
129 data_[i] = data_[i + 1];
130 i++;
131 }
132 return element;
133}
134
135
136template<typename T, class P>
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137bool List<T, P>::RemoveElement(const T& elm) {
138 for (int i = 0; i < length_; i++) {
139 if (data_[i] == elm) {
140 Remove(i);
141 return true;
142 }
143 }
144 return false;
145}
146
147
148template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000149void List<T, P>::Allocate(int length, P allocator) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +0000150 DeleteData(data_);
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000151 Initialize(length, allocator);
jkummerow@chromium.org212d9642012-05-11 15:02:09 +0000152 length_ = length;
153}
154
155
156template<typename T, class P>
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000157void List<T, P>::Clear() {
158 DeleteData(data_);
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000159 // We don't call Initialize(0) since that requires passing a Zone,
160 // which we don't really need.
161 data_ = NULL;
162 capacity_ = 0;
163 length_ = 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000164}
165
166
167template<typename T, class P>
168void List<T, P>::Rewind(int pos) {
169 length_ = pos;
170}
171
172
173template<typename T, class P>
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000174void List<T, P>::Trim(P alloc) {
175 if (length_ < capacity_ / 4) {
176 Resize(capacity_ / 2, alloc);
177 }
178}
179
180
181template<typename T, class P>
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000182void List<T, P>::Iterate(void (*callback)(T* x)) {
183 for (int i = 0; i < length_; i++) callback(&data_[i]);
184}
185
186
187template<typename T, class P>
vegorov@chromium.org26c16f82010-08-11 13:41:03 +0000188template<class Visitor>
189void List<T, P>::Iterate(Visitor* visitor) {
190 for (int i = 0; i < length_; i++) visitor->Apply(&data_[i]);
191}
192
193
194template<typename T, class P>
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195bool List<T, P>::Contains(const T& elm) const {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000196 for (int i = 0; i < length_; i++) {
197 if (data_[i] == elm)
198 return true;
199 }
200 return false;
201}
202
203
204template<typename T, class P>
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000205int List<T, P>::CountOccurrences(const T& elm, int start, int end) const {
206 int result = 0;
207 for (int i = start; i <= end; i++) {
208 if (data_[i] == elm) ++result;
209 }
210 return result;
211}
212
213
214template<typename T, class P>
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215void List<T, P>::Sort(int (*cmp)(const T* x, const T* y)) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000216 ToVector().Sort(cmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217#ifdef DEBUG
218 for (int i = 1; i < length_; i++)
219 ASSERT(cmp(&data_[i - 1], &data_[i]) <= 0);
220#endif
221}
222
223
224template<typename T, class P>
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000225void List<T, P>::Sort() {
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000226 ToVector().Sort();
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000227}
228
229
230template<typename T, class P>
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000231void List<T, P>::Initialize(int capacity, P allocator) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000232 ASSERT(capacity >= 0);
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000233 data_ = (capacity > 0) ? NewData(capacity, allocator) : NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000234 capacity_ = capacity;
235 length_ = 0;
236}
237
238
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000239template <typename T, typename P>
240int SortedListBSearch(const List<T>& list, P cmp) {
lrn@chromium.org34e60782011-09-15 07:25:40 +0000241 int low = 0;
242 int high = list.length() - 1;
243 while (low <= high) {
244 int mid = (low + high) / 2;
245 T mid_elem = list[mid];
246
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000247 if (cmp(&mid_elem) > 0) {
lrn@chromium.org34e60782011-09-15 07:25:40 +0000248 high = mid - 1;
249 continue;
250 }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000251 if (cmp(&mid_elem) < 0) {
lrn@chromium.org34e60782011-09-15 07:25:40 +0000252 low = mid + 1;
253 continue;
254 }
255 // Found the elememt.
256 return mid;
257 }
258 return -1;
259}
260
261
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000262template<typename T>
263class ElementCmp {
264 public:
265 explicit ElementCmp(T e) : elem_(e) {}
266 int operator()(const T* other) {
267 return PointerValueCompare(other, &elem_);
268 }
269 private:
270 T elem_;
271};
272
273
lrn@chromium.org34e60782011-09-15 07:25:40 +0000274template <typename T>
275int SortedListBSearch(const List<T>& list, T elem) {
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000276 return SortedListBSearch<T, ElementCmp<T> > (list, ElementCmp<T>(elem));
lrn@chromium.org34e60782011-09-15 07:25:40 +0000277}
278
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000279
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000280} } // namespace v8::internal
281
282#endif // V8_LIST_INL_H_