Iterable.h revision 262528
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
15namespace lldb_private
16{
17
18template <typename I, typename E> E map_adapter(I &iter)
19{
20    return iter->second;
21}
22
23template <typename I, typename E> E vector_adapter(I &iter)
24{
25    return *iter;
26}
27
28template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedConstIterator
29{
30public:
31    typedef typename C::const_iterator BackingIterator;
32private:
33    BackingIterator m_iter;
34public:
35    // Wrapping constructor
36    AdaptedConstIterator (BackingIterator backing_iterator) :
37        m_iter(backing_iterator)
38    {
39    }
40
41    // Default-constructible
42    AdaptedConstIterator () :
43        m_iter()
44    {
45    }
46
47    // Copy-constructible
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
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
160template <typename C, typename E, E (*A)(typename C::const_iterator &)>
161AdaptedConstIterator<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
166template <typename C, typename E, E (*A)(typename C::const_iterator &)>
167typename 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
172template <typename C, typename E, E (*A)(typename C::const_iterator &)>
173void swap (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
174{
175    std::swap(lhs.m_iter, rhs.m_iter);
176}
177
178template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedIterable
179{
180private:
181    const C &m_container;
182public:
183    AdaptedIterable (const C &container) :
184        m_container(container)
185    {
186    }
187
188    AdaptedConstIterator<C, E, A> begin ()
189    {
190        return AdaptedConstIterator<C, E, A>(m_container.begin());
191    }
192
193    AdaptedConstIterator<C, E, A> end ()
194    {
195        return AdaptedConstIterator<C, E, A>(m_container.end());
196    }
197};
198
199template <typename C, typename E, E (*A)(typename C::const_iterator &)> class LockingAdaptedIterable : public AdaptedIterable<C, E, A>
200{
201private:
202    Mutex *m_mutex = nullptr;
203public:
204    LockingAdaptedIterable (C &container, Mutex &mutex) :
205        AdaptedIterable<C,E,A>(container),
206        m_mutex(&mutex)
207    {
208        m_mutex->Lock();
209    }
210
211    LockingAdaptedIterable (LockingAdaptedIterable &&rhs) :
212        AdaptedIterable<C,E,A>(rhs),
213        m_mutex(rhs.m_mutex)
214    {
215        rhs.m_mutex = NULL;
216    }
217
218    ~LockingAdaptedIterable ()
219    {
220        if (m_mutex)
221            m_mutex->Unlock();
222    }
223
224private:
225    DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable);
226};
227
228}
229
230#endif
231