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