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