Iterable.h revision 280031
1//===-- Iterable.h ----------------------------------------------*- 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#ifndef liblldb_Iterable_h_ 11#define liblldb_Iterable_h_ 12 13#include "lldb/Host/Mutex.h" 14 15namespace lldb_private 16{ 17 18template <typename I, typename E> E map_adapter(I &iter) 19{ 20 return iter->second; 21} 22 23template <typename I, typename E> E vector_adapter(I &iter) 24{ 25 return *iter; 26} 27 28template <typename I, typename E> E list_adapter(I &iter) 29{ 30 return *iter; 31} 32 33template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedConstIterator 34{ 35public: 36 typedef typename C::const_iterator BackingIterator; 37private: 38 BackingIterator m_iter; 39public: 40 // Wrapping constructor 41 AdaptedConstIterator (BackingIterator backing_iterator) : 42 m_iter(backing_iterator) 43 { 44 } 45 46 // Default-constructible 47 AdaptedConstIterator () : 48 m_iter() 49 { 50 } 51 52 // Copy-constructible 53 AdaptedConstIterator (const AdaptedConstIterator &rhs) : 54 m_iter(rhs.m_iter) 55 { 56 } 57 58 // Copy-assignable 59 AdaptedConstIterator &operator= (const AdaptedConstIterator &rhs) 60 { 61 m_iter = rhs.m_iter; 62 return *this; 63 } 64 65 // Destructible 66 ~AdaptedConstIterator () { } 67 68 // Comparable 69 bool operator== (const AdaptedConstIterator &rhs) 70 { 71 return m_iter == rhs.m_iter; 72 } 73 74 bool operator!= (const AdaptedConstIterator &rhs) 75 { 76 return m_iter != rhs.m_iter; 77 } 78 79 // Rvalue dereferenceable 80 E operator* () 81 { 82 return (*A)(m_iter); 83 } 84 85 E operator-> () 86 { 87 return (*A)(m_iter); 88 } 89 90 // Offset dereferenceable 91 E operator[] (typename BackingIterator::difference_type offset) 92 { 93 return AdaptedConstIterator(m_iter + offset); 94 } 95 96 // Incrementable 97 AdaptedConstIterator &operator++ () 98 { 99 m_iter++; 100 return *this; 101 } 102 103 // Decrementable 104 AdaptedConstIterator &operator-- () 105 { 106 m_iter--; 107 return *this; 108 } 109 110 // Compound assignment 111 AdaptedConstIterator &operator+= (typename BackingIterator::difference_type offset) 112 { 113 m_iter += offset; 114 return *this; 115 } 116 117 AdaptedConstIterator &operator-= (typename BackingIterator::difference_type offset) 118 { 119 m_iter -= offset; 120 return *this; 121 } 122 123 // Arithmetic 124 AdaptedConstIterator operator+ (typename BackingIterator::difference_type offset) 125 { 126 return AdaptedConstIterator(m_iter + offset); 127 } 128 129 AdaptedConstIterator operator- (typename BackingIterator::difference_type offset) 130 { 131 return AdaptedConstIterator(m_iter - offset); 132 } 133 134 // Comparable 135 bool operator< (AdaptedConstIterator &rhs) 136 { 137 return m_iter < rhs.m_iter; 138 } 139 140 bool operator<= (AdaptedConstIterator &rhs) 141 { 142 return m_iter <= rhs.m_iter; 143 } 144 145 bool operator> (AdaptedConstIterator &rhs) 146 { 147 return m_iter > rhs.m_iter; 148 } 149 150 bool operator>= (AdaptedConstIterator &rhs) 151 { 152 return m_iter >= rhs.m_iter; 153 } 154 155 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 156 friend AdaptedConstIterator<C1, E1, A1> operator+(typename C1::const_iterator::difference_type, AdaptedConstIterator<C1, E1, A1> &); 157 158 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 159 friend typename C1::const_iterator::difference_type operator-(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &); 160 161 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 162 friend void swap(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &); 163}; 164 165template <typename C, typename E, E (*A)(typename C::const_iterator &)> 166AdaptedConstIterator<C, E, A> operator+ (typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type offset, AdaptedConstIterator<C, E, A> &rhs) 167{ 168 return rhs.operator+(offset); 169} 170 171template <typename C, typename E, E (*A)(typename C::const_iterator &)> 172typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type operator- (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs) 173{ 174 return(lhs.m_iter - rhs.m_iter); 175} 176 177template <typename C, typename E, E (*A)(typename C::const_iterator &)> 178void swap (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs) 179{ 180 std::swap(lhs.m_iter, rhs.m_iter); 181} 182 183template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedIterable 184{ 185private: 186 const C &m_container; 187public: 188 AdaptedIterable (const C &container) : 189 m_container(container) 190 { 191 } 192 193 AdaptedConstIterator<C, E, A> begin () 194 { 195 return AdaptedConstIterator<C, E, A>(m_container.begin()); 196 } 197 198 AdaptedConstIterator<C, E, A> end () 199 { 200 return AdaptedConstIterator<C, E, A>(m_container.end()); 201 } 202}; 203 204template <typename C, typename E, E (*A)(typename C::const_iterator &)> class LockingAdaptedIterable : public AdaptedIterable<C, E, A> 205{ 206private: 207 Mutex *m_mutex = nullptr; 208public: 209 LockingAdaptedIterable (C &container, Mutex &mutex) : 210 AdaptedIterable<C,E,A>(container), 211 m_mutex(&mutex) 212 { 213 m_mutex->Lock(); 214 } 215 216 LockingAdaptedIterable (LockingAdaptedIterable &&rhs) : 217 AdaptedIterable<C,E,A>(rhs), 218 m_mutex(rhs.m_mutex) 219 { 220 rhs.m_mutex = NULL; 221 } 222 223 ~LockingAdaptedIterable () 224 { 225 if (m_mutex) 226 m_mutex->Unlock(); 227 } 228 229private: 230 DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable); 231}; 232 233} 234 235#endif 236