// // 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 #include #include namespace angle { template > 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 &other); FixedVector(FixedVector &&other); FixedVector(std::initializer_list init); FixedVector &operator=(const FixedVector &other); FixedVector &operator=(FixedVector &&other); FixedVector &operator=(std::initializer_list 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); template void emplace_back(Args &&... args); void pop_back(); reference back(); const_reference back() const; void swap(FixedVector &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 init); Storage mStorage; size_type mSize = 0; }; template bool operator==(const FixedVector &a, const FixedVector &b) { return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); } template bool operator!=(const FixedVector &a, const FixedVector &b) { return !(a == b); } template FixedVector::FixedVector() = default; template FixedVector::FixedVector(size_type count, const value_type &value) : mSize(count) { ASSERT(count <= N); std::fill(mStorage.begin(), mStorage.begin() + count, value); } template FixedVector::FixedVector(size_type count) : mSize(count) { ASSERT(count <= N); } template FixedVector::FixedVector(const FixedVector &other) = default; template FixedVector::FixedVector(FixedVector &&other) = default; template FixedVector::FixedVector(std::initializer_list init) { ASSERT(init.size() <= N); assign_from_initializer_list(init); } template FixedVector &FixedVector::operator=( const FixedVector &other) = default; template FixedVector &FixedVector::operator=( FixedVector &&other) = default; template FixedVector &FixedVector::operator=( std::initializer_list init) { clear(); ASSERT(init.size() <= N); assign_from_initializer_list(init); return this; } template FixedVector::~FixedVector() { clear(); } template typename FixedVector::reference FixedVector::at(size_type pos) { ASSERT(pos < N); return mStorage.at(pos); } template typename FixedVector::const_reference FixedVector::at( size_type pos) const { ASSERT(pos < N); return mStorage.at(pos); } template typename FixedVector::reference FixedVector::operator[](size_type pos) { ASSERT(pos < N); return mStorage[pos]; } template typename FixedVector::const_reference FixedVector::operator[]( size_type pos) const { ASSERT(pos < N); return mStorage[pos]; } template typename FixedVector::const_pointer angle::FixedVector::data() const { return mStorage.data(); } template typename FixedVector::pointer angle::FixedVector::data() { return mStorage.data(); } template typename FixedVector::iterator FixedVector::begin() { return mStorage.begin(); } template typename FixedVector::const_iterator FixedVector::begin() const { return mStorage.begin(); } template typename FixedVector::iterator FixedVector::end() { return mStorage.begin() + mSize; } template typename FixedVector::const_iterator FixedVector::end() const { return mStorage.begin() + mSize; } template bool FixedVector::empty() const { return mSize == 0; } template typename FixedVector::size_type FixedVector::size() const { return mSize; } template constexpr typename FixedVector::size_type FixedVector::max_size() { return N; } template void FixedVector::clear() { resize(0); } template void FixedVector::push_back(const value_type &value) { ASSERT(mSize < N); mStorage[mSize] = value; mSize++; } template void FixedVector::push_back(value_type &&value) { ASSERT(mSize < N); mStorage[mSize] = std::move(value); mSize++; } template template void FixedVector::emplace_back(Args &&... args) { ASSERT(mSize < N); new (&mStorage[mSize]) T{std::forward(args)...}; mSize++; } template void FixedVector::pop_back() { ASSERT(mSize > 0); mSize--; } template typename FixedVector::reference FixedVector::back() { ASSERT(mSize > 0); return mStorage[mSize - 1]; } template typename FixedVector::const_reference FixedVector::back() const { ASSERT(mSize > 0); return mStorage[mSize - 1]; } template void FixedVector::swap(FixedVector &other) { std::swap(mSize, other.mSize); std::swap(mStorage, other.mStorage); } template void FixedVector::resize(size_type count) { ASSERT(count <= N); while (mSize > count) { mSize--; mStorage[mSize] = value_type(); } while (mSize < count) { mStorage[mSize] = value_type(); mSize++; } } template void FixedVector::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 void FixedVector::assign_from_initializer_list( std::initializer_list init) { for (auto element : init) { mStorage[mSize] = std::move(element); mSize++; } } template bool FixedVector::full() const { return (mSize == N); } } // namespace angle #endif // COMMON_FIXEDVECTOR_H_