]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Utility/Iterable.h
Merge lld release_80 branch r351543, and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / include / lldb / Utility / Iterable.h
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
16 namespace lldb_private {
17
18 template <typename I, typename E> E map_adapter(I &iter) {
19   return iter->second;
20 }
21
22 template <typename I, typename E> E vector_adapter(I &iter) { return *iter; }
23
24 template <typename I, typename E> E list_adapter(I &iter) { return *iter; }
25
26 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
27 class AdaptedConstIterator {
28 public:
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
128 private:
129   BackingIterator m_iter;
130 };
131
132 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
133 AdaptedConstIterator<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
140 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
141 typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type
142 operator-(AdaptedConstIterator<C, E, A> &lhs,
143           AdaptedConstIterator<C, E, A> &rhs) {
144   return (lhs.m_iter - rhs.m_iter);
145 }
146
147 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
148 void swap(AdaptedConstIterator<C, E, A> &lhs,
149           AdaptedConstIterator<C, E, A> &rhs) {
150   std::swap(lhs.m_iter, rhs.m_iter);
151 }
152
153 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
154 class AdaptedIterable {
155 private:
156   const C &m_container;
157
158 public:
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
170 template <typename C, typename E, E (*A)(typename C::const_iterator &),
171           typename MutexType>
172 class LockingAdaptedIterable : public AdaptedIterable<C, E, A> {
173 public:
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
189 private:
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_