Iterable.h revision 258882
1258882Semaste//===-- Iterable.h ----------------------------------------------*- C++ -*-===//
2258882Semaste//
3258882Semaste//                     The LLVM Compiler Infrastructure
4258882Semaste//
5258882Semaste// This file is distributed under the University of Illinois Open Source
6258882Semaste// License. See LICENSE.TXT for details.
7258882Semaste//
8258882Semaste//===----------------------------------------------------------------------===//
9258882Semaste
10258882Semaste#ifndef liblldb_Iterable_h_
11258882Semaste#define liblldb_Iterable_h_
12258882Semaste
13258882Semaste#include "lldb/Host/Mutex.h"
14258882Semaste
15258882Semastenamespace lldb_private
16258882Semaste{
17258882Semaste
18258882Semastetemplate <typename I, typename E> E map_adapter(I &iter)
19258882Semaste{
20258882Semaste    return iter->second;
21258882Semaste}
22258882Semaste
23258882Semastetemplate <typename I, typename E> E vector_adapter(I &iter)
24258882Semaste{
25258882Semaste    return *iter;
26258882Semaste}
27258882Semaste
28258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedConstIterator
29258882Semaste{
30258882Semastepublic:
31258882Semaste    typedef typename C::const_iterator BackingIterator;
32258882Semasteprivate:
33258882Semaste    BackingIterator m_iter;
34258882Semastepublic:
35258882Semaste    // Wrapping constructor
36258882Semaste    AdaptedConstIterator (BackingIterator backing_iterator) :
37258882Semaste        m_iter(backing_iterator)
38258882Semaste    {
39258882Semaste    }
40258882Semaste
41258882Semaste    // Default-constructible
42258882Semaste    AdaptedConstIterator () :
43258882Semaste        m_iter()
44258882Semaste    {
45258882Semaste    }
46258882Semaste
47258882Semaste    // Copy-constructible
48258882Semaste    AdaptedConstIterator (const AdaptedConstIterator &rhs) :
49258882Semaste        m_iter(rhs.m_iter)
50258882Semaste    {
51258882Semaste    }
52258882Semaste
53258882Semaste    // Copy-assignable
54258882Semaste    AdaptedConstIterator &operator= (const AdaptedConstIterator &rhs)
55258882Semaste    {
56258882Semaste        m_iter = rhs.m_iter;
57258882Semaste        return *this;
58258882Semaste    }
59258882Semaste
60258882Semaste    // Destructible
61258882Semaste    ~AdaptedConstIterator () { }
62258882Semaste
63258882Semaste    // Comparable
64258882Semaste    bool operator== (const AdaptedConstIterator &rhs)
65258882Semaste    {
66258882Semaste        return m_iter == rhs.m_iter;
67258882Semaste    }
68258882Semaste
69258882Semaste    bool operator!= (const AdaptedConstIterator &rhs)
70258882Semaste    {
71258882Semaste        return m_iter != rhs.m_iter;
72258882Semaste    }
73258882Semaste
74258882Semaste    // Rvalue dereferenceable
75258882Semaste    E operator* ()
76258882Semaste    {
77258882Semaste        return (*A)(m_iter);
78258882Semaste    }
79258882Semaste
80258882Semaste    E operator-> ()
81258882Semaste    {
82258882Semaste        return (*A)(m_iter);
83258882Semaste    }
84258882Semaste
85258882Semaste    // Offset dereferenceable
86258882Semaste    E operator[] (typename BackingIterator::difference_type offset)
87258882Semaste    {
88258882Semaste        return AdaptedConstIterator(m_iter + offset);
89258882Semaste    }
90258882Semaste
91258882Semaste    // Incrementable
92258882Semaste    AdaptedConstIterator &operator++ ()
93258882Semaste    {
94258882Semaste        m_iter++;
95258882Semaste        return *this;
96258882Semaste    }
97258882Semaste
98258882Semaste    // Decrementable
99258882Semaste    AdaptedConstIterator &operator-- ()
100258882Semaste    {
101258882Semaste        m_iter--;
102258882Semaste        return *this;
103258882Semaste    }
104258882Semaste
105258882Semaste    // Compound assignment
106258882Semaste    AdaptedConstIterator &operator+= (typename BackingIterator::difference_type offset)
107258882Semaste    {
108258882Semaste        m_iter += offset;
109258882Semaste        return *this;
110258882Semaste    }
111258882Semaste
112258882Semaste    AdaptedConstIterator &operator-= (typename BackingIterator::difference_type offset)
113258882Semaste    {
114258882Semaste        m_iter -= offset;
115258882Semaste        return *this;
116258882Semaste    }
117258882Semaste
118258882Semaste    // Arithmetic
119258882Semaste    AdaptedConstIterator operator+ (typename BackingIterator::difference_type offset)
120258882Semaste    {
121258882Semaste        return AdaptedConstIterator(m_iter + offset);
122258882Semaste    }
123258882Semaste
124258882Semaste    AdaptedConstIterator operator- (typename BackingIterator::difference_type offset)
125258882Semaste    {
126258882Semaste        return AdaptedConstIterator(m_iter - offset);
127258882Semaste    }
128258882Semaste
129258882Semaste    // Comparable
130258882Semaste    bool operator< (AdaptedConstIterator &rhs)
131258882Semaste    {
132258882Semaste        return m_iter < rhs.m_iter;
133258882Semaste    }
134258882Semaste
135258882Semaste    bool operator<= (AdaptedConstIterator &rhs)
136258882Semaste    {
137258882Semaste        return m_iter <= rhs.m_iter;
138258882Semaste    }
139258882Semaste
140258882Semaste    bool operator> (AdaptedConstIterator &rhs)
141258882Semaste    {
142258882Semaste        return m_iter > rhs.m_iter;
143258882Semaste    }
144258882Semaste
145258882Semaste    bool operator>= (AdaptedConstIterator &rhs)
146258882Semaste    {
147258882Semaste        return m_iter >= rhs.m_iter;
148258882Semaste    }
149258882Semaste
150258882Semaste    friend AdaptedConstIterator operator+(typename BackingIterator::difference_type, AdaptedConstIterator &);
151258882Semaste    friend typename BackingIterator::difference_type operator-(AdaptedConstIterator &, AdaptedConstIterator &);
152258882Semaste    friend void swap(AdaptedConstIterator &, AdaptedConstIterator &);
153258882Semaste};
154258882Semaste
155258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)>
156258882SemasteAdaptedConstIterator<C, E, A> operator+ (typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type offset, AdaptedConstIterator<C, E, A> &rhs)
157258882Semaste{
158258882Semaste    return rhs.operator+(offset);
159258882Semaste}
160258882Semaste
161258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)>
162258882Semastetypename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type operator- (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
163258882Semaste{
164258882Semaste    return(lhs.m_iter - rhs.m_iter);
165258882Semaste}
166258882Semaste
167258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)>
168258882Semastevoid swap (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
169258882Semaste{
170258882Semaste    std::swap(lhs.m_iter, rhs.m_iter);
171258882Semaste}
172258882Semaste
173258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedIterable
174258882Semaste{
175258882Semasteprivate:
176258882Semaste    const C &m_container;
177258882Semastepublic:
178258882Semaste    AdaptedIterable (const C &container) :
179258882Semaste        m_container(container)
180258882Semaste    {
181258882Semaste    }
182258882Semaste
183258882Semaste    AdaptedConstIterator<C, E, A> begin ()
184258882Semaste    {
185258882Semaste        return AdaptedConstIterator<C, E, A>(m_container.begin());
186258882Semaste    }
187258882Semaste
188258882Semaste    AdaptedConstIterator<C, E, A> end ()
189258882Semaste    {
190258882Semaste        return AdaptedConstIterator<C, E, A>(m_container.end());
191258882Semaste    }
192258882Semaste};
193258882Semaste
194258882Semastetemplate <typename C, typename E, E (*A)(typename C::const_iterator &)> class LockingAdaptedIterable : public AdaptedIterable<C, E, A>
195258882Semaste{
196258882Semasteprivate:
197258882Semaste    Mutex *m_mutex = nullptr;
198258882Semastepublic:
199258882Semaste    LockingAdaptedIterable (C &container, Mutex &mutex) :
200258882Semaste        AdaptedIterable<C,E,A>(container),
201258882Semaste        m_mutex(&mutex)
202258882Semaste    {
203258882Semaste        m_mutex->Lock();
204258882Semaste    }
205258882Semaste
206258882Semaste    LockingAdaptedIterable (LockingAdaptedIterable &&rhs) :
207258882Semaste        AdaptedIterable<C,E,A>(rhs),
208258882Semaste        m_mutex(rhs.m_mutex)
209258882Semaste    {
210258882Semaste        rhs.m_mutex = NULL;
211258882Semaste    }
212258882Semaste
213258882Semaste    ~LockingAdaptedIterable ()
214258882Semaste    {
215258882Semaste        if (m_mutex)
216258882Semaste            m_mutex->Unlock();
217258882Semaste    }
218258882Semaste
219258882Semasteprivate:
220258882Semaste    DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable);
221258882Semaste};
222258882Semaste
223258882Semaste}
224258882Semaste
225258882Semaste#endif
226