// Copyright 2021 The Tint Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SRC_UTILS_UNIQUE_VECTOR_H_ #define SRC_UTILS_UNIQUE_VECTOR_H_ #include #include namespace tint { namespace utils { /// UniqueVector is an ordered container that only contains unique items. /// Attempting to add a duplicate is a no-op. template > struct UniqueVector { /// The iterator returned by begin() and end() using ConstIterator = typename std::vector::const_iterator; /// Constructor UniqueVector() = default; /// Constructor /// @param v the vector to construct this UniqueVector with. Duplicate /// elements will be removed. explicit UniqueVector(std::vector&& v) { for (auto& el : v) { add(el); } } /// add appends the item to the end of the vector, if the vector does not /// already contain the given item. /// @param item the item to append to the end of the vector void add(const T& item) { if (set.count(item) == 0) { vector.emplace_back(item); set.emplace(item); } } /// @returns true if the vector contains `item` /// @param item the item bool contains(const T& item) const { return set.count(item); } /// @param i the index of the element to retrieve /// @returns the element at the index `i` T& operator[](size_t i) { return vector[i]; } /// @param i the index of the element to retrieve /// @returns the element at the index `i` const T& operator[](size_t i) const { return vector[i]; } /// @returns the number of items in the vector size_t size() const { return vector.size(); } /// @returns an iterator to the beginning of the vector ConstIterator begin() const { return vector.begin(); } /// @returns an iterator to the end of the vector ConstIterator end() const { return vector.end(); } /// @returns a const reference to the internal vector operator const std::vector &() const { return vector; } private: std::vector vector; std::unordered_set set; }; } // namespace utils } // namespace tint #endif // SRC_UTILS_UNIQUE_VECTOR_H_