/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/ThirdParty/Jolt/Core/StaticArray.h
325 строк
7 KB
Jan Krassnigg
Updated Jolt (#1965)
16 июн 2026, 10:48
Не верифицирован
16 июн 2026, 10:48
2c0d62b
Код
Авторство
О чём код?
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics) // SPDX-FileCopyrightText: 2021 Jorrit Rouwe // SPDX-License-Identifier: MIT #pragma once #include <Jolt/Core/HashCombine.h> JPH_NAMESPACE_BEGIN /// Simple variable length array backed by a fixed size buffer template <class T, uint N> class [[nodiscard]] StaticArray { public: using value_type = T; using size_type = uint; static constexpr uint Capacity = N; /// Default constructor StaticArray() { /* We specifically don't want to initialize the union */ } /// Constructor from initializer list explicit StaticArray(std::initializer_list<T> inList) { JPH_ASSERT(inList.size() <= N); for (const T &v : inList) new (reinterpret_cast<T *>(&mElements[mSize++])) T(v); } /// Copy constructor StaticArray(const StaticArray<T, N> &inRHS) { while (mSize < inRHS.mSize) { new (&mElements[mSize]) T(inRHS[mSize]); ++mSize; } } /// Destruct all elements ~StaticArray() { if constexpr (!std::is_trivially_destructible<T>()) for (T *e = reinterpret_cast<T *>(mElements), *end = e + mSize; e < end; ++e) e->~T(); } /// Destruct all elements and set length to zero void clear() { if constexpr (!std::is_trivially_destructible<T>()) for (T *e = reinterpret_cast<T *>(mElements), *end = e + mSize; e < end; ++e) e->~T(); mSize = 0; } /// Add element to the back of the array void push_back(const T &inElement) { JPH_ASSERT(mSize < N); new (&mElements[mSize++]) T(inElement); } /// Construct element at the back of the array template <class... A> void emplace_back(A &&... inElement) { JPH_ASSERT(mSize < N); new (&mElements[mSize++]) T(std::forward<A>(inElement)...); } /// Remove element from the back of the array void pop_back() { JPH_ASSERT(mSize > 0); reinterpret_cast<T &>(mElements[--mSize]).~T(); } /// Returns true if there are no elements in the array bool empty() const { return mSize == 0; } /// Returns amount of elements in the array size_type size() const { return mSize; } /// Returns maximum amount of elements the array can hold size_type capacity() const { return N; } /// Resize array to new length void resize(size_type inNewSize) { JPH_ASSERT(inNewSize <= N); if constexpr (!std::is_trivially_constructible<T>()) for (T *element = reinterpret_cast<T *>(mElements) + mSize, *element_end = reinterpret_cast<T *>(mElements) + inNewSize; element < element_end; ++element) new (element) T; if constexpr (!std::is_trivially_destructible<T>()) for (T *element = reinterpret_cast<T *>(mElements) + inNewSize, *element_end = reinterpret_cast<T *>(mElements) + mSize; element < element_end; ++element) element->~T(); mSize = inNewSize; } using const_iterator = const T *; /// Iterators const_iterator begin() const { return reinterpret_cast<const T *>(mElements); } const_iterator end() const { return reinterpret_cast<const T *>(mElements + mSize); } using iterator = T *; iterator begin() { return reinterpret_cast<T *>(mElements); } iterator end() { return reinterpret_cast<T *>(mElements + mSize); } const T * data() const { return reinterpret_cast<const T *>(mElements); } T * data() { return reinterpret_cast<T *>(mElements); } /// Access element T & operator [] (size_type inIdx) { JPH_ASSERT(inIdx < mSize); return reinterpret_cast<T &>(mElements[inIdx]); } const T & operator [] (size_type inIdx) const { JPH_ASSERT(inIdx < mSize); return reinterpret_cast<const T &>(mElements[inIdx]); } /// Access element T & at(size_type inIdx) { JPH_ASSERT(inIdx < mSize); return reinterpret_cast<T &>(mElements[inIdx]); } const T & at(size_type inIdx) const { JPH_ASSERT(inIdx < mSize); return reinterpret_cast<const T &>(mElements[inIdx]); } /// First element in the array const T & front() const { JPH_ASSERT(mSize > 0); return reinterpret_cast<const T &>(mElements[0]); } T & front() { JPH_ASSERT(mSize > 0); return reinterpret_cast<T &>(mElements[0]); } /// Last element in the array const T & back() const { JPH_ASSERT(mSize > 0); return reinterpret_cast<const T &>(mElements[mSize - 1]); } T & back() { JPH_ASSERT(mSize > 0); return reinterpret_cast<T &>(mElements[mSize - 1]); } /// Remove one element from the array void erase(const_iterator inIter) { size_type p = size_type(inIter - begin()); JPH_ASSERT(p < mSize); reinterpret_cast<T &>(mElements[p]).~T(); if (p + 1 < mSize) memmove(mElements + p, mElements + p + 1, (mSize - p - 1) * sizeof(T)); --mSize; } /// Remove multiple element from the array void erase(const_iterator inBegin, const_iterator inEnd) { size_type p = size_type(inBegin - begin()); size_type n = size_type(inEnd - inBegin); JPH_ASSERT(inEnd <= end()); for (size_type i = 0; i < n; ++i) reinterpret_cast<T &>(mElements[p + i]).~T(); if (p + n < mSize) memmove(mElements + p, mElements + p + n, (mSize - p - n) * sizeof(T)); mSize -= n; } /// Assignment operator StaticArray<T, N> & operator = (const StaticArray<T, N> &inRHS) { size_type rhs_size = inRHS.size(); if (static_cast<const void *>(this) != static_cast<const void *>(&inRHS)) { clear(); while (mSize < rhs_size) { new (&mElements[mSize]) T(inRHS[mSize]); ++mSize; } } return *this; } /// Assignment operator with static array of different max length template <uint M> StaticArray<T, N> & operator = (const StaticArray<T, M> &inRHS) { size_type rhs_size = inRHS.size(); JPH_ASSERT(rhs_size <= N); if (static_cast<const void *>(this) != static_cast<const void *>(&inRHS)) { clear(); while (mSize < rhs_size) { new (&mElements[mSize]) T(inRHS[mSize]); ++mSize; } } return *this; } /// Comparing arrays bool operator == (const StaticArray<T, N> &inRHS) const { if (mSize != inRHS.mSize) return false; for (size_type i = 0; i < mSize; ++i) if (!(reinterpret_cast<const T &>(mElements[i]) == reinterpret_cast<const T &>(inRHS.mElements[i]))) return false; return true; } bool operator != (const StaticArray<T, N> &inRHS) const { if (mSize != inRHS.mSize) return true; for (size_type i = 0; i < mSize; ++i) if (reinterpret_cast<const T &>(mElements[i]) != reinterpret_cast<const T &>(inRHS.mElements[i])) return true; return false; } /// Get hash for this array uint64 GetHash() const { // Hash length first uint64 ret = Hash<uint32> { } (uint32(size())); // Then hash elements for (const T *element = reinterpret_cast<const T *>(mElements), *element_end = reinterpret_cast<const T *>(mElements) + mSize; element < element_end; ++element) HashCombine(ret, *element); return ret; } protected: size_type mSize = 0; union // Prevent constructors from being called for mElements { T mElements[N]; uint8 mDummy; }; }; JPH_NAMESPACE_END JPH_SUPPRESS_WARNING_PUSH JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat") namespace std { /// Declare std::hash for StaticArray template <class T, JPH::uint N> struct hash<JPH::StaticArray<T, N>> { size_t operator () (const JPH::StaticArray<T, N> &inRHS) const { return std::size_t(inRHS.GetHash()); } }; } JPH_SUPPRESS_WARNING_POP