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