LLVM API Documentation
00001 //===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements a set that has insertion order iteration 00011 // characteristics. This is useful for keeping a set of things that need to be 00012 // visited later but in a deterministic order (insertion order). The interface 00013 // is purposefully minimal. 00014 // 00015 // This file defines SetVector and SmallSetVector, which performs no allocations 00016 // if the SetVector has less than a certain number of elements. 00017 // 00018 //===----------------------------------------------------------------------===// 00019 00020 #ifndef LLVM_ADT_SETVECTOR_H 00021 #define LLVM_ADT_SETVECTOR_H 00022 00023 #include "llvm/ADT/SmallSet.h" 00024 #include <vector> 00025 #include <cassert> 00026 #include <algorithm> 00027 00028 namespace llvm { 00029 00030 /// This adapter class provides a way to keep a set of things that also has the 00031 /// property of a deterministic iteration order. The order of iteration is the 00032 /// order of insertion. 00033 /// @brief A vector that has set insertion semantics. 00034 template <typename T, typename Vector = std::vector<T>, 00035 typename Set = SmallSet<T, 16> > 00036 class SetVector { 00037 public: 00038 typedef T value_type; 00039 typedef T key_type; 00040 typedef T& reference; 00041 typedef const T& const_reference; 00042 typedef Set set_type; 00043 typedef Vector vector_type; 00044 typedef typename vector_type::const_iterator iterator; 00045 typedef typename vector_type::const_iterator const_iterator; 00046 typedef typename vector_type::size_type size_type; 00047 00048 /// @brief Construct an empty SetVector 00049 SetVector() {} 00050 00051 /// @brief Initialize a SetVector with a range of elements 00052 template<typename It> 00053 SetVector(It Start, It End) { 00054 insert(Start, End); 00055 } 00056 00057 /// @brief Determine if the SetVector is empty or not. 00058 bool empty() const { 00059 return vector_.empty(); 00060 } 00061 00062 /// @brief Determine the number of elements in the SetVector. 00063 size_type size() const { 00064 return vector_.size(); 00065 } 00066 00067 /// @brief Get an iterator to the beginning of the SetVector. 00068 iterator begin() { 00069 return vector_.begin(); 00070 } 00071 00072 /// @brief Get a const_iterator to the beginning of the SetVector. 00073 const_iterator begin() const { 00074 return vector_.begin(); 00075 } 00076 00077 /// @brief Get an iterator to the end of the SetVector. 00078 iterator end() { 00079 return vector_.end(); 00080 } 00081 00082 /// @brief Get a const_iterator to the end of the SetVector. 00083 const_iterator end() const { 00084 return vector_.end(); 00085 } 00086 00087 /// @brief Return the last element of the SetVector. 00088 const T &back() const { 00089 assert(!empty() && "Cannot call back() on empty SetVector!"); 00090 return vector_.back(); 00091 } 00092 00093 /// @brief Index into the SetVector. 00094 const_reference operator[](size_type n) const { 00095 assert(n < vector_.size() && "SetVector access out of range!"); 00096 return vector_[n]; 00097 } 00098 00099 /// @returns true iff the element was inserted into the SetVector. 00100 /// @brief Insert a new element into the SetVector. 00101 bool insert(const value_type &X) { 00102 bool result = set_.insert(X); 00103 if (result) 00104 vector_.push_back(X); 00105 return result; 00106 } 00107 00108 /// @brief Insert a range of elements into the SetVector. 00109 template<typename It> 00110 void insert(It Start, It End) { 00111 for (; Start != End; ++Start) 00112 if (set_.insert(*Start)) 00113 vector_.push_back(*Start); 00114 } 00115 00116 /// @brief Remove an item from the set vector. 00117 void remove(const value_type& X) { 00118 if (set_.erase(X)) { 00119 typename vector_type::iterator I = 00120 std::find(vector_.begin(), vector_.end(), X); 00121 assert(I != vector_.end() && "Corrupted SetVector instances!"); 00122 vector_.erase(I); 00123 } 00124 } 00125 00126 00127 /// @returns 0 if the element is not in the SetVector, 1 if it is. 00128 /// @brief Count the number of elements of a given key in the SetVector. 00129 size_type count(const key_type &key) const { 00130 return set_.count(key); 00131 } 00132 00133 /// @brief Completely clear the SetVector 00134 void clear() { 00135 set_.clear(); 00136 vector_.clear(); 00137 } 00138 00139 /// @brief Remove the last element of the SetVector. 00140 void pop_back() { 00141 assert(!empty() && "Cannot remove an element from an empty SetVector!"); 00142 set_.erase(back()); 00143 vector_.pop_back(); 00144 } 00145 00146 private: 00147 set_type set_; ///< The set. 00148 vector_type vector_; ///< The vector. 00149 }; 00150 00151 /// SmallSetVector - A SetVector that performs no allocations if smaller than 00152 /// a certain size. 00153 template <typename T, unsigned N> 00154 class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > { 00155 public: 00156 SmallSetVector() {} 00157 00158 /// @brief Initialize a SmallSetVector with a range of elements 00159 template<typename It> 00160 SmallSetVector(It Start, It End) { 00161 this->insert(Start, End); 00162 } 00163 }; 00164 00165 } // End llvm namespace 00166 00167 // vim: sw=2 ai 00168 #endif