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 "lldb/Host/Mutex.h"
14
15 namespace lldb_private
16 {
17
map_adapter(I & iter)18 template <typename I, typename E> E map_adapter(I &iter)
19 {
20 return iter->second;
21 }
22
vector_adapter(I & iter)23 template <typename I, typename E> E vector_adapter(I &iter)
24 {
25 return *iter;
26 }
27
28 template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedConstIterator
29 {
30 public:
31 typedef typename C::const_iterator BackingIterator;
32 private:
33 BackingIterator m_iter;
34 public:
35 // Wrapping constructor
AdaptedConstIterator(BackingIterator backing_iterator)36 AdaptedConstIterator (BackingIterator backing_iterator) :
37 m_iter(backing_iterator)
38 {
39 }
40
41 // Default-constructible
AdaptedConstIterator()42 AdaptedConstIterator () :
43 m_iter()
44 {
45 }
46
47 // Copy-constructible
AdaptedConstIterator(const AdaptedConstIterator & rhs)48 AdaptedConstIterator (const AdaptedConstIterator &rhs) :
49 m_iter(rhs.m_iter)
50 {
51 }
52
53 // Copy-assignable
54 AdaptedConstIterator &operator= (const AdaptedConstIterator &rhs)
55 {
56 m_iter = rhs.m_iter;
57 return *this;
58 }
59
60 // Destructible
~AdaptedConstIterator()61 ~AdaptedConstIterator () { }
62
63 // Comparable
64 bool operator== (const AdaptedConstIterator &rhs)
65 {
66 return m_iter == rhs.m_iter;
67 }
68
69 bool operator!= (const AdaptedConstIterator &rhs)
70 {
71 return m_iter != rhs.m_iter;
72 }
73
74 // Rvalue dereferenceable
75 E operator* ()
76 {
77 return (*A)(m_iter);
78 }
79
80 E operator-> ()
81 {
82 return (*A)(m_iter);
83 }
84
85 // Offset dereferenceable
86 E operator[] (typename BackingIterator::difference_type offset)
87 {
88 return AdaptedConstIterator(m_iter + offset);
89 }
90
91 // Incrementable
92 AdaptedConstIterator &operator++ ()
93 {
94 m_iter++;
95 return *this;
96 }
97
98 // Decrementable
99 AdaptedConstIterator &operator-- ()
100 {
101 m_iter--;
102 return *this;
103 }
104
105 // Compound assignment
106 AdaptedConstIterator &operator+= (typename BackingIterator::difference_type offset)
107 {
108 m_iter += offset;
109 return *this;
110 }
111
112 AdaptedConstIterator &operator-= (typename BackingIterator::difference_type offset)
113 {
114 m_iter -= offset;
115 return *this;
116 }
117
118 // Arithmetic
119 AdaptedConstIterator operator+ (typename BackingIterator::difference_type offset)
120 {
121 return AdaptedConstIterator(m_iter + offset);
122 }
123
124 AdaptedConstIterator operator- (typename BackingIterator::difference_type offset)
125 {
126 return AdaptedConstIterator(m_iter - offset);
127 }
128
129 // Comparable
130 bool operator< (AdaptedConstIterator &rhs)
131 {
132 return m_iter < rhs.m_iter;
133 }
134
135 bool operator<= (AdaptedConstIterator &rhs)
136 {
137 return m_iter <= rhs.m_iter;
138 }
139
140 bool operator> (AdaptedConstIterator &rhs)
141 {
142 return m_iter > rhs.m_iter;
143 }
144
145 bool operator>= (AdaptedConstIterator &rhs)
146 {
147 return m_iter >= rhs.m_iter;
148 }
149
150 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
151 friend AdaptedConstIterator<C1, E1, A1> operator+(typename C1::const_iterator::difference_type, AdaptedConstIterator<C1, E1, A1> &);
152
153 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
154 friend typename C1::const_iterator::difference_type operator-(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &);
155
156 template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
157 friend void swap(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &);
158 };
159
160 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
161 AdaptedConstIterator<C, E, A> operator+ (typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type offset, AdaptedConstIterator<C, E, A> &rhs)
162 {
163 return rhs.operator+(offset);
164 }
165
166 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
167 typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type operator- (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
168 {
169 return(lhs.m_iter - rhs.m_iter);
170 }
171
172 template <typename C, typename E, E (*A)(typename C::const_iterator &)>
swap(AdaptedConstIterator<C,E,A> & lhs,AdaptedConstIterator<C,E,A> & rhs)173 void swap (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
174 {
175 std::swap(lhs.m_iter, rhs.m_iter);
176 }
177
178 template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedIterable
179 {
180 private:
181 const C &m_container;
182 public:
AdaptedIterable(const C & container)183 AdaptedIterable (const C &container) :
184 m_container(container)
185 {
186 }
187
begin()188 AdaptedConstIterator<C, E, A> begin ()
189 {
190 return AdaptedConstIterator<C, E, A>(m_container.begin());
191 }
192
end()193 AdaptedConstIterator<C, E, A> end ()
194 {
195 return AdaptedConstIterator<C, E, A>(m_container.end());
196 }
197 };
198
199 template <typename C, typename E, E (*A)(typename C::const_iterator &)> class LockingAdaptedIterable : public AdaptedIterable<C, E, A>
200 {
201 private:
202 Mutex *m_mutex = nullptr;
203 public:
LockingAdaptedIterable(C & container,Mutex & mutex)204 LockingAdaptedIterable (C &container, Mutex &mutex) :
205 AdaptedIterable<C,E,A>(container),
206 m_mutex(&mutex)
207 {
208 m_mutex->Lock();
209 }
210
LockingAdaptedIterable(LockingAdaptedIterable && rhs)211 LockingAdaptedIterable (LockingAdaptedIterable &&rhs) :
212 AdaptedIterable<C,E,A>(rhs),
213 m_mutex(rhs.m_mutex)
214 {
215 rhs.m_mutex = NULL;
216 }
217
~LockingAdaptedIterable()218 ~LockingAdaptedIterable ()
219 {
220 if (m_mutex)
221 m_mutex->Unlock();
222 }
223
224 private:
225 DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable);
226 };
227
228 }
229
230 #endif
231