// // Copyright 2018 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // FastVector.h: // A vector class with a initial fixed size and variable growth. // Based on FixedVector. //
template <class T, size_t N, class Storage = std::array<T, N>> class FastVector final
{ public: using value_type = typename Storage::value_type; using size_type = typename Storage::size_type; using reference = typename Storage::reference; using const_reference = typename Storage::const_reference; using pointer = typename Storage::pointer; using const_pointer = typename Storage::const_pointer; using iterator = WrapIter<T *>; using const_iterator = WrapIter<const T *>;
FastVector<T, N, Storage> &operator=(const FastVector<T, N, Storage> &other);
FastVector<T, N, Storage> &operator=(FastVector<T, N, Storage> &&other);
FastVector<T, N, Storage> &operator=(std::initializer_list<value_type> init);
// Specialty function that removes a known element and might shuffle the list. void remove_and_permute(const value_type &element); void remove_and_permute(iterator pos);
template <class T, size_t N, class StorageN, size_t M, class StorageM> booloperator==(const FastVector<T, N, StorageN> &a, const FastVector<T, M, StorageM> &b)
{ return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
}
template <class T, size_t N, class StorageN, size_t M, class StorageM> booloperator!=(const FastVector<T, N, StorageN> &a, const FastVector<T, M, StorageM> &b)
{ return !(a == b);
}
template <class T, size_t N, class Storage>
ANGLE_INLINE bool FastVector<T, N, Storage>::uses_fixed_storage() const
{ return mData == mFixedStorage.data();
}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage>::FastVector()
{}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage>::FastVector(size_type count, const value_type &value)
{
ensure_capacity(count);
mSize = count;
std::fill(begin(), end(), value);
}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage>::FastVector(size_type count)
{
ensure_capacity(count);
mSize = count;
}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage>::FastVector(const FastVector<T, N, Storage> &other)
: FastVector(other.begin(), other.end())
{}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage>::FastVector(FastVector<T, N, Storage> &&other) : FastVector()
{
swap(other);
}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage>::FastVector(std::initializer_list<value_type> init)
{
assign_from_initializer_list(init);
}
template <class T, size_t N, class Storage> template <class InputIt, std::enable_if_t<!std::is_integral<InputIt>::value, bool>>
FastVector<T, N, Storage>::FastVector(InputIt first, InputIt last)
{
size_t newSize = last - first;
ensure_capacity(newSize);
mSize = newSize;
std::copy(first, last, begin());
}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=( const FastVector<T, N, Storage> &other)
{
ensure_capacity(other.mSize);
mSize = other.mSize;
std::copy(other.begin(), other.end(), begin()); return *this;
}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=(FastVector<T, N, Storage> &&other)
{
swap(other); return *this;
}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=(
std::initializer_list<value_type> init)
{
assign_from_initializer_list(init); return *this;
}
template <class T, size_t N, class Storage>
FastVector<T, N, Storage>::~FastVector()
{
clear(); if (!uses_fixed_storage())
{ delete[] mData;
}
}
template <class T, size_t N, class Storage> typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::at(size_type pos)
{
ASSERT(pos < mSize); return mData[pos];
}
template <class T, size_t N, class Storage> typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::at(
size_type pos) const
{
ASSERT(pos < mSize); return mData[pos];
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::operator[](
size_type pos)
{
ASSERT(pos < mSize); return mData[pos];
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference
FastVector<T, N, Storage>::operator[](size_type pos) const
{
ASSERT(pos < mSize); return mData[pos];
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::const_pointer
angle::FastVector<T, N, Storage>::data() const
{ return mData;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::pointer angle::FastVector<T, N, Storage>::data()
{ return mData;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::iterator FastVector<T, N, Storage>::begin()
{ return mData;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::const_iterator FastVector<T, N, Storage>::begin() const
{ return mData;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::iterator FastVector<T, N, Storage>::end()
{ return mData + mSize;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::const_iterator FastVector<T, N, Storage>::end() const
{ return mData + mSize;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE bool FastVector<T, N, Storage>::empty() const
{ return mSize == 0;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::size_type FastVector<T, N, Storage>::size() const
{ return mSize;
}
template <class T, size_t N, class Storage> void FastVector<T, N, Storage>::clear()
{
resize(0);
}
template <class T, size_t N, class Storage>
ANGLE_INLINE void FastVector<T, N, Storage>::push_back(const value_type &value)
{ if (mSize == mReservedSize)
ensure_capacity(mSize + 1);
mData[mSize++] = value;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE void FastVector<T, N, Storage>::push_back(value_type &&value)
{
emplace_back(std::move(value));
}
template <class T, size_t N, class Storage> template <typename... Args>
ANGLE_INLINE void FastVector<T, N, Storage>::emplace_back(Args &&...args)
{ if (mSize == mReservedSize)
ensure_capacity(mSize + 1);
mData[mSize++] = std::move(T(std::forward<Args>(args)...));
}
template <class T, size_t N, class Storage>
ANGLE_INLINE void FastVector<T, N, Storage>::pop_back()
{
ASSERT(mSize > 0);
mSize--;
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::front()
{
ASSERT(mSize > 0); return mData[0];
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::front() const
{
ASSERT(mSize > 0); return mData[0];
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::back()
{
ASSERT(mSize > 0); return mData[mSize - 1];
}
template <class T, size_t N, class Storage>
ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::back() const
{
ASSERT(mSize > 0); return mData[mSize - 1];
}
template <class T, size_t N, class Storage> void FastVector<T, N, Storage>::swap(FastVector<T, N, Storage> &other)
{
std::swap(mSize, other.mSize);
if (uses_fixed_storage() || other.uses_fixed_storage())
std::swap(mFixedStorage, other.mFixedStorage);
}
template <class T, size_t N, class Storage> void FastVector<T, N, Storage>::resize(size_type count)
{ if (count > mSize)
{
ensure_capacity(count);
}
mSize = count;
}
template <class T, size_t N, class Storage> void FastVector<T, N, Storage>::resize(size_type count, const value_type &value)
{ if (count > mSize)
{
ensure_capacity(count);
std::fill(mData + mSize, mData + count, value);
}
mSize = count;
}
template <class T, size_t N, class Storage> void FastVector<T, N, Storage>::reserve(size_type count)
{
ensure_capacity(count);
}
template <class T, size_t N, class Storage> void FastVector<T, N, Storage>::assign_from_initializer_list(std::initializer_list<value_type> init)
{
ensure_capacity(init.size());
mSize = init.size();
size_t index = 0; for (auto &value : init)
{
mData[index++] = value;
}
}
template <class T, size_t N, class Storage>
ANGLE_INLINE void FastVector<T, N, Storage>::remove_and_permute(const value_type &element)
{
size_t len = mSize - 1; for (size_t index = 0; index < len; ++index)
{ if (mData[index] == element)
{
mData[index] = std::move(mData[len]); break;
}
}
pop_back();
}
template <class T, size_t N, class Storage>
ANGLE_INLINE void FastVector<T, N, Storage>::remove_and_permute(iterator pos)
{
ASSERT(pos >= begin());
ASSERT(pos < end());
size_t len = mSize - 1;
*pos = std::move(mData[len]);
pop_back();
}
template <class T, size_t N, class Storage> void FastVector<T, N, Storage>::ensure_capacity(size_t capacity)
{ // We have a minimum capacity of N. if (mReservedSize < capacity)
{
ASSERT(capacity > N);
size_type newSize = std::max(mReservedSize, N); while (newSize < capacity)
{
newSize *= 2;
}
pointer newData = new value_type[newSize];
if (mSize > 0)
{
std::move(begin(), end(), newData);
}
if (!uses_fixed_storage())
{ delete[] mData;
}
mData = newData;
mReservedSize = newSize;
}
}
template <class Value, size_t N> class FastMap final
{ public:
FastMap() {}
~FastMap() {}
Value &operator[](uint32_t key)
{ if (mData.size() <= key)
{
mData.resize(key + 1, {});
} return mData[key];
}
template <class Key, class Value, size_t N> class FlatUnorderedMap final
{ public: using Pair = std::pair<Key, Value>; using Storage = FastVector<Pair, N>; using iterator = typename Storage::iterator; using const_iterator = typename Storage::const_iterator;
template <class T, size_t N> class FlatUnorderedSet final
{ public: using Storage = FastVector<T, N>; using iterator = typename Storage::iterator; using const_iterator = typename Storage::const_iterator;
// This is needed to accommodate the chromium style guide error - // [chromium-style] Complex constructor has an inlined body.
ANGLE_INLINE FastIntegerSet::FastIntegerSet() {}
ANGLE_INLINE FastIntegerSet::~FastIntegerSet() {}
template <typename Value> class FastIntegerMap final
{ public:
FastIntegerMap() {}
~FastIntegerMap() {}
ANGLE_INLINE void ensureCapacity(size_t size)
{ // Ensure key set has capacity
mKeySet.ensureCapacity(size);
// Ensure value vector has capacity
ensureCapacityImpl(size);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.