blob: 9b122fdbae4417fc710b755cc4be9fe541f4b04b [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2009 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_LIST_INL_H_
6#define V8_LIST_INL_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/list.h"
9
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010#include "src/base/macros.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/base/platform/platform.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000012
13namespace v8 {
14namespace internal {
15
16
17template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018void List<T, P>::Add(const T& element, P alloc) {
Steve Blocka7e24c12009-10-30 11:49:00 +000019 if (length_ < capacity_) {
20 data_[length_++] = element;
21 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022 List<T, P>::ResizeAdd(element, alloc);
Steve Blocka7e24c12009-10-30 11:49:00 +000023 }
24}
25
26
27template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028void List<T, P>::AddAll(const List<T, P>& other, P alloc) {
29 AddAll(other.ToVector(), alloc);
Ben Murdoch257744e2011-11-30 15:57:28 +000030}
31
32
33template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034void List<T, P>::AddAll(const Vector<T>& other, P alloc) {
Ben Murdoch257744e2011-11-30 15:57:28 +000035 int result_length = length_ + other.length();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036 if (capacity_ < result_length) Resize(result_length, alloc);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040037 if (base::is_fundamental<T>()) {
38 memcpy(data_ + length_, other.start(), sizeof(*data_) * other.length());
39 } else {
40 for (int i = 0; i < other.length(); i++) data_[length_ + i] = other.at(i);
Steve Blocka7e24c12009-10-30 11:49:00 +000041 }
42 length_ = result_length;
43}
44
45
46// Use two layers of inlining so that the non-inlined function can
47// use the same implementation as the inlined version.
48template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000049void List<T, P>::ResizeAdd(const T& element, P alloc) {
50 ResizeAddInternal(element, alloc);
Steve Blocka7e24c12009-10-30 11:49:00 +000051}
52
53
54template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055void List<T, P>::ResizeAddInternal(const T& element, P alloc) {
56 DCHECK(length_ >= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +010057 // Grow the list capacity by 100%, but make sure to let it grow
Steve Blocka7e24c12009-10-30 11:49:00 +000058 // even when the capacity is zero (possible initial case).
Ben Murdoch3ef787d2012-04-12 10:51:47 +010059 int new_capacity = 1 + 2 * capacity_;
Steve Blocka7e24c12009-10-30 11:49:00 +000060 // Since the element reference could be an element of the list, copy
61 // it out of the old backing storage before resizing.
62 T temp = element;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063 Resize(new_capacity, alloc);
Steve Blocka7e24c12009-10-30 11:49:00 +000064 data_[length_++] = temp;
65}
66
67
68template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069void List<T, P>::Resize(int new_capacity, P alloc) {
70 DCHECK_LE(length_, new_capacity);
71 T* new_data = NewData(new_capacity, alloc);
72 MemCopy(new_data, data_, length_ * sizeof(T));
Steve Blocka7e24c12009-10-30 11:49:00 +000073 List<T, P>::DeleteData(data_);
74 data_ = new_data;
75 capacity_ = new_capacity;
76}
77
78
79template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080Vector<T> List<T, P>::AddBlock(T value, int count, P alloc) {
Steve Blocka7e24c12009-10-30 11:49:00 +000081 int start = length_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000082 for (int i = 0; i < count; i++) Add(value, alloc);
Steve Blocka7e24c12009-10-30 11:49:00 +000083 return Vector<T>(&data_[start], count);
84}
85
86
87template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088void List<T, P>::Set(int index, const T& elm) {
89 DCHECK(index >= 0 && index <= length_);
90 data_[index] = elm;
91}
92
93
94template<typename T, class P>
95void List<T, P>::InsertAt(int index, const T& elm, P alloc) {
96 DCHECK(index >= 0 && index <= length_);
97 Add(elm, alloc);
Ben Murdochb0fe1622011-05-05 13:52:32 +010098 for (int i = length_ - 1; i > index; --i) {
99 data_[i] = data_[i - 1];
100 }
101 data_[index] = elm;
102}
103
104
105template<typename T, class P>
Steve Blocka7e24c12009-10-30 11:49:00 +0000106T List<T, P>::Remove(int i) {
107 T element = at(i);
108 length_--;
109 while (i < length_) {
110 data_[i] = data_[i + 1];
111 i++;
112 }
113 return element;
114}
115
116
117template<typename T, class P>
Ben Murdochb0fe1622011-05-05 13:52:32 +0100118bool List<T, P>::RemoveElement(const T& elm) {
119 for (int i = 0; i < length_; i++) {
120 if (data_[i] == elm) {
121 Remove(i);
122 return true;
123 }
124 }
125 return false;
126}
127
128
129template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000130void List<T, P>::Allocate(int length, P allocator) {
131 DeleteData(data_);
132 Initialize(length, allocator);
133 length_ = length;
134}
135
136
137template<typename T, class P>
Steve Blocka7e24c12009-10-30 11:49:00 +0000138void List<T, P>::Clear() {
139 DeleteData(data_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140 // We don't call Initialize(0) since that requires passing a Zone,
141 // which we don't really need.
142 data_ = NULL;
143 capacity_ = 0;
144 length_ = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000145}
146
147
148template<typename T, class P>
149void List<T, P>::Rewind(int pos) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150 DCHECK(0 <= pos && pos <= length_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 length_ = pos;
152}
153
154
155template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000156void List<T, P>::Trim(P alloc) {
157 if (length_ < capacity_ / 4) {
158 Resize(capacity_ / 2, alloc);
159 }
160}
161
162
163template<typename T, class P>
Steve Blocka7e24c12009-10-30 11:49:00 +0000164void List<T, P>::Iterate(void (*callback)(T* x)) {
165 for (int i = 0; i < length_; i++) callback(&data_[i]);
166}
167
168
169template<typename T, class P>
Iain Merrick75681382010-08-19 15:07:18 +0100170template<class Visitor>
171void List<T, P>::Iterate(Visitor* visitor) {
172 for (int i = 0; i < length_; i++) visitor->Apply(&data_[i]);
173}
174
175
176template<typename T, class P>
Ben Murdochb0fe1622011-05-05 13:52:32 +0100177bool List<T, P>::Contains(const T& elm) const {
Steve Blocka7e24c12009-10-30 11:49:00 +0000178 for (int i = 0; i < length_; i++) {
179 if (data_[i] == elm)
180 return true;
181 }
182 return false;
183}
184
185
186template<typename T, class P>
Ben Murdochb0fe1622011-05-05 13:52:32 +0100187int List<T, P>::CountOccurrences(const T& elm, int start, int end) const {
188 int result = 0;
189 for (int i = start; i <= end; i++) {
190 if (data_[i] == elm) ++result;
191 }
192 return result;
193}
194
195
196template<typename T, class P>
Steve Blocka7e24c12009-10-30 11:49:00 +0000197void List<T, P>::Sort(int (*cmp)(const T* x, const T* y)) {
198 ToVector().Sort(cmp);
199#ifdef DEBUG
200 for (int i = 1; i < length_; i++)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000201 DCHECK(cmp(&data_[i - 1], &data_[i]) <= 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000202#endif
203}
204
205
206template<typename T, class P>
207void List<T, P>::Sort() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208 ToVector().Sort();
Steve Blocka7e24c12009-10-30 11:49:00 +0000209}
210
211
212template<typename T, class P>
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213void List<T, P>::Initialize(int capacity, P allocator) {
214 DCHECK(capacity >= 0);
215 data_ = (capacity > 0) ? NewData(capacity, allocator) : NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000216 capacity_ = capacity;
217 length_ = 0;
218}
219
220
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000221template <typename T, typename P>
222int SortedListBSearch(const List<T>& list, P cmp) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000223 int low = 0;
224 int high = list.length() - 1;
225 while (low <= high) {
226 int mid = (low + high) / 2;
227 T mid_elem = list[mid];
228
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000229 if (cmp(&mid_elem) > 0) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000230 high = mid - 1;
231 continue;
232 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000233 if (cmp(&mid_elem) < 0) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000234 low = mid + 1;
235 continue;
236 }
237 // Found the elememt.
238 return mid;
239 }
240 return -1;
241}
242
243
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000244template<typename T>
245class ElementCmp {
246 public:
247 explicit ElementCmp(T e) : elem_(e) {}
248 int operator()(const T* other) {
249 return PointerValueCompare(other, &elem_);
250 }
251 private:
252 T elem_;
253};
254
255
Ben Murdoch589d6972011-11-30 16:04:58 +0000256template <typename T>
257int SortedListBSearch(const List<T>& list, T elem) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000258 return SortedListBSearch<T, ElementCmp<T> > (list, ElementCmp<T>(elem));
Ben Murdoch589d6972011-11-30 16:04:58 +0000259}
260
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100261
Steve Blocka7e24c12009-10-30 11:49:00 +0000262} } // namespace v8::internal
263
264#endif // V8_LIST_INL_H_