/* * Copyright 2014 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrOrderedSet_DEFINED #define GrOrderedSet_DEFINED #include "GrRedBlackTree.h" template <typename T, typename C = GrLess<T> > class GrOrderedSet : SkNoncopyable { public: /** * Creates an empty set */ GrOrderedSet() : fComp() {} ~GrOrderedSet() {} class Iter; /** * @return true if there are no items in the set, false otherwise. */ bool empty() const { return fRBTree.empty(); } /** * @return the number of items in the set. */ int count() const { return fRBTree.count(); } /** * Removes all items in the set */ void reset() { fRBTree.reset(); } /** * Adds an element to set if it does not already exists in the set. * @param t the item to add * @return an iterator to added element or matching element already in set */ Iter insert(const T& t); /** * Removes the item indicated by an iterator. The iterator will not be valid * afterwards. * @param iter iterator of item to remove. Must be valid (not end()). */ void remove(const Iter& iter); /** * @return an iterator to the first item in sorted order, or end() if empty */ Iter begin(); /** * Gets the last valid iterator. This is always valid, even on an empty. * However, it can never be dereferenced. Useful as a loop terminator. * @return an iterator that is just beyond the last item in sorted order. */ Iter end(); /** * @return an iterator that to the last item in sorted order, or end() if * empty. */ Iter last(); /** * Finds an occurrence of an item. * @param t the item to find. * @return an iterator to a set element equal to t or end() if none exists. */ Iter find(const T& t); private: GrRedBlackTree<T, C> fRBTree; const C fComp; }; template <typename T, typename C> class GrOrderedSet<T,C>::Iter { public: Iter() {} Iter(const Iter& i) { fTreeIter = i.fTreeIter; } Iter& operator =(const Iter& i) { fTreeIter = i.fTreeIter; return *this; } const T& operator *() const { return *fTreeIter; } bool operator ==(const Iter& i) const { return fTreeIter == i.fTreeIter; } bool operator !=(const Iter& i) const { return !(*this == i); } Iter& operator ++() { ++fTreeIter; return *this; } Iter& operator --() { --fTreeIter; return *this; } const typename GrRedBlackTree<T,C>::Iter& getTreeIter() const { return fTreeIter; } private: friend class GrOrderedSet; explicit Iter(typename GrRedBlackTree<T, C>::Iter iter) { fTreeIter = iter; } typename GrRedBlackTree<T,C>::Iter fTreeIter; }; template <typename T, typename C> typename GrOrderedSet<T,C>::Iter GrOrderedSet<T,C>::begin() { return Iter(fRBTree.begin()); } template <typename T, typename C> typename GrOrderedSet<T,C>::Iter GrOrderedSet<T,C>::end() { return Iter(fRBTree.end()); } template <typename T, typename C> typename GrOrderedSet<T,C>::Iter GrOrderedSet<T,C>::last() { return Iter(fRBTree.last()); } template <typename T, typename C> typename GrOrderedSet<T,C>::Iter GrOrderedSet<T,C>::find(const T& t) { return Iter(fRBTree.find(t)); } template <typename T, typename C> typename GrOrderedSet<T,C>::Iter GrOrderedSet<T,C>::insert(const T& t) { if (fRBTree.find(t) == fRBTree.end()) { return Iter(fRBTree.insert(t)); } else { return Iter(fRBTree.find(t)); } } template <typename T, typename C> void GrOrderedSet<T,C>::remove(const typename GrOrderedSet<T,C>::Iter& iter) { if (this->end() != iter) { fRBTree.remove(iter.getTreeIter()); } } #endif