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