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