From: Puyan Lotfi Date: Tue, 28 Jul 2015 06:04:00 +0000 (+0000) Subject: Adding ADT SortedVector; client patch will follow. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=268011e5e236acc86e3bfea7167ce71d243a7362;p=oota-llvm.git Adding ADT SortedVector; client patch will follow. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243386 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst index 08cc61a187b..fbc63324c31 100644 --- a/docs/ProgrammersManual.rst +++ b/docs/ProgrammersManual.rst @@ -1314,7 +1314,8 @@ never use hash_set and unordered_set because they are generally very expensive std::multiset is useful if you're not interested in elimination of duplicates, but has all the drawbacks of :ref:`std::set `. A sorted vector (where you don't delete duplicate entries) or some other approach is almost -always better. +always better. LLVM actually offers SortedVector which does the job of a sorted +std::vector. .. _ds_map: diff --git a/include/llvm/ADT/SortedVector.h b/include/llvm/ADT/SortedVector.h new file mode 100644 index 00000000000..1fd4cfc8219 --- /dev/null +++ b/include/llvm/ADT/SortedVector.h @@ -0,0 +1,133 @@ +//===-- llvm/ADT/SortedVector.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_SORTEDVECTOR_H +#define LLVM_ADT_SORTEDVECTOR_H + +#include +#include +#include +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +/// \brief Lazily maintains a sorted and unique vector of elements of type T. +template> +class SortedVector { +public: + typedef typename std::vector VectorType; + typedef typename VectorType::iterator iterator; + typedef typename VectorType::const_iterator const_iterator; + +private: + VectorType Vector; + bool IsSorted = true; + + void doCheck() const { + assert(IsSorted && "Unsorted SortedVector access; call sortUnique prior."); + } + +public: + /// \brief Appends Entry to the sorted unique vector; sets the IsSorted flag + /// to false if appending Entry puts Vector into an unsorted state. + void insert(const T &Entry) { + if (!Vector.size()) + Vector.push_back(Entry); + + // Vector is sorted and Entry is a duplicate of the previous so skip. + if (IsSorted && Entry == Vector.back()) + return; + + IsSorted &= (CMP()(Vector.back(), Entry)); + Vector.push_back(Entry); + } + + // \brief Sorts and uniques Vector. + void sortUnique() { + if (IsSorted) + return; + + std::sort(Vector.begin(), Vector.end()); + Vector.erase(std::unique(Vector.begin(), Vector.end()), Vector.end()); + IsSorted = true; + } + + /// \brief Tells if Entry is in Vector without relying on sorted-uniqueness. + bool has(T Entry) const { + if (IsSorted) + return std::binary_search(Vector.begin(), Vector.end(), Entry); + + return std::find(Vector.begin(), Vector.end(), Entry) != Vector.end(); + } + + /// \brief Returns a reference to the entry with the specified index. + const T &operator[](unsigned index) const { + assert(index < size() && "SortedVector index is out of range!"); + doCheck(); + return Vector[index]; + } + + /// \brief Return an iterator to the start of the vector. + iterator begin() { + doCheck(); + return Vector.begin(); + } + + /// \brief Returns const iterator to the start of the vector. + const_iterator begin() const { + doCheck(); + return Vector.begin(); + } + + /// \brief Returns iterator to the end of Vector. + iterator end() { + doCheck(); + return Vector.end(); + } + + /// \brief Returns const iterator to the end of Vector. Assert if unsorted. + const_iterator end() const { + doCheck(); + return Vector.end(); + } + + /// \brief Erases Vector at position. Asserts if Vector is unsorted. + iterator erase(iterator position) { + doCheck(); + return Vector.erase(position); + } + + /// \brief Erases Vector entirely. + iterator erase() { + IsSorted = true; + return Vector.erase(); + } + + /// \brief Returns number of entries in Vector; asserts if it is unsorted. + size_t size() const { + doCheck(); + return Vector.size(); + } + + /// \brief Returns true if Vector is empty. + bool empty() const { + return Vector.empty(); + } + + /// \brief Clears all the entries. + void reset() { + IsSorted = true; + Vector.resize(0, 0); + } +}; + +} // End of namespace llvm + +#endif // LLVM_ADT_SORTEDVECTOR_H +