Iterable.h revision 314564
1179645Smarcel//===-- Iterable.h ----------------------------------------------*- C++ -*-===//
2179645Smarcel//
3179645Smarcel//                     The LLVM Compiler Infrastructure
4179645Smarcel//
5179645Smarcel// This file is distributed under the University of Illinois Open Source
6179645Smarcel// License. See LICENSE.TXT for details.
7179645Smarcel//
8179645Smarcel//===----------------------------------------------------------------------===//
9179645Smarcel
10179645Smarcel#ifndef liblldb_Iterable_h_
11179645Smarcel#define liblldb_Iterable_h_
12179645Smarcel
13179645Smarcel// C Includes
14179645Smarcel// C++ Includes
15179645Smarcel#include <utility>
16179645Smarcel
17179645Smarcel// Other libraries and framework includes
18179645Smarcel// Project includes
19179645Smarcel
20179645Smarcelnamespace lldb_private {
21179645Smarcel
22179645Smarceltemplate <typename I, typename E> E map_adapter(I &iter) {
23179645Smarcel  return iter->second;
24179645Smarcel}
25179645Smarcel
26179645Smarceltemplate <typename I, typename E> E vector_adapter(I &iter) { return *iter; }
27179645Smarcel
28179645Smarceltemplate <typename I, typename E> E list_adapter(I &iter) { return *iter; }
29179645Smarcel
30179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)>
31179645Smarcelclass AdaptedConstIterator {
32179645Smarcelpublic:
33179645Smarcel  typedef typename C::const_iterator BackingIterator;
34179645Smarcel
35179645Smarcel  // Wrapping constructor
36179645Smarcel  AdaptedConstIterator(BackingIterator backing_iterator)
37179645Smarcel      : m_iter(backing_iterator) {}
38179645Smarcel
39179645Smarcel  // Default-constructible
40179645Smarcel  AdaptedConstIterator() : m_iter() {}
41179645Smarcel
42179645Smarcel  // Copy-constructible
43179645Smarcel  AdaptedConstIterator(const AdaptedConstIterator &rhs) : m_iter(rhs.m_iter) {}
44179645Smarcel
45179645Smarcel  // Copy-assignable
46179645Smarcel  AdaptedConstIterator &operator=(const AdaptedConstIterator &rhs) {
47179645Smarcel    m_iter = rhs.m_iter;
48179645Smarcel    return *this;
49179645Smarcel  }
50179645Smarcel
51179645Smarcel  // Destructible
52179645Smarcel  ~AdaptedConstIterator() = default;
53179645Smarcel
54179645Smarcel  // Comparable
55179645Smarcel  bool operator==(const AdaptedConstIterator &rhs) {
56179645Smarcel    return m_iter == rhs.m_iter;
57179645Smarcel  }
58179645Smarcel
59179645Smarcel  bool operator!=(const AdaptedConstIterator &rhs) {
60179645Smarcel    return m_iter != rhs.m_iter;
61179645Smarcel  }
62179645Smarcel
63179645Smarcel  // Rvalue dereferenceable
64179645Smarcel  E operator*() { return (*A)(m_iter); }
65179645Smarcel
66226995Smarius  E operator->() { return (*A)(m_iter); }
67179645Smarcel
68179645Smarcel  // Offset dereferenceable
69179645Smarcel  E operator[](typename BackingIterator::difference_type offset) {
70179645Smarcel    return AdaptedConstIterator(m_iter + offset);
71179645Smarcel  }
72179645Smarcel
73179645Smarcel  // Incrementable
74179645Smarcel  AdaptedConstIterator &operator++() {
75179645Smarcel    m_iter++;
76179645Smarcel    return *this;
77179645Smarcel  }
78179645Smarcel
79179645Smarcel  // Decrementable
80179645Smarcel  AdaptedConstIterator &operator--() {
81179645Smarcel    m_iter--;
82179645Smarcel    return *this;
83179645Smarcel  }
84179645Smarcel
85188131Snwhitehorn  // Compound assignment
86179645Smarcel  AdaptedConstIterator &
87179645Smarcel  operator+=(typename BackingIterator::difference_type offset) {
88179645Smarcel    m_iter += offset;
89179645Smarcel    return *this;
90179645Smarcel  }
91179645Smarcel
92179645Smarcel  AdaptedConstIterator &
93179645Smarcel  operator-=(typename BackingIterator::difference_type offset) {
94179645Smarcel    m_iter -= offset;
95179645Smarcel    return *this;
96179645Smarcel  }
97179645Smarcel
98179645Smarcel  // Arithmetic
99179645Smarcel  AdaptedConstIterator
100179645Smarcel  operator+(typename BackingIterator::difference_type offset) {
101179645Smarcel    return AdaptedConstIterator(m_iter + offset);
102179645Smarcel  }
103179645Smarcel
104179645Smarcel  AdaptedConstIterator
105179645Smarcel  operator-(typename BackingIterator::difference_type offset) {
106179645Smarcel    return AdaptedConstIterator(m_iter - offset);
107179645Smarcel  }
108179645Smarcel
109179645Smarcel  // Comparable
110179645Smarcel  bool operator<(AdaptedConstIterator &rhs) { return m_iter < rhs.m_iter; }
111179645Smarcel
112179645Smarcel  bool operator<=(AdaptedConstIterator &rhs) { return m_iter <= rhs.m_iter; }
113226995Smarius
114226995Smarius  bool operator>(AdaptedConstIterator &rhs) { return m_iter > rhs.m_iter; }
115226995Smarius
116226995Smarius  bool operator>=(AdaptedConstIterator &rhs) { return m_iter >= rhs.m_iter; }
117226995Smarius
118226995Smarius  template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
119226995Smarius  friend AdaptedConstIterator<C1, E1, A1>
120226995Smarius  operator+(typename C1::const_iterator::difference_type,
121226995Smarius            AdaptedConstIterator<C1, E1, A1> &);
122226995Smarius
123226995Smarius  template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
124226995Smarius  friend typename C1::const_iterator::difference_type
125226995Smarius  operator-(AdaptedConstIterator<C1, E1, A1> &,
126226995Smarius            AdaptedConstIterator<C1, E1, A1> &);
127226995Smarius
128226995Smarius  template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)>
129226995Smarius  friend void swap(AdaptedConstIterator<C1, E1, A1> &,
130226995Smarius                   AdaptedConstIterator<C1, E1, A1> &);
131179645Smarcel
132179645Smarcelprivate:
133179645Smarcel  BackingIterator m_iter;
134179645Smarcel};
135179645Smarcel
136179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)>
137179645SmarcelAdaptedConstIterator<C, E, A> operator+(
138179645Smarcel    typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type
139179645Smarcel        offset,
140179645Smarcel    AdaptedConstIterator<C, E, A> &rhs) {
141179645Smarcel  return rhs.operator+(offset);
142227843Smarius}
143227843Smarius
144179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)>
145179645Smarceltypename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type
146179645Smarceloperator-(AdaptedConstIterator<C, E, A> &lhs,
147179645Smarcel          AdaptedConstIterator<C, E, A> &rhs) {
148179645Smarcel  return (lhs.m_iter - rhs.m_iter);
149179645Smarcel}
150179645Smarcel
151179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)>
152179645Smarcelvoid swap(AdaptedConstIterator<C, E, A> &lhs,
153179645Smarcel          AdaptedConstIterator<C, E, A> &rhs) {
154179645Smarcel  std::swap(lhs.m_iter, rhs.m_iter);
155179645Smarcel}
156179645Smarcel
157179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &)>
158179645Smarcelclass AdaptedIterable {
159179645Smarcelprivate:
160179645Smarcel  const C &m_container;
161179645Smarcel
162226995Smariuspublic:
163179645Smarcel  AdaptedIterable(const C &container) : m_container(container) {}
164179645Smarcel
165226995Smarius  AdaptedConstIterator<C, E, A> begin() {
166179645Smarcel    return AdaptedConstIterator<C, E, A>(m_container.begin());
167226995Smarius  }
168179645Smarcel
169226995Smarius  AdaptedConstIterator<C, E, A> end() {
170179645Smarcel    return AdaptedConstIterator<C, E, A>(m_container.end());
171226995Smarius  }
172226995Smarius};
173226995Smarius
174179645Smarceltemplate <typename C, typename E, E (*A)(typename C::const_iterator &),
175179645Smarcel          typename MutexType>
176179645Smarcelclass LockingAdaptedIterable : public AdaptedIterable<C, E, A> {
177226995Smariuspublic:
178179645Smarcel  LockingAdaptedIterable(C &container, MutexType &mutex)
179226995Smarius      : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) {
180226995Smarius    m_mutex->lock();
181179645Smarcel  }
182226995Smarius
183226995Smarius  LockingAdaptedIterable(LockingAdaptedIterable &&rhs)
184179645Smarcel      : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex) {
185226995Smarius    rhs.m_mutex = nullptr;
186179645Smarcel  }
187226995Smarius
188226995Smarius  ~LockingAdaptedIterable() {
189226995Smarius    if (m_mutex)
190179645Smarcel      m_mutex->unlock();
191226995Smarius  }
192179645Smarcel
193179645Smarcelprivate:
194179645Smarcel  MutexType *m_mutex = nullptr;
195179645Smarcel
196179645Smarcel  LockingAdaptedIterable(const LockingAdaptedIterable &) = delete;
197179645Smarcel  LockingAdaptedIterable &operator=(const LockingAdaptedIterable &) = delete;
198179645Smarcel};
199179645Smarcel
200179645Smarcel} // namespace lldb_private
201226995Smarius
202179645Smarcel#endif // liblldb_Iterable_h_
203179645Smarcel