Iterable.h revision 258882
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    friend AdaptedConstIterator operator+(typename BackingIterator::difference_type, AdaptedConstIterator &);
151    friend typename BackingIterator::difference_type operator-(AdaptedConstIterator &, AdaptedConstIterator &);
152    friend void swap(AdaptedConstIterator &, AdaptedConstIterator &);
153};
154
155template <typename C, typename E, E (*A)(typename C::const_iterator &)>
156AdaptedConstIterator<C, E, A> operator+ (typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type offset, AdaptedConstIterator<C, E, A> &rhs)
157{
158    return rhs.operator+(offset);
159}
160
161template <typename C, typename E, E (*A)(typename C::const_iterator &)>
162typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type operator- (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
163{
164    return(lhs.m_iter - rhs.m_iter);
165}
166
167template <typename C, typename E, E (*A)(typename C::const_iterator &)>
168void swap (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
169{
170    std::swap(lhs.m_iter, rhs.m_iter);
171}
172
173template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedIterable
174{
175private:
176    const C &m_container;
177public:
178    AdaptedIterable (const C &container) :
179        m_container(container)
180    {
181    }
182
183    AdaptedConstIterator<C, E, A> begin ()
184    {
185        return AdaptedConstIterator<C, E, A>(m_container.begin());
186    }
187
188    AdaptedConstIterator<C, E, A> end ()
189    {
190        return AdaptedConstIterator<C, E, A>(m_container.end());
191    }
192};
193
194template <typename C, typename E, E (*A)(typename C::const_iterator &)> class LockingAdaptedIterable : public AdaptedIterable<C, E, A>
195{
196private:
197    Mutex *m_mutex = nullptr;
198public:
199    LockingAdaptedIterable (C &container, Mutex &mutex) :
200        AdaptedIterable<C,E,A>(container),
201        m_mutex(&mutex)
202    {
203        m_mutex->Lock();
204    }
205
206    LockingAdaptedIterable (LockingAdaptedIterable &&rhs) :
207        AdaptedIterable<C,E,A>(rhs),
208        m_mutex(rhs.m_mutex)
209    {
210        rhs.m_mutex = NULL;
211    }
212
213    ~LockingAdaptedIterable ()
214    {
215        if (m_mutex)
216            m_mutex->Unlock();
217    }
218
219private:
220    DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable);
221};
222
223}
224
225#endif
226