diff options
Diffstat (limited to 'gfx/angle/checkout/src/common/FixedVector.h')
-rw-r--r-- | gfx/angle/checkout/src/common/FixedVector.h | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/common/FixedVector.h b/gfx/angle/checkout/src/common/FixedVector.h new file mode 100644 index 0000000000..f2c4748d5d --- /dev/null +++ b/gfx/angle/checkout/src/common/FixedVector.h @@ -0,0 +1,341 @@ +// +// 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. +// +// FixedVector.h: +// A vector class with a maximum size and fixed storage. +// + +#ifndef COMMON_FIXEDVECTOR_H_ +#define COMMON_FIXEDVECTOR_H_ + +#include "common/debug.h" + +#include <algorithm> +#include <array> +#include <initializer_list> + +namespace angle +{ +template <class T, size_t N, class Storage = std::array<T, N>> +class FixedVector 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 = typename Storage::iterator; + using const_iterator = typename Storage::const_iterator; + using reverse_iterator = typename Storage::reverse_iterator; + using const_reverse_iterator = typename Storage::const_reverse_iterator; + + FixedVector(); + FixedVector(size_type count, const value_type &value); + FixedVector(size_type count); + + FixedVector(const FixedVector<T, N, Storage> &other); + FixedVector(FixedVector<T, N, Storage> &&other); + FixedVector(std::initializer_list<value_type> init); + + FixedVector<T, N, Storage> &operator=(const FixedVector<T, N, Storage> &other); + FixedVector<T, N, Storage> &operator=(FixedVector<T, N, Storage> &&other); + FixedVector<T, N, Storage> &operator=(std::initializer_list<value_type> init); + + ~FixedVector(); + + reference at(size_type pos); + const_reference at(size_type pos) const; + + reference operator[](size_type pos); + const_reference operator[](size_type pos) const; + + pointer data(); + const_pointer data() const; + + iterator begin(); + const_iterator begin() const; + + iterator end(); + const_iterator end() const; + + bool empty() const; + size_type size() const; + static constexpr size_type max_size(); + + void clear(); + + void push_back(const value_type &value); + void push_back(value_type &&value); + + void pop_back(); + reference back(); + const_reference back() const; + + void swap(FixedVector<T, N, Storage> &other); + + void resize(size_type count); + void resize(size_type count, const value_type &value); + + bool full() const; + + private: + void assign_from_initializer_list(std::initializer_list<value_type> init); + + Storage mStorage; + size_type mSize = 0; +}; + +template <class T, size_t N, class Storage> +bool operator==(const FixedVector<T, N, Storage> &a, const FixedVector<T, N, Storage> &b) +{ + return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); +} + +template <class T, size_t N, class Storage> +bool operator!=(const FixedVector<T, N, Storage> &a, const FixedVector<T, N, Storage> &b) +{ + return !(a == b); +} + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage>::FixedVector() = default; + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage>::FixedVector(size_type count, const value_type &value) : mSize(count) +{ + ASSERT(count <= N); + std::fill(mStorage.begin(), mStorage.begin() + count, value); +} + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage>::FixedVector(size_type count) : mSize(count) +{ + ASSERT(count <= N); +} + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage>::FixedVector(const FixedVector<T, N, Storage> &other) = default; + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage>::FixedVector(FixedVector<T, N, Storage> &&other) = default; + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage>::FixedVector(std::initializer_list<value_type> init) +{ + ASSERT(init.size() <= N); + assign_from_initializer_list(init); +} + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=( + const FixedVector<T, N, Storage> &other) = default; + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=( + FixedVector<T, N, Storage> &&other) = default; + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=( + std::initializer_list<value_type> init) +{ + clear(); + ASSERT(init.size() <= N); + assign_from_initializer_list(init); + return this; +} + +template <class T, size_t N, class Storage> +FixedVector<T, N, Storage>::~FixedVector() +{ + clear(); +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::at(size_type pos) +{ + ASSERT(pos < N); + return mStorage.at(pos); +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::at( + size_type pos) const +{ + ASSERT(pos < N); + return mStorage.at(pos); +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::operator[](size_type pos) +{ + ASSERT(pos < N); + return mStorage[pos]; +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::operator[]( + size_type pos) const +{ + ASSERT(pos < N); + return mStorage[pos]; +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::const_pointer angle::FixedVector<T, N, Storage>::data() const +{ + return mStorage.data(); +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::pointer angle::FixedVector<T, N, Storage>::data() +{ + return mStorage.data(); +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::iterator FixedVector<T, N, Storage>::begin() +{ + return mStorage.begin(); +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::const_iterator FixedVector<T, N, Storage>::begin() const +{ + return mStorage.begin(); +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::iterator FixedVector<T, N, Storage>::end() +{ + return mStorage.begin() + mSize; +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::const_iterator FixedVector<T, N, Storage>::end() const +{ + return mStorage.begin() + mSize; +} + +template <class T, size_t N, class Storage> +bool FixedVector<T, N, Storage>::empty() const +{ + return mSize == 0; +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::size_type FixedVector<T, N, Storage>::size() const +{ + return mSize; +} + +template <class T, size_t N, class Storage> +constexpr typename FixedVector<T, N, Storage>::size_type FixedVector<T, N, Storage>::max_size() +{ + return N; +} + +template <class T, size_t N, class Storage> +void FixedVector<T, N, Storage>::clear() +{ + resize(0); +} + +template <class T, size_t N, class Storage> +void FixedVector<T, N, Storage>::push_back(const value_type &value) +{ + ASSERT(mSize < N); + mStorage[mSize] = value; + mSize++; +} + +template <class T, size_t N, class Storage> +void FixedVector<T, N, Storage>::push_back(value_type &&value) +{ + ASSERT(mSize < N); + mStorage[mSize] = std::move(value); + mSize++; +} + +template <class T, size_t N, class Storage> +void FixedVector<T, N, Storage>::pop_back() +{ + ASSERT(mSize > 0); + mSize--; +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::back() +{ + ASSERT(mSize > 0); + return mStorage[mSize - 1]; +} + +template <class T, size_t N, class Storage> +typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::back() const +{ + ASSERT(mSize > 0); + return mStorage[mSize - 1]; +} + +template <class T, size_t N, class Storage> +void FixedVector<T, N, Storage>::swap(FixedVector<T, N, Storage> &other) +{ + std::swap(mSize, other.mSize); + std::swap(mStorage, other.mStorage); +} + +template <class T, size_t N, class Storage> +void FixedVector<T, N, Storage>::resize(size_type count) +{ + ASSERT(count <= N); + while (mSize > count) + { + mSize--; + mStorage[mSize] = value_type(); + } + while (mSize < count) + { + mStorage[mSize] = value_type(); + mSize++; + } +} + +template <class T, size_t N, class Storage> +void FixedVector<T, N, Storage>::resize(size_type count, const value_type &value) +{ + ASSERT(count <= N); + while (mSize > count) + { + mSize--; + mStorage[mSize] = value_type(); + } + while (mSize < count) + { + mStorage[mSize] = value; + mSize++; + } +} + +template <class T, size_t N, class Storage> +void FixedVector<T, N, Storage>::assign_from_initializer_list( + std::initializer_list<value_type> init) +{ + for (auto element : init) + { + mStorage[mSize] = std::move(element); + mSize++; + } +} + +template <class T, size_t N, class Storage> +bool FixedVector<T, N, Storage>::full() const +{ + return (mSize == N); +} +} // namespace angle + +#endif // COMMON_FIXEDVECTOR_H_ |