OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef ContiguousContainer_h | 5 #ifndef ContiguousContainer_h |
6 #define ContiguousContainer_h | 6 #define ContiguousContainer_h |
7 | 7 |
8 #include "platform/PlatformExport.h" | 8 #include "platform/PlatformExport.h" |
9 #include "wtf/Alignment.h" | 9 #include "wtf/Alignment.h" |
10 #include "wtf/Allocator.h" | 10 #include "wtf/Allocator.h" |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 BaseElementType& operator[](size_t index) { return *(begin() + index); } | 159 BaseElementType& operator[](size_t index) { return *(begin() + index); } |
160 const BaseElementType& operator[](size_t index) const { return *(begin() + i
ndex); } | 160 const BaseElementType& operator[](size_t index) const { return *(begin() + i
ndex); } |
161 | 161 |
162 template <class DerivedElementType, typename... Args> | 162 template <class DerivedElementType, typename... Args> |
163 DerivedElementType& allocateAndConstruct(Args&&... args) | 163 DerivedElementType& allocateAndConstruct(Args&&... args) |
164 { | 164 { |
165 static_assert(WTF::IsSubclass<DerivedElementType, BaseElementType>::valu
e, | 165 static_assert(WTF::IsSubclass<DerivedElementType, BaseElementType>::valu
e, |
166 "Must use subclass of BaseElementType."); | 166 "Must use subclass of BaseElementType."); |
167 static_assert(alignment % WTF_ALIGN_OF(DerivedElementType) == 0, | 167 static_assert(alignment % WTF_ALIGN_OF(DerivedElementType) == 0, |
168 "Derived type requires stronger alignment."); | 168 "Derived type requires stronger alignment."); |
169 size_t allocSize = align(sizeof(DerivedElementType)); | 169 return *new (alignedAllocate(sizeof(DerivedElementType))) DerivedElement
Type(std::forward<Args>(args)...); |
170 return *new (allocate(allocSize)) DerivedElementType(std::forward<Args>(
args)...); | |
171 } | 170 } |
172 | 171 |
173 void removeLast() | 172 void removeLast() |
174 { | 173 { |
175 ASSERT(!isEmpty()); | 174 ASSERT(!isEmpty()); |
176 last().~BaseElementType(); | 175 last().~BaseElementType(); |
177 ContiguousContainerBase::removeLast(); | 176 ContiguousContainerBase::removeLast(); |
178 } | 177 } |
179 | 178 |
180 void clear() | 179 void clear() |
181 { | 180 { |
182 for (auto& element : *this) { | 181 for (auto& element : *this) { |
183 (void)element; // MSVC incorrectly reports this variable as unused. | 182 (void)element; // MSVC incorrectly reports this variable as unused. |
184 element.~BaseElementType(); | 183 element.~BaseElementType(); |
185 } | 184 } |
186 ContiguousContainerBase::clear(); | 185 ContiguousContainerBase::clear(); |
187 } | 186 } |
188 | 187 |
189 void swap(ContiguousContainer& other) { ContiguousContainerBase::swap(other)
; } | 188 void swap(ContiguousContainer& other) { ContiguousContainerBase::swap(other)
; } |
190 | 189 |
191 // Appends a new element using memcpy, then default-constructs a base | 190 // Appends a new element using memcpy, then default-constructs a base |
192 // element in its place. Use with care. | 191 // element in its place. Use with care. |
193 BaseElementType& appendByMoving(BaseElementType& item, size_t size) | 192 BaseElementType& appendByMoving(BaseElementType& item, size_t size) |
194 { | 193 { |
195 ASSERT(size >= sizeof(BaseElementType)); | 194 ASSERT(size >= sizeof(BaseElementType)); |
196 void* newItem = allocate(size); | 195 void* newItem = alignedAllocate(size); |
197 memcpy(newItem, static_cast<void*>(&item), size); | 196 memcpy(newItem, static_cast<void*>(&item), size); |
198 new (&item) BaseElementType; | 197 new (&item) BaseElementType; |
199 return *static_cast<BaseElementType*>(newItem); | 198 return *static_cast<BaseElementType*>(newItem); |
200 } | 199 } |
201 | 200 |
202 private: | 201 private: |
203 void* allocate(size_t objectSize) | 202 void* alignedAllocate(size_t size) |
204 { | 203 { |
205 return ContiguousContainerBase::allocate(objectSize, WTF_HEAP_PROFILER_T
YPE_NAME(BaseElementType)); | 204 void* result = ContiguousContainerBase::allocate(align(size), WTF_HEAP_P
ROFILER_TYPE_NAME(BaseElementType)); |
| 205 DCHECK_EQ(reinterpret_cast<intptr_t>(result) & (alignment - 1), 0u); |
| 206 return result; |
206 } | 207 } |
207 | 208 |
208 static size_t align(size_t size) | 209 static size_t align(size_t size) |
209 { | 210 { |
210 size_t alignedSize = alignment * ((size + alignment - 1) / alignment); | 211 size_t alignedSize = alignment * ((size + alignment - 1) / alignment); |
211 ASSERT(alignedSize % alignment == 0); | 212 DCHECK_EQ(alignedSize % alignment, 0u); |
212 ASSERT(alignedSize >= size); | 213 DCHECK_GE(alignedSize, size); |
213 ASSERT(alignedSize < size + alignment); | 214 DCHECK_LT(alignedSize, size + alignment); |
214 return alignedSize; | 215 return alignedSize; |
215 } | 216 } |
216 }; | 217 }; |
217 | 218 |
218 } // namespace blink | 219 } // namespace blink |
219 | 220 |
220 #endif // ContiguousContainer_h | 221 #endif // ContiguousContainer_h |
OLD | NEW |