File indexing completed on 2026-05-10 08:42:57
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_UTILITY_ITERABLE_H
0010 #define LLDB_UTILITY_ITERABLE_H
0011
0012 #include <utility>
0013
0014
0015 namespace lldb_private {
0016
0017 template <typename I, typename E> E map_adapter(I &iter) {
0018 return iter->second;
0019 }
0020
0021 template <typename I, typename E> E vector_adapter(I &iter) { return *iter; }
0022
0023 template <typename I, typename E> E list_adapter(I &iter) { return *iter; }
0024
0025 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
0026 class AdaptedConstIterator {
0027 public:
0028 typedef typename C::const_iterator BackingIterator;
0029
0030
0031 AdaptedConstIterator(BackingIterator backing_iterator)
0032 : m_iter(backing_iterator) {}
0033
0034
0035 AdaptedConstIterator() : m_iter() {}
0036
0037
0038 AdaptedConstIterator(const AdaptedConstIterator &rhs) : m_iter(rhs.m_iter) {}
0039
0040
0041 AdaptedConstIterator &operator=(const AdaptedConstIterator &rhs) {
0042 m_iter = rhs.m_iter;
0043 return *this;
0044 }
0045
0046
0047 ~AdaptedConstIterator() = default;
0048
0049
0050 bool operator==(const AdaptedConstIterator &rhs) {
0051 return m_iter == rhs.m_iter;
0052 }
0053
0054 bool operator!=(const AdaptedConstIterator &rhs) {
0055 return m_iter != rhs.m_iter;
0056 }
0057
0058
0059 E operator*() { return (*A)(m_iter); }
0060
0061 E operator->() { return (*A)(m_iter); }
0062
0063
0064 E operator[](typename BackingIterator::difference_type offset) {
0065 return AdaptedConstIterator(m_iter + offset);
0066 }
0067
0068
0069 AdaptedConstIterator &operator++() {
0070 m_iter++;
0071 return *this;
0072 }
0073
0074
0075 AdaptedConstIterator &operator--() {
0076 m_iter--;
0077 return *this;
0078 }
0079
0080
0081 AdaptedConstIterator &
0082 operator+=(typename BackingIterator::difference_type offset) {
0083 m_iter += offset;
0084 return *this;
0085 }
0086
0087 AdaptedConstIterator &
0088 operator-=(typename BackingIterator::difference_type offset) {
0089 m_iter -= offset;
0090 return *this;
0091 }
0092
0093
0094 AdaptedConstIterator
0095 operator+(typename BackingIterator::difference_type offset) {
0096 return AdaptedConstIterator(m_iter + offset);
0097 }
0098
0099 AdaptedConstIterator
0100 operator-(typename BackingIterator::difference_type offset) {
0101 return AdaptedConstIterator(m_iter - offset);
0102 }
0103
0104
0105 bool operator<(AdaptedConstIterator &rhs) { return m_iter < rhs.m_iter; }
0106
0107 bool operator<=(AdaptedConstIterator &rhs) { return m_iter <= rhs.m_iter; }
0108
0109 bool operator>(AdaptedConstIterator &rhs) { return m_iter > rhs.m_iter; }
0110
0111 bool operator>=(AdaptedConstIterator &rhs) { return m_iter >= rhs.m_iter; }
0112
0113 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
0114 friend AdaptedConstIterator<C1, E1, A1>
0115 operator+(typename C1::const_iterator::difference_type,
0116 AdaptedConstIterator<C1, E1, A1> &);
0117
0118 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
0119 friend typename C1::const_iterator::difference_type
0120 operator-(AdaptedConstIterator<C1, E1, A1> &,
0121 AdaptedConstIterator<C1, E1, A1> &);
0122
0123 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
0124 friend void swap(AdaptedConstIterator<C1, E1, A1> &,
0125 AdaptedConstIterator<C1, E1, A1> &);
0126
0127 private:
0128 BackingIterator m_iter;
0129 };
0130
0131 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
0132 AdaptedConstIterator<C, E, A> operator+(
0133 typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type
0134 offset,
0135 AdaptedConstIterator<C, E, A> &rhs) {
0136 return rhs.operator+(offset);
0137 }
0138
0139 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
0140 typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type
0141 operator-(AdaptedConstIterator<C, E, A> &lhs,
0142 AdaptedConstIterator<C, E, A> &rhs) {
0143 return (lhs.m_iter - rhs.m_iter);
0144 }
0145
0146 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
0147 void swap(AdaptedConstIterator<C, E, A> &lhs,
0148 AdaptedConstIterator<C, E, A> &rhs) {
0149 std::swap(lhs.m_iter, rhs.m_iter);
0150 }
0151
0152 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
0153 class AdaptedIterable {
0154 private:
0155 const C &m_container;
0156
0157 public:
0158 AdaptedIterable(const C &container) : m_container(container) {}
0159
0160 AdaptedConstIterator<C, E, A> begin() {
0161 return AdaptedConstIterator<C, E, A>(m_container.begin());
0162 }
0163
0164 AdaptedConstIterator<C, E, A> end() {
0165 return AdaptedConstIterator<C, E, A>(m_container.end());
0166 }
0167 };
0168
0169 template <typename C, typename E, E (*A)(typename C::const_iterator &),
0170 typename MutexType>
0171 class LockingAdaptedIterable : public AdaptedIterable<C, E, A> {
0172 public:
0173 LockingAdaptedIterable(const C &container, MutexType &mutex)
0174 : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) {
0175 m_mutex->lock();
0176 }
0177
0178 LockingAdaptedIterable(LockingAdaptedIterable &&rhs)
0179 : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex) {
0180 rhs.m_mutex = nullptr;
0181 }
0182
0183 ~LockingAdaptedIterable() {
0184 if (m_mutex)
0185 m_mutex->unlock();
0186 }
0187
0188 private:
0189 MutexType *m_mutex = nullptr;
0190
0191 LockingAdaptedIterable(const LockingAdaptedIterable &) = delete;
0192 LockingAdaptedIterable &operator=(const LockingAdaptedIterable &) = delete;
0193 };
0194
0195 }
0196
0197 #endif