1258882Semaste//===-- Iterable.h ----------------------------------------------*- C++ -*-===// 2258882Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6258882Semaste// 7258882Semaste//===----------------------------------------------------------------------===// 8258882Semaste 9258882Semaste#ifndef liblldb_Iterable_h_ 10258882Semaste#define liblldb_Iterable_h_ 11258882Semaste 12296417Sdim#include <utility> 13296417Sdim 14258882Semaste 15314564Sdimnamespace lldb_private { 16314564Sdim 17314564Sdimtemplate <typename I, typename E> E map_adapter(I &iter) { 18314564Sdim return iter->second; 19258882Semaste} 20314564Sdim 21314564Sdimtemplate <typename I, typename E> E vector_adapter(I &iter) { return *iter; } 22314564Sdim 23314564Sdimtemplate <typename I, typename E> E list_adapter(I &iter) { return *iter; } 24314564Sdim 25314564Sdimtemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 26314564Sdimclass AdaptedConstIterator { 27258882Semastepublic: 28314564Sdim typedef typename C::const_iterator BackingIterator; 29296417Sdim 30314564Sdim // Wrapping constructor 31314564Sdim AdaptedConstIterator(BackingIterator backing_iterator) 32314564Sdim : m_iter(backing_iterator) {} 33262528Semaste 34314564Sdim // Default-constructible 35314564Sdim AdaptedConstIterator() : m_iter() {} 36262528Semaste 37314564Sdim // Copy-constructible 38314564Sdim AdaptedConstIterator(const AdaptedConstIterator &rhs) : m_iter(rhs.m_iter) {} 39296417Sdim 40314564Sdim // Copy-assignable 41314564Sdim AdaptedConstIterator &operator=(const AdaptedConstIterator &rhs) { 42314564Sdim m_iter = rhs.m_iter; 43314564Sdim return *this; 44314564Sdim } 45314564Sdim 46314564Sdim // Destructible 47314564Sdim ~AdaptedConstIterator() = default; 48314564Sdim 49314564Sdim // Comparable 50314564Sdim bool operator==(const AdaptedConstIterator &rhs) { 51314564Sdim return m_iter == rhs.m_iter; 52314564Sdim } 53314564Sdim 54314564Sdim bool operator!=(const AdaptedConstIterator &rhs) { 55314564Sdim return m_iter != rhs.m_iter; 56314564Sdim } 57314564Sdim 58314564Sdim // Rvalue dereferenceable 59314564Sdim E operator*() { return (*A)(m_iter); } 60314564Sdim 61314564Sdim E operator->() { return (*A)(m_iter); } 62314564Sdim 63314564Sdim // Offset dereferenceable 64314564Sdim E operator[](typename BackingIterator::difference_type offset) { 65314564Sdim return AdaptedConstIterator(m_iter + offset); 66314564Sdim } 67314564Sdim 68314564Sdim // Incrementable 69314564Sdim AdaptedConstIterator &operator++() { 70314564Sdim m_iter++; 71314564Sdim return *this; 72314564Sdim } 73314564Sdim 74314564Sdim // Decrementable 75314564Sdim AdaptedConstIterator &operator--() { 76314564Sdim m_iter--; 77314564Sdim return *this; 78314564Sdim } 79314564Sdim 80314564Sdim // Compound assignment 81314564Sdim AdaptedConstIterator & 82314564Sdim operator+=(typename BackingIterator::difference_type offset) { 83314564Sdim m_iter += offset; 84314564Sdim return *this; 85314564Sdim } 86314564Sdim 87314564Sdim AdaptedConstIterator & 88314564Sdim operator-=(typename BackingIterator::difference_type offset) { 89314564Sdim m_iter -= offset; 90314564Sdim return *this; 91314564Sdim } 92314564Sdim 93314564Sdim // Arithmetic 94314564Sdim AdaptedConstIterator 95314564Sdim operator+(typename BackingIterator::difference_type offset) { 96314564Sdim return AdaptedConstIterator(m_iter + offset); 97314564Sdim } 98314564Sdim 99314564Sdim AdaptedConstIterator 100314564Sdim operator-(typename BackingIterator::difference_type offset) { 101314564Sdim return AdaptedConstIterator(m_iter - offset); 102314564Sdim } 103314564Sdim 104314564Sdim // Comparable 105314564Sdim bool operator<(AdaptedConstIterator &rhs) { return m_iter < rhs.m_iter; } 106314564Sdim 107314564Sdim bool operator<=(AdaptedConstIterator &rhs) { return m_iter <= rhs.m_iter; } 108314564Sdim 109314564Sdim bool operator>(AdaptedConstIterator &rhs) { return m_iter > rhs.m_iter; } 110314564Sdim 111314564Sdim bool operator>=(AdaptedConstIterator &rhs) { return m_iter >= rhs.m_iter; } 112314564Sdim 113314564Sdim template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 114314564Sdim friend AdaptedConstIterator<C1, E1, A1> 115314564Sdim operator+(typename C1::const_iterator::difference_type, 116314564Sdim AdaptedConstIterator<C1, E1, A1> &); 117314564Sdim 118314564Sdim template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 119314564Sdim friend typename C1::const_iterator::difference_type 120314564Sdim operator-(AdaptedConstIterator<C1, E1, A1> &, 121314564Sdim AdaptedConstIterator<C1, E1, A1> &); 122314564Sdim 123314564Sdim template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> 124314564Sdim friend void swap(AdaptedConstIterator<C1, E1, A1> &, 125314564Sdim AdaptedConstIterator<C1, E1, A1> &); 126314564Sdim 127296417Sdimprivate: 128314564Sdim BackingIterator m_iter; 129258882Semaste}; 130314564Sdim 131258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 132314564SdimAdaptedConstIterator<C, E, A> operator+( 133314564Sdim typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type 134314564Sdim offset, 135314564Sdim AdaptedConstIterator<C, E, A> &rhs) { 136314564Sdim return rhs.operator+(offset); 137258882Semaste} 138258882Semaste 139258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 140314564Sdimtypename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type 141314564Sdimoperator-(AdaptedConstIterator<C, E, A> &lhs, 142314564Sdim AdaptedConstIterator<C, E, A> &rhs) { 143314564Sdim return (lhs.m_iter - rhs.m_iter); 144258882Semaste} 145258882Semaste 146258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 147314564Sdimvoid swap(AdaptedConstIterator<C, E, A> &lhs, 148314564Sdim AdaptedConstIterator<C, E, A> &rhs) { 149314564Sdim std::swap(lhs.m_iter, rhs.m_iter); 150258882Semaste} 151314564Sdim 152314564Sdimtemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> 153314564Sdimclass AdaptedIterable { 154258882Semasteprivate: 155314564Sdim const C &m_container; 156314564Sdim 157258882Semastepublic: 158314564Sdim AdaptedIterable(const C &container) : m_container(container) {} 159314564Sdim 160314564Sdim AdaptedConstIterator<C, E, A> begin() { 161314564Sdim return AdaptedConstIterator<C, E, A>(m_container.begin()); 162314564Sdim } 163314564Sdim 164314564Sdim AdaptedConstIterator<C, E, A> end() { 165314564Sdim return AdaptedConstIterator<C, E, A>(m_container.end()); 166314564Sdim } 167258882Semaste}; 168309124Sdim 169314564Sdimtemplate <typename C, typename E, E (*A)(typename C::const_iterator &), 170314564Sdim typename MutexType> 171314564Sdimclass LockingAdaptedIterable : public AdaptedIterable<C, E, A> { 172258882Semastepublic: 173314564Sdim LockingAdaptedIterable(C &container, MutexType &mutex) 174314564Sdim : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) { 175314564Sdim m_mutex->lock(); 176314564Sdim } 177309124Sdim 178314564Sdim LockingAdaptedIterable(LockingAdaptedIterable &&rhs) 179314564Sdim : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex) { 180314564Sdim rhs.m_mutex = nullptr; 181314564Sdim } 182309124Sdim 183314564Sdim ~LockingAdaptedIterable() { 184314564Sdim if (m_mutex) 185314564Sdim m_mutex->unlock(); 186314564Sdim } 187309124Sdim 188258882Semasteprivate: 189314564Sdim MutexType *m_mutex = nullptr; 190296417Sdim 191314564Sdim LockingAdaptedIterable(const LockingAdaptedIterable &) = delete; 192314564Sdim LockingAdaptedIterable &operator=(const LockingAdaptedIterable &) = delete; 193258882Semaste}; 194309124Sdim 195296417Sdim} // namespace lldb_private 196258882Semaste 197296417Sdim#endif // liblldb_Iterable_h_ 198