1 //===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains some templates that are useful if you are working with the 11 // STL at all. 12 // 13 // No library is required when using these functions. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_ADT_STLEXTRAS_H 18 #define LLVM_ADT_STLEXTRAS_H 19 20 #include <cstddef> // for std::size_t 21 #include <cstdlib> // for qsort 22 #include <functional> 23 #include <iterator> 24 #include <utility> // for std::pair 25 26 namespace llvm { 27 28 //===----------------------------------------------------------------------===// 29 // Extra additions to <functional> 30 //===----------------------------------------------------------------------===// 31 32 template<class Ty> 33 struct identity : public std::unary_function<Ty, Ty> { 34 Ty &operator()(Ty &self) const { 35 return self; 36 } 37 const Ty &operator()(const Ty &self) const { 38 return self; 39 } 40 }; 41 42 template<class Ty> 43 struct less_ptr : public std::binary_function<Ty, Ty, bool> { 44 bool operator()(const Ty* left, const Ty* right) const { 45 return *left < *right; 46 } 47 }; 48 49 template<class Ty> 50 struct greater_ptr : public std::binary_function<Ty, Ty, bool> { 51 bool operator()(const Ty* left, const Ty* right) const { 52 return *right < *left; 53 } 54 }; 55 56 // deleter - Very very very simple method that is used to invoke operator 57 // delete on something. It is used like this: 58 // 59 // for_each(V.begin(), B.end(), deleter<Interval>); 60 // 61 template <class T> 62 inline void deleter(T *Ptr) { 63 delete Ptr; 64 } 65 66 67 68 //===----------------------------------------------------------------------===// 69 // Extra additions to <iterator> 70 //===----------------------------------------------------------------------===// 71 72 // mapped_iterator - This is a simple iterator adapter that causes a function to 73 // be dereferenced whenever operator* is invoked on the iterator. 74 // 75 template <class RootIt, class UnaryFunc> 76 class mapped_iterator { 77 RootIt current; 78 UnaryFunc Fn; 79 public: 80 typedef typename std::iterator_traits<RootIt>::iterator_category 81 iterator_category; 82 typedef typename std::iterator_traits<RootIt>::difference_type 83 difference_type; 84 typedef typename UnaryFunc::result_type value_type; 85 86 typedef void pointer; 87 //typedef typename UnaryFunc::result_type *pointer; 88 typedef void reference; // Can't modify value returned by fn 89 90 typedef RootIt iterator_type; 91 typedef mapped_iterator<RootIt, UnaryFunc> _Self; 92 93 inline const RootIt &getCurrent() const { return current; } 94 inline const UnaryFunc &getFunc() const { return Fn; } 95 96 inline explicit mapped_iterator(const RootIt &I, UnaryFunc F) 97 : current(I), Fn(F) {} 98 inline mapped_iterator(const mapped_iterator &It) 99 : current(It.current), Fn(It.Fn) {} 100 101 inline value_type operator*() const { // All this work to do this 102 return Fn(*current); // little change 103 } 104 105 _Self& operator++() { ++current; return *this; } 106 _Self& operator--() { --current; return *this; } 107 _Self operator++(int) { _Self __tmp = *this; ++current; return __tmp; } 108 _Self operator--(int) { _Self __tmp = *this; --current; return __tmp; } 109 _Self operator+ (difference_type n) const { 110 return _Self(current + n, Fn); 111 } 112 _Self& operator+= (difference_type n) { current += n; return *this; } 113 _Self operator- (difference_type n) const { 114 return _Self(current - n, Fn); 115 } 116 _Self& operator-= (difference_type n) { current -= n; return *this; } 117 reference operator[](difference_type n) const { return *(*this + n); } 118 119 inline bool operator!=(const _Self &X) const { return !operator==(X); } 120 inline bool operator==(const _Self &X) const { return current == X.current; } 121 inline bool operator< (const _Self &X) const { return current < X.current; } 122 123 inline difference_type operator-(const _Self &X) const { 124 return current - X.current; 125 } 126 }; 127 128 template <class _Iterator, class Func> 129 inline mapped_iterator<_Iterator, Func> 130 operator+(typename mapped_iterator<_Iterator, Func>::difference_type N, 131 const mapped_iterator<_Iterator, Func>& X) { 132 return mapped_iterator<_Iterator, Func>(X.getCurrent() - N, X.getFunc()); 133 } 134 135 136 // map_iterator - Provide a convenient way to create mapped_iterators, just like 137 // make_pair is useful for creating pairs... 138 // 139 template <class ItTy, class FuncTy> 140 inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) { 141 return mapped_iterator<ItTy, FuncTy>(I, F); 142 } 143 144 145 // next/prior - These functions unlike std::advance do not modify the 146 // passed iterator but return a copy. 147 // 148 // next(myIt) returns copy of myIt incremented once 149 // next(myIt, n) returns copy of myIt incremented n times 150 // prior(myIt) returns copy of myIt decremented once 151 // prior(myIt, n) returns copy of myIt decremented n times 152 153 template <typename ItTy, typename Dist> 154 inline ItTy next(ItTy it, Dist n) 155 { 156 std::advance(it, n); 157 return it; 158 } 159 160 template <typename ItTy> 161 inline ItTy next(ItTy it) 162 { 163 return ++it; 164 } 165 166 template <typename ItTy, typename Dist> 167 inline ItTy prior(ItTy it, Dist n) 168 { 169 std::advance(it, -n); 170 return it; 171 } 172 173 template <typename ItTy> 174 inline ItTy prior(ItTy it) 175 { 176 return --it; 177 } 178 179 //===----------------------------------------------------------------------===// 180 // Extra additions to <utility> 181 //===----------------------------------------------------------------------===// 182 183 // tie - this function ties two objects and returns a temporary object 184 // that is assignable from a std::pair. This can be used to make code 185 // more readable when using values returned from functions bundled in 186 // a std::pair. Since an example is worth 1000 words: 187 // 188 // typedef std::map<int, int> Int2IntMap; 189 // 190 // Int2IntMap myMap; 191 // Int2IntMap::iterator where; 192 // bool inserted; 193 // tie(where, inserted) = myMap.insert(std::make_pair(123,456)); 194 // 195 // if (inserted) 196 // // do stuff 197 // else 198 // // do other stuff 199 template <typename T1, typename T2> 200 struct tier { 201 typedef T1 &first_type; 202 typedef T2 &second_type; 203 204 first_type first; 205 second_type second; 206 207 tier(first_type f, second_type s) : first(f), second(s) { } 208 tier& operator=(const std::pair<T1, T2>& p) { 209 first = p.first; 210 second = p.second; 211 return *this; 212 } 213 }; 214 215 template <typename T1, typename T2> 216 inline tier<T1, T2> tie(T1& f, T2& s) { 217 return tier<T1, T2>(f, s); 218 } 219 220 //===----------------------------------------------------------------------===// 221 // Extra additions for arrays 222 //===----------------------------------------------------------------------===// 223 224 /// Find where an array ends (for ending iterators) 225 /// This returns a pointer to the byte immediately 226 /// after the end of an array. 227 template<class T, std::size_t N> 228 inline T *array_endof(T (&x)[N]) { 229 return x+N; 230 } 231 232 /// Find the length of an array. 233 template<class T, std::size_t N> 234 inline size_t array_lengthof(T (&)[N]) { 235 return N; 236 } 237 238 /// array_pod_sort_comparator - This is helper function for array_pod_sort, 239 /// which just uses operator< on T. 240 template<typename T> 241 inline int array_pod_sort_comparator(const void *P1, const void *P2) { 242 if (*reinterpret_cast<const T*>(P1) < *reinterpret_cast<const T*>(P2)) 243 return -1; 244 if (*reinterpret_cast<const T*>(P2) < *reinterpret_cast<const T*>(P1)) 245 return 1; 246 return 0; 247 } 248 249 /// get_array_pod_sort_comparator - This is an internal helper function used to 250 /// get type deduction of T right. 251 template<typename T> 252 inline int (*get_array_pod_sort_comparator(const T &)) 253 (const void*, const void*) { 254 return array_pod_sort_comparator<T>; 255 } 256 257 258 /// array_pod_sort - This sorts an array with the specified start and end 259 /// extent. This is just like std::sort, except that it calls qsort instead of 260 /// using an inlined template. qsort is slightly slower than std::sort, but 261 /// most sorts are not performance critical in LLVM and std::sort has to be 262 /// template instantiated for each type, leading to significant measured code 263 /// bloat. This function should generally be used instead of std::sort where 264 /// possible. 265 /// 266 /// This function assumes that you have simple POD-like types that can be 267 /// compared with operator< and can be moved with memcpy. If this isn't true, 268 /// you should use std::sort. 269 /// 270 /// NOTE: If qsort_r were portable, we could allow a custom comparator and 271 /// default to std::less. 272 template<class IteratorTy> 273 inline void array_pod_sort(IteratorTy Start, IteratorTy End) { 274 // Don't dereference start iterator of empty sequence. 275 if (Start == End) return; 276 qsort(&*Start, End-Start, sizeof(*Start), 277 get_array_pod_sort_comparator(*Start)); 278 } 279 280 template<class IteratorTy> 281 inline void array_pod_sort(IteratorTy Start, IteratorTy End, 282 int (*Compare)(const void*, const void*)) { 283 // Don't dereference start iterator of empty sequence. 284 if (Start == End) return; 285 qsort(&*Start, End-Start, sizeof(*Start), Compare); 286 } 287 288 //===----------------------------------------------------------------------===// 289 // Extra additions to <algorithm> 290 //===----------------------------------------------------------------------===// 291 292 /// For a container of pointers, deletes the pointers and then clears the 293 /// container. 294 template<typename Container> 295 void DeleteContainerPointers(Container &C) { 296 for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I) 297 delete *I; 298 C.clear(); 299 } 300 301 /// In a container of pairs (usually a map) whose second element is a pointer, 302 /// deletes the second elements and then clears the container. 303 template<typename Container> 304 void DeleteContainerSeconds(Container &C) { 305 for (typename Container::iterator I = C.begin(), E = C.end(); I != E; ++I) 306 delete I->second; 307 C.clear(); 308 } 309 310 } // End llvm namespace 311 312 #endif 313