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

source code of lldb/include/lldb/Utility/Iterable.h