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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 { | 185 { |
186 for (auto& element : *this) { | 186 for (auto& element : *this) { |
187 (void)element; // MSVC incorrectly reports this variable as unused. | 187 (void)element; // MSVC incorrectly reports this variable as unused. |
188 element.~BaseElementType(); | 188 element.~BaseElementType(); |
189 } | 189 } |
190 ContiguousContainerBase::clear(); | 190 ContiguousContainerBase::clear(); |
191 } | 191 } |
192 | 192 |
193 void swap(ContiguousContainer& other) { ContiguousContainerBase::swap(other)
; } | 193 void swap(ContiguousContainer& other) { ContiguousContainerBase::swap(other)
; } |
194 | 194 |
195 // Appends a new element using memcpy, then default-constructs a base | 195 // Appends a new element using memcpy, then constructs a base element in its
place with args. |
196 // element in its place. Use with care. | 196 // Use with care. |
197 BaseElementType& appendByMoving(BaseElementType& item, size_t size) | 197 template <typename... Args> |
| 198 BaseElementType& appendByMoving(BaseElementType& item, size_t size, Args&&..
. args) |
198 { | 199 { |
199 ASSERT(size >= sizeof(BaseElementType)); | 200 ASSERT(size >= sizeof(BaseElementType)); |
200 void* newItem = alignedAllocate(size); | 201 void* newItem = alignedAllocate(size); |
201 memcpy(newItem, static_cast<void*>(&item), size); | 202 memcpy(newItem, static_cast<void*>(&item), size); |
202 new (&item) BaseElementType; | 203 new (&item) BaseElementType(std::forward<Args>(args)...); |
203 return *static_cast<BaseElementType*>(newItem); | 204 return *static_cast<BaseElementType*>(newItem); |
204 } | 205 } |
205 | 206 |
206 private: | 207 private: |
207 void* alignedAllocate(size_t size) | 208 void* alignedAllocate(size_t size) |
208 { | 209 { |
209 void* result = ContiguousContainerBase::allocate(align(size), WTF_HEAP_P
ROFILER_TYPE_NAME(BaseElementType)); | 210 void* result = ContiguousContainerBase::allocate(align(size), WTF_HEAP_P
ROFILER_TYPE_NAME(BaseElementType)); |
210 DCHECK_EQ(reinterpret_cast<intptr_t>(result) & (alignment - 1), 0u); | 211 DCHECK_EQ(reinterpret_cast<intptr_t>(result) & (alignment - 1), 0u); |
211 return result; | 212 return result; |
212 } | 213 } |
213 | 214 |
214 static size_t align(size_t size) | 215 static size_t align(size_t size) |
215 { | 216 { |
216 size_t alignedSize = alignment * ((size + alignment - 1) / alignment); | 217 size_t alignedSize = alignment * ((size + alignment - 1) / alignment); |
217 DCHECK_EQ(alignedSize % alignment, 0u); | 218 DCHECK_EQ(alignedSize % alignment, 0u); |
218 DCHECK_GE(alignedSize, size); | 219 DCHECK_GE(alignedSize, size); |
219 DCHECK_LT(alignedSize, size + alignment); | 220 DCHECK_LT(alignedSize, size + alignment); |
220 return alignedSize; | 221 return alignedSize; |
221 } | 222 } |
222 }; | 223 }; |
223 | 224 |
224 } // namespace blink | 225 } // namespace blink |
225 | 226 |
226 #endif // ContiguousContainer_h | 227 #endif // ContiguousContainer_h |
OLD | NEW |