Iterable.h revision 314564
1179645Smarcel//===-- Iterable.h ----------------------------------------------*- C++ -*-===// 2179645Smarcel// 3179645Smarcel// The LLVM Compiler Infrastructure 4179645Smarcel// 5179645Smarcel// This file is distributed under the University of Illinois Open Source 6179645Smarcel// License. See LICENSE.TXT for details. 7179645Smarcel// 8179645Smarcel//===----------------------------------------------------------------------===// 9179645Smarcel 10179645Smarcel#ifndef liblldb_Iterable_h_ 11179645Smarcel#define liblldb_Iterable_h_ 12179645Smarcel 13179645Smarcel// C Includes 14179645Smarcel// C++ Includes 15179645Smarcel#include <utility> 16179645Smarcel 17179645Smarcel// Other libraries and framework includes 18179645Smarcel// Project includes 19179645Smarcel 20179645Smarcelnamespace lldb_private { 21179645Smarcel 22179645Smarceltemplate <typename I, typename E> E map_adapter(I &iter) { 23179645Smarcel return iter->second; 24179645Smarcel} 25179645Smarcel 26179645Smarceltemplate <typename I, typename E> E vector_adapter(I &iter) { return *iter; } 27179645Smarcel 28179645Smarceltemplate <typename I, typename E> E list_adapter(I &iter) { return *iter; } 29179645Smarcel 30179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 31179645Smarcelclass AdaptedConstIterator { 32179645Smarcelpublic: 33179645Smarcel typedef typename C::const_iterator BackingIterator; 34179645Smarcel 35179645Smarcel // Wrapping constructor 36179645Smarcel AdaptedConstIterator(BackingIterator backing_iterator) 37179645Smarcel : m_iter(backing_iterator) {} 38179645Smarcel 39179645Smarcel // Default-constructible 40179645Smarcel AdaptedConstIterator() : m_iter() {} 41179645Smarcel 42179645Smarcel // Copy-constructible 43179645Smarcel AdaptedConstIterator(const AdaptedConstIterator &rhs) : m_iter(rhs.m_iter) {} 44179645Smarcel 45179645Smarcel // Copy-assignable 46179645Smarcel AdaptedConstIterator &operator=(const AdaptedConstIterator &rhs) { 47179645Smarcel m_iter = rhs.m_iter; 48179645Smarcel return *this; 49179645Smarcel } 50179645Smarcel 51179645Smarcel // Destructible 52179645Smarcel ~AdaptedConstIterator() = default; 53179645Smarcel 54179645Smarcel // Comparable 55179645Smarcel bool operator==(const AdaptedConstIterator &rhs) { 56179645Smarcel return m_iter == rhs.m_iter; 57179645Smarcel } 58179645Smarcel 59179645Smarcel bool operator!=(const AdaptedConstIterator &rhs) { 60179645Smarcel return m_iter != rhs.m_iter; 61179645Smarcel } 62179645Smarcel 63179645Smarcel // Rvalue dereferenceable 64179645Smarcel E operator*() { return (*A)(m_iter); } 65179645Smarcel 66226995Smarius E operator->() { return (*A)(m_iter); } 67179645Smarcel 68179645Smarcel // Offset dereferenceable 69179645Smarcel E operator[](typename BackingIterator::difference_type offset) { 70179645Smarcel return AdaptedConstIterator(m_iter + offset); 71179645Smarcel } 72179645Smarcel 73179645Smarcel // Incrementable 74179645Smarcel AdaptedConstIterator &operator++() { 75179645Smarcel m_iter++; 76179645Smarcel return *this; 77179645Smarcel } 78179645Smarcel 79179645Smarcel // Decrementable 80179645Smarcel AdaptedConstIterator &operator--() { 81179645Smarcel m_iter--; 82179645Smarcel return *this; 83179645Smarcel } 84179645Smarcel 85188131Snwhitehorn // Compound assignment 86179645Smarcel AdaptedConstIterator & 87179645Smarcel operator+=(typename BackingIterator::difference_type offset) { 88179645Smarcel m_iter += offset; 89179645Smarcel return *this; 90179645Smarcel } 91179645Smarcel 92179645Smarcel AdaptedConstIterator & 93179645Smarcel operator-=(typename BackingIterator::difference_type offset) { 94179645Smarcel m_iter -= offset; 95179645Smarcel return *this; 96179645Smarcel } 97179645Smarcel 98179645Smarcel // Arithmetic 99179645Smarcel AdaptedConstIterator 100179645Smarcel operator+(typename BackingIterator::difference_type offset) { 101179645Smarcel return AdaptedConstIterator(m_iter + offset); 102179645Smarcel } 103179645Smarcel 104179645Smarcel AdaptedConstIterator 105179645Smarcel operator-(typename BackingIterator::difference_type offset) { 106179645Smarcel return AdaptedConstIterator(m_iter - offset); 107179645Smarcel } 108179645Smarcel 109179645Smarcel // Comparable 110179645Smarcel bool operator<(AdaptedConstIterator &rhs) { return m_iter < rhs.m_iter; } 111179645Smarcel 112179645Smarcel bool operator<=(AdaptedConstIterator &rhs) { return m_iter <= rhs.m_iter; } 113226995Smarius 114226995Smarius bool operator>(AdaptedConstIterator &rhs) { return m_iter > rhs.m_iter; } 115226995Smarius 116226995Smarius bool operator>=(AdaptedConstIterator &rhs) { return m_iter >= rhs.m_iter; } 117226995Smarius 118226995Smarius template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 119226995Smarius friend AdaptedConstIterator<C1, E1, A1> 120226995Smarius operator+(typename C1::const_iterator::difference_type, 121226995Smarius AdaptedConstIterator<C1, E1, A1> &); 122226995Smarius 123226995Smarius template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 124226995Smarius friend typename C1::const_iterator::difference_type 125226995Smarius operator-(AdaptedConstIterator<C1, E1, A1> &, 126226995Smarius AdaptedConstIterator<C1, E1, A1> &); 127226995Smarius 128226995Smarius template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 129226995Smarius friend void swap(AdaptedConstIterator<C1, E1, A1> &, 130226995Smarius AdaptedConstIterator<C1, E1, A1> &); 131179645Smarcel 132179645Smarcelprivate: 133179645Smarcel BackingIterator m_iter; 134179645Smarcel}; 135179645Smarcel 136179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 137179645SmarcelAdaptedConstIterator<C, E, A> operator+( 138179645Smarcel typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type 139179645Smarcel offset, 140179645Smarcel AdaptedConstIterator<C, E, A> &rhs) { 141179645Smarcel return rhs.operator+(offset); 142227843Smarius} 143227843Smarius 144179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 145179645Smarceltypename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type 146179645Smarceloperator-(AdaptedConstIterator<C, E, A> &lhs, 147179645Smarcel AdaptedConstIterator<C, E, A> &rhs) { 148179645Smarcel return (lhs.m_iter - rhs.m_iter); 149179645Smarcel} 150179645Smarcel 151179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 152179645Smarcelvoid swap(AdaptedConstIterator<C, E, A> &lhs, 153179645Smarcel AdaptedConstIterator<C, E, A> &rhs) { 154179645Smarcel std::swap(lhs.m_iter, rhs.m_iter); 155179645Smarcel} 156179645Smarcel 157179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 158179645Smarcelclass AdaptedIterable { 159179645Smarcelprivate: 160179645Smarcel const C &m_container; 161179645Smarcel 162226995Smariuspublic: 163179645Smarcel AdaptedIterable(const C &container) : m_container(container) {} 164179645Smarcel 165226995Smarius AdaptedConstIterator<C, E, A> begin() { 166179645Smarcel return AdaptedConstIterator<C, E, A>(m_container.begin()); 167226995Smarius } 168179645Smarcel 169226995Smarius AdaptedConstIterator<C, E, A> end() { 170179645Smarcel return AdaptedConstIterator<C, E, A>(m_container.end()); 171226995Smarius } 172226995Smarius}; 173226995Smarius 174179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &), 175179645Smarcel typename MutexType> 176179645Smarcelclass LockingAdaptedIterable : public AdaptedIterable<C, E, A> { 177226995Smariuspublic: 178179645Smarcel LockingAdaptedIterable(C &container, MutexType &mutex) 179226995Smarius : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) { 180226995Smarius m_mutex->lock(); 181179645Smarcel } 182226995Smarius 183226995Smarius LockingAdaptedIterable(LockingAdaptedIterable &&rhs) 184179645Smarcel : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex) { 185226995Smarius rhs.m_mutex = nullptr; 186179645Smarcel } 187226995Smarius 188226995Smarius ~LockingAdaptedIterable() { 189226995Smarius if (m_mutex) 190179645Smarcel m_mutex->unlock(); 191226995Smarius } 192179645Smarcel 193179645Smarcelprivate: 194179645Smarcel MutexType *m_mutex = nullptr; 195179645Smarcel 196179645Smarcel LockingAdaptedIterable(const LockingAdaptedIterable &) = delete; 197179645Smarcel LockingAdaptedIterable &operator=(const LockingAdaptedIterable &) = delete; 198179645Smarcel}; 199179645Smarcel 200179645Smarcel} // namespace lldb_private 201226995Smarius 202179645Smarcel#endif // liblldb_Iterable_h_ 203179645Smarcel