summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/common/FixedVector.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/common/FixedVector.h')
-rw-r--r--gfx/angle/checkout/src/common/FixedVector.h353
1 files changed, 353 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..bff87fc969
--- /dev/null
+++ b/gfx/angle/checkout/src/common/FixedVector.h
@@ -0,0 +1,353 @@
+//
+// 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);
+
+ template <class... Args>
+ void emplace_back(Args &&... args);
+
+ 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>
+template <class... Args>
+void FixedVector<T, N, Storage>::emplace_back(Args &&... args)
+{
+ ASSERT(mSize < N);
+ new (&mStorage[mSize]) T{std::forward<Args>(args)...};
+ 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_