| //===-- Iterable.h ----------------------------------------------*- C++ -*-===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #ifndef LLDB_UTILITY_ITERABLE_H | |
| #define LLDB_UTILITY_ITERABLE_H | |
| #include <utility> | |
| namespace lldb_private { | |
| template <typename I, typename E> E map_adapter(I &iter) { | |
| return iter->second; | |
| } | |
| template <typename I, typename E> E vector_adapter(I &iter) { return *iter; } | |
| template <typename I, typename E> E list_adapter(I &iter) { return *iter; } | |
| template <typename C, typename E, E (*A)(typename C::const_iterator &)> | |
| class AdaptedConstIterator { | |
| public: | |
| typedef typename C::const_iterator BackingIterator; | |
| // Wrapping constructor | |
| AdaptedConstIterator(BackingIterator backing_iterator) | |
| : m_iter(backing_iterator) {} | |
| // Default-constructible | |
| AdaptedConstIterator() : m_iter() {} | |
| // Copy-constructible | |
| AdaptedConstIterator(const AdaptedConstIterator &rhs) : m_iter(rhs.m_iter) {} | |
| // Copy-assignable | |
| AdaptedConstIterator &operator=(const AdaptedConstIterator &rhs) { | |
| m_iter = rhs.m_iter; | |
| return *this; | |
| } | |
| // Destructible | |
| ~AdaptedConstIterator() = default; | |
| // Comparable | |
| bool operator==(const AdaptedConstIterator &rhs) { | |
| return m_iter == rhs.m_iter; | |
| } | |
| bool operator!=(const AdaptedConstIterator &rhs) { | |
| return m_iter != rhs.m_iter; | |
| } | |
| // Rvalue dereferenceable | |
| E operator*() { return (*A)(m_iter); } | |
| E operator->() { return (*A)(m_iter); } | |
| // Offset dereferenceable | |
| E operator[](typename BackingIterator::difference_type offset) { | |
| return AdaptedConstIterator(m_iter + offset); | |
| } | |
| // Incrementable | |
| AdaptedConstIterator &operator++() { | |
| m_iter++; | |
| return *this; | |
| } | |
| // Decrementable | |
| AdaptedConstIterator &operator--() { | |
| m_iter--; | |
| return *this; | |
| } | |
| // Compound assignment | |
| AdaptedConstIterator & | |
| operator+=(typename BackingIterator::difference_type offset) { | |
| m_iter += offset; | |
| return *this; | |
| } | |
| AdaptedConstIterator & | |
| operator-=(typename BackingIterator::difference_type offset) { | |
| m_iter -= offset; | |
| return *this; | |
| } | |
| // Arithmetic | |
| AdaptedConstIterator | |
| operator+(typename BackingIterator::difference_type offset) { | |
| return AdaptedConstIterator(m_iter + offset); | |
| } | |
| AdaptedConstIterator | |
| operator-(typename BackingIterator::difference_type offset) { | |
| return AdaptedConstIterator(m_iter - offset); | |
| } | |
| // Comparable | |
| bool operator<(AdaptedConstIterator &rhs) { return m_iter < rhs.m_iter; } | |
| bool operator<=(AdaptedConstIterator &rhs) { return m_iter <= rhs.m_iter; } | |
| bool operator>(AdaptedConstIterator &rhs) { return m_iter > rhs.m_iter; } | |
| bool operator>=(AdaptedConstIterator &rhs) { return m_iter >= rhs.m_iter; } | |
| template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> | |
| friend AdaptedConstIterator<C1, E1, A1> | |
| operator+(typename C1::const_iterator::difference_type, | |
| AdaptedConstIterator<C1, E1, A1> &); | |
| template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> | |
| friend typename C1::const_iterator::difference_type | |
| operator-(AdaptedConstIterator<C1, E1, A1> &, | |
| AdaptedConstIterator<C1, E1, A1> &); | |
| template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> | |
| friend void swap(AdaptedConstIterator<C1, E1, A1> &, | |
| AdaptedConstIterator<C1, E1, A1> &); | |
| private: | |
| BackingIterator m_iter; | |
| }; | |
| template <typename C, typename E, E (*A)(typename C::const_iterator &)> | |
| AdaptedConstIterator<C, E, A> operator+( | |
| typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type | |
| offset, | |
| AdaptedConstIterator<C, E, A> &rhs) { | |
| return rhs.operator+(offset); | |
| } | |
| template <typename C, typename E, E (*A)(typename C::const_iterator &)> | |
| typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type | |
| operator-(AdaptedConstIterator<C, E, A> &lhs, | |
| AdaptedConstIterator<C, E, A> &rhs) { | |
| return (lhs.m_iter - rhs.m_iter); | |
| } | |
| template <typename C, typename E, E (*A)(typename C::const_iterator &)> | |
| void swap(AdaptedConstIterator<C, E, A> &lhs, | |
| AdaptedConstIterator<C, E, A> &rhs) { | |
| std::swap(lhs.m_iter, rhs.m_iter); | |
| } | |
| template <typename C, typename E, E (*A)(typename C::const_iterator &)> | |
| class AdaptedIterable { | |
| private: | |
| const C &m_container; | |
| public: | |
| AdaptedIterable(const C &container) : m_container(container) {} | |
| AdaptedConstIterator<C, E, A> begin() { | |
| return AdaptedConstIterator<C, E, A>(m_container.begin()); | |
| } | |
| AdaptedConstIterator<C, E, A> end() { | |
| return AdaptedConstIterator<C, E, A>(m_container.end()); | |
| } | |
| }; | |
| template <typename C, typename E, E (*A)(typename C::const_iterator &), | |
| typename MutexType> | |
| class LockingAdaptedIterable : public AdaptedIterable<C, E, A> { | |
| public: | |
| LockingAdaptedIterable(const C &container, MutexType &mutex) | |
| : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) { | |
| m_mutex->lock(); | |
| } | |
| LockingAdaptedIterable(LockingAdaptedIterable &&rhs) | |
| : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex) { | |
| rhs.m_mutex = nullptr; | |
| } | |
| ~LockingAdaptedIterable() { | |
| if (m_mutex) | |
| m_mutex->unlock(); | |
| } | |
| private: | |
| MutexType *m_mutex = nullptr; | |
| LockingAdaptedIterable(const LockingAdaptedIterable &) = delete; | |
| LockingAdaptedIterable &operator=(const LockingAdaptedIterable &) = delete; | |
| }; | |
| } // namespace lldb_private | |
| #endif // LLDB_UTILITY_ITERABLE_H |