| From 5db7e9f9370a5e04949846cc68eeb13e2c1db187 Mon Sep 17 00:00:00 2001 |
| From: PJ Reiniger <pj.reiniger@gmail.com> |
| Date: Tue, 3 May 2022 22:16:10 -0400 |
| Subject: [PATCH 13/28] Extra collections features |
| |
| --- |
| llvm/include/llvm/ADT/StringMap.h | 103 +++++++++++++++++++++++++++++- |
| llvm/lib/Support/raw_ostream.cpp | 8 +++ |
| 2 files changed, 110 insertions(+), 1 deletion(-) |
| |
| diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h |
| index 8747cdb35..16f13f048 100644 |
| --- a/llvm/include/llvm/ADT/StringMap.h |
| +++ b/llvm/include/llvm/ADT/StringMap.h |
| @@ -42,7 +42,7 @@ protected: |
| |
| protected: |
| explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {} |
| - StringMapImpl(StringMapImpl &&RHS) |
| + StringMapImpl(StringMapImpl &&RHS) noexcept |
| : TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets), |
| NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones), |
| ItemSize(RHS.ItemSize) { |
| @@ -420,11 +420,27 @@ public: |
| return Tmp; |
| } |
| |
| + DerivedTy &operator--() { // Predecrement |
| + --Ptr; |
| + ReversePastEmptyBuckets(); |
| + return static_cast<DerivedTy &>(*this); |
| + } |
| + |
| + DerivedTy operator--(int) { // Post-decrement |
| + DerivedTy Tmp(Ptr); |
| + --*this; |
| + return Tmp; |
| + } |
| + |
| private: |
| void AdvancePastEmptyBuckets() { |
| while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal()) |
| ++Ptr; |
| } |
| + void ReversePastEmptyBuckets() { |
| + while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal()) |
| + --Ptr; |
| + } |
| }; |
| |
| template <typename ValueTy> |
| @@ -483,6 +499,91 @@ public: |
| std::string_view operator*() const { return this->wrapped()->getKey(); } |
| }; |
| |
| +template <typename ValueTy> |
| +bool operator==(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) { |
| + // same instance? |
| + if (&lhs == &rhs) return true; |
| + |
| + // first check that sizes are identical |
| + if (lhs.size() != rhs.size()) return false; |
| + |
| + // copy into vectors and sort by key |
| + SmallVector<StringMapConstIterator<ValueTy>, 16> lhs_items; |
| + lhs_items.reserve(lhs.size()); |
| + for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i) |
| + lhs_items.push_back(i); |
| + std::sort(lhs_items.begin(), lhs_items.end(), |
| + [](const StringMapConstIterator<ValueTy>& a, |
| + const StringMapConstIterator<ValueTy>& b) { |
| + return a->getKey() < b->getKey(); |
| + }); |
| + |
| + SmallVector<StringMapConstIterator<ValueTy>, 16> rhs_items; |
| + rhs_items.reserve(rhs.size()); |
| + for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i) |
| + rhs_items.push_back(i); |
| + std::sort(rhs_items.begin(), rhs_items.end(), |
| + [](const StringMapConstIterator<ValueTy>& a, |
| + const StringMapConstIterator<ValueTy>& b) { |
| + return a->getKey() < b->getKey(); |
| + }); |
| + |
| + // compare vector keys and values |
| + for (auto a = lhs_items.begin(), b = rhs_items.begin(), |
| + aend = lhs_items.end(), bend = rhs_items.end(); |
| + a != aend && b != bend; ++a, ++b) { |
| + if ((*a)->first() != (*b)->first() || (*a)->second != (*b)->second) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +template <typename ValueTy> |
| +inline bool operator!=(const StringMap<ValueTy>& lhs, |
| + const StringMap<ValueTy>& rhs) { |
| + return !(lhs == rhs); |
| +} |
| + |
| +template <typename ValueTy> |
| +bool operator<(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) { |
| + // same instance? |
| + if (&lhs == &rhs) return false; |
| + |
| + // copy into vectors and sort by key |
| + SmallVector<std::string_view, 16> lhs_keys; |
| + lhs_keys.reserve(lhs.size()); |
| + for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i) |
| + lhs_keys.push_back(i->getKey()); |
| + std::sort(lhs_keys.begin(), lhs_keys.end()); |
| + |
| + SmallVector<std::string_view, 16> rhs_keys; |
| + rhs_keys.reserve(rhs.size()); |
| + for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i) |
| + rhs_keys.push_back(i->getKey()); |
| + std::sort(rhs_keys.begin(), rhs_keys.end()); |
| + |
| + // use std::vector comparison |
| + return lhs_keys < rhs_keys; |
| +} |
| + |
| +template <typename ValueTy> |
| +inline bool operator<=(const StringMap<ValueTy>& lhs, |
| + const StringMap<ValueTy>& rhs) { |
| + return !(rhs < lhs); |
| +} |
| + |
| +template <typename ValueTy> |
| +inline bool operator>(const StringMap<ValueTy>& lhs, |
| + const StringMap<ValueTy>& rhs) { |
| + return !(lhs <= rhs); |
| +} |
| + |
| +template <typename ValueTy> |
| +inline bool operator>=(const StringMap<ValueTy>& lhs, |
| + const StringMap<ValueTy>& rhs) { |
| + return !(lhs < rhs); |
| +} |
| + |
| } // end namespace llvm |
| |
| #endif // LLVM_ADT_STRINGMAP_H |
| diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp |
| index 36faf744c..95152849c 100644 |
| --- a/llvm/lib/Support/raw_ostream.cpp |
| +++ b/llvm/lib/Support/raw_ostream.cpp |
| @@ -76,6 +76,14 @@ constexpr raw_ostream::Colors raw_ostream::WHITE; |
| constexpr raw_ostream::Colors raw_ostream::SAVEDCOLOR; |
| constexpr raw_ostream::Colors raw_ostream::RESET; |
| |
| +namespace { |
| +// Find the length of an array. |
| +template <class T, std::size_t N> |
| +constexpr inline size_t array_lengthof(T (&)[N]) { |
| + return N; |
| +} |
| +} // namespace |
| + |
| raw_ostream::~raw_ostream() { |
| // raw_ostream's subclasses should take care to flush the buffer |
| // in their destructors. |