10#ifdef JPH_USE_STD_VECTOR
18template <
class T,
class Allocator = STLAllocator<T>>
using Array = std::vector<T, Allocator>;
34template <
class T,
class Allocator = STLAllocator<T>>
35class [[nodiscard]]
Array :
private Allocator
52 if constexpr (std::is_trivially_copyable<T>())
53 memmove(inDestination, inSource, inCount *
sizeof(T));
56 if (inDestination < inSource)
58 for (T *destination_end = inDestination + inCount; inDestination < destination_end; ++inDestination, ++inSource)
60 ::new (inDestination) T(std::move(*inSource));
66 for (T *destination = inDestination + inCount - 1, *source = inSource + inCount - 1; destination >= inDestination; --destination, --source)
68 ::new (destination) T(std::move(*source));
76 inline void reallocate(size_type inNewCapacity)
78 JPH_ASSERT(inNewCapacity > 0 && inNewCapacity >= mSize);
84 pointer = get_allocator().reallocate(mElements, mCapacity, inNewCapacity);
89 pointer = get_allocator().allocate(inNewCapacity);
90 if (mElements !=
nullptr)
92 move(pointer, mElements, mSize);
93 get_allocator().deallocate(mElements, mCapacity);
97 mCapacity = inNewCapacity;
101 inline void destruct(size_type inStart, size_type inEnd)
103 if constexpr (!is_trivially_destructible<T>())
105 for (T *element = mElements + inStart, *element_end = mElements + inEnd; element < element_end; ++element)
113 if (mCapacity < inNewSize)
114 reallocate(inNewSize);
120 destruct(inNewSize, mSize);
123 if constexpr (!is_trivially_constructible<T>())
124 for (T *element = mElements + mSize, *element_end = mElements + inNewSize; element < element_end; ++element)
132 JPH_ASSERT(&inValue < mElements || &inValue >= mElements + mSize,
"Can't pass an element from the array to resize");
134 destruct(inNewSize, mSize);
137 for (T *element = mElements + mSize, *element_end = mElements + inNewSize; element < element_end; ++element)
138 ::new (element) T(inValue);
151 inline void grow(size_type inAmount = 1)
153 size_type min_size = mSize + inAmount;
154 if (min_size > mCapacity)
156 size_type new_capacity = max(min_size, mCapacity * 2);
157 reserve(new_capacity);
164 get_allocator().deallocate(mElements, mCapacity);
170 inline void destroy()
172 if (mElements !=
nullptr)
181 template <
class Iterator>
182 inline void assign(Iterator inBegin, Iterator inEnd)
185 reserve(
size_type(std::distance(inBegin, inEnd)));
187 for (Iterator element = inBegin; element != inEnd; ++element)
188 ::new (&mElements[mSize++]) T(*element);
192 inline void assign(std::initializer_list<T> inList)
197 for (
const T &v : inList)
198 ::new (&mElements[mSize++]) T(v);
205 explicit inline Array(
const Allocator &inAllocator) :
206 Allocator(inAllocator)
212 Allocator(inAllocator)
218 inline Array(
size_type inLength,
const T &inValue,
const Allocator &inAllocator = { }) :
219 Allocator(inAllocator)
221 resize(inLength, inValue);
225 inline Array(std::initializer_list<T> inList,
const Allocator &inAllocator = { }) :
226 Allocator(inAllocator)
233 Allocator(inAllocator)
235 assign(inBegin, inEnd);
240 Allocator(inRHS.get_allocator())
247 Allocator(std::move(inRHS.get_allocator())),
249 mCapacity(inRHS.mCapacity),
250 mElements(inRHS.mElements)
254 inRHS.mElements =
nullptr;
277 JPH_ASSERT(&inValue < mElements || &inValue >= mElements + mSize,
"Can't pass an element from the array to push_back");
281 T *element = mElements + mSize++;
282 ::new (element) T(inValue);
289 T *element = mElements + mSize++;
290 ::new (element) T(std::move(inValue));
294 template <
class... A>
299 T *element = mElements + mSize++;
300 ::new (element) T(std::forward<A>(inValue)...);
308 mElements[--mSize].~T();
332 if (mElements !=
nullptr)
336 else if (mCapacity > mSize)
344 std::swap(get_allocator(), inRHS.get_allocator());
345 std::swap(mSize, inRHS.mSize);
346 std::swap(mCapacity, inRHS.mCapacity);
347 std::swap(mElements, inRHS.mElements);
350 template <
class Iterator>
354 if (num_elements > 0)
357 size_type first_element = inPos - mElements;
361 T *element_begin = mElements + first_element;
362 T *element_end = element_begin + num_elements;
363 move(element_end, element_begin, mSize - first_element);
365 for (T *element = element_begin; element < element_end; ++element, ++inBegin)
366 ::new (element) T(*inBegin);
368 mSize += num_elements;
374 JPH_ASSERT(&inValue < mElements || &inValue >= mElements + mSize,
"Can't pass an element from the array to insert");
377 size_type first_element = inPos - mElements;
381 T *element = mElements + first_element;
382 move(element + 1, element, mSize - first_element);
384 ::new (element) T(inValue);
395 move(mElements + p, mElements + p + 1, mSize - p - 1);
407 move(mElements + p, mElements + p + n, mSize - p - n);
419 return mElements + mSize;
429 return mElements + mSize;
439 return mElements + mSize;
456 return mElements[inIdx];
462 return mElements[inIdx];
469 return mElements[inIdx];
475 return mElements[inIdx];
495 return mElements[mSize - 1];
501 return mElements[mSize - 1];
507 if (
static_cast<const void *
>(
this) !=
static_cast<const void *
>(&inRHS))
516 if (
static_cast<const void *
>(
this) !=
static_cast<const void *
>(&inRHS))
520 get_allocator() = std::move(inRHS.get_allocator());
523 mCapacity = inRHS.mCapacity;
524 mElements = inRHS.mElements;
528 inRHS.mElements =
nullptr;
545 if (mSize != inRHS.mSize)
548 if (!(mElements[i] == inRHS.mElements[i]))
555 if (mSize != inRHS.mSize)
558 if (mElements[i] != inRHS.mElements[i])
565 size_type mCapacity = 0;
566 T * mElements =
nullptr;
571JPH_SUPPRESS_WARNING_PUSH
577 template <
class T,
class Allocator>
578 struct hash<JPH::
Array<T, Allocator>>
580 size_t operator () (
const JPH::Array<T, Allocator> &inRHS)
const
585 JPH::HashCombine(ret, inRHS.size());
588 for (
const T &t : inRHS)
589 JPH::HashCombine(ret, t);
596JPH_SUPPRESS_WARNING_POP
#define JPH_SUPPRESS_WARNINGS_STD_BEGIN
Definition: Core.h:383
#define JPH_SUPPRESS_WARNINGS_STD_END
Definition: Core.h:395
#define JPH_NAMESPACE_END
Definition: Core.h:378
#define JPH_CLANG_SUPPRESS_WARNING(w)
Definition: Core.h:263
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
#define JPH_ASSERT(...)
Definition: IssueReporting.h:33
void resize(size_type inNewSize)
Resize array to new length.
Definition: Array.h:118
Array()=default
Default constructor.
void push_back(T &&inValue)
Definition: Array.h:285
void pop_back()
Remove element from the back of the array.
Definition: Array.h:305
bool empty() const
Returns true if there are no elements in the array.
Definition: Array.h:312
size_type capacity() const
Returns maximum amount of elements the array can hold.
Definition: Array.h:324
Array(const Allocator &inAllocator)
Constructor with allocator.
Definition: Array.h:205
size_t size_type
Definition: Array.h:39
~Array()
Destruct all elements.
Definition: Array.h:258
const T & back() const
Last element in the array.
Definition: Array.h:492
const T * const_iterator
Definition: Array.h:45
T * data()
Definition: Array.h:447
const_iterator begin() const
Iterators.
Definition: Array.h:412
const_iterator cbegin() const
Definition: Array.h:422
void insert(const_iterator inPos, Iterator inBegin, Iterator inEnd)
Definition: Array.h:351
iterator end()
Definition: Array.h:437
void erase(const_iterator inBegin, const_iterator inEnd)
Remove multiple element from the array.
Definition: Array.h:400
void resize(size_type inNewSize, const T &inValue)
Resize array to new length and initialize all elements with inValue.
Definition: Array.h:130
iterator begin()
Definition: Array.h:432
const T * const_pointer
Definition: Array.h:41
void swap(Array< T, Allocator > &inRHS) noexcept
Swap the contents of two arrays.
Definition: Array.h:342
Array(size_type inLength, const T &inValue, const Allocator &inAllocator={ })
Constructor with length and value.
Definition: Array.h:218
const T * data() const
Definition: Array.h:442
Array(std::initializer_list< T > inList, const Allocator &inAllocator={ })
Constructor from initializer list.
Definition: Array.h:225
size_type size() const
Returns amount of elements in the array.
Definition: Array.h:318
Array(Array< T, Allocator > &&inRHS) noexcept
Move constructor.
Definition: Array.h:246
void shrink_to_fit()
Reduce the capacity of the array to match its size.
Definition: Array.h:330
void clear()
Destruct all elements and set length to zero.
Definition: Array.h:143
const_iterator cend() const
Definition: Array.h:427
const Allocator & get_allocator() const
Definition: Array.h:269
T & emplace_back(A &&... inValue)
Construct element at the back of the array.
Definition: Array.h:295
T * pointer
Definition: Array.h:40
T * iterator
Definition: Array.h:46
Array(size_type inLength, const Allocator &inAllocator={ })
Constructor with length.
Definition: Array.h:211
void push_back(const T &inValue)
Add element to the back of the array.
Definition: Array.h:275
void insert(const_iterator inPos, const T &inValue)
Definition: Array.h:372
T & back()
Definition: Array.h:498
const T & const_reference
Definition: Array.h:43
T & at(size_type inIdx)
Access element.
Definition: Array.h:466
const T & front() const
First element in the array.
Definition: Array.h:479
void reserve(size_type inNewSize)
Reserve array space.
Definition: Array.h:111
void assign(Iterator inBegin, Iterator inEnd)
Replace the contents of this array with inBegin .. inEnd.
Definition: Array.h:182
T value_type
Definition: Array.h:38
Allocator & get_allocator()
Get the allocator.
Definition: Array.h:264
void erase(const_iterator inIter)
Remove one element from the array.
Definition: Array.h:389
const_iterator end() const
Definition: Array.h:417
T & front()
Definition: Array.h:485
T & reference
Definition: Array.h:42
const T & at(size_type inIdx) const
Definition: Array.h:472
Array(const_iterator inBegin, const_iterator inEnd, const Allocator &inAllocator={ })
Constructor from iterator.
Definition: Array.h:232
void assign(std::initializer_list< T > inList)
Replace the contents of this array with inList.
Definition: Array.h:192
Array(const Array< T, Allocator > &inRHS)
Copy constructor.
Definition: Array.h:239
Default implementation of AllocatorHasReallocate which tells if an allocator has a reallocate functio...
Definition: STLAllocator.h:10