From 5db7e9f9370a5e04949846cc68eeb13e2c1db187 Mon Sep 17 00:00:00 2001 From: PJ Reiniger 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(*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 @@ -483,6 +499,91 @@ public: std::string_view operator*() const { return this->wrapped()->getKey(); } }; +template +bool operator==(const StringMap& lhs, const StringMap& 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, 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& a, + const StringMapConstIterator& b) { + return a->getKey() < b->getKey(); + }); + + SmallVector, 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& a, + const StringMapConstIterator& 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 +inline bool operator!=(const StringMap& lhs, + const StringMap& rhs) { + return !(lhs == rhs); +} + +template +bool operator<(const StringMap& lhs, const StringMap& rhs) { + // same instance? + if (&lhs == &rhs) return false; + + // copy into vectors and sort by key + SmallVector 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 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 +inline bool operator<=(const StringMap& lhs, + const StringMap& rhs) { + return !(rhs < lhs); +} + +template +inline bool operator>(const StringMap& lhs, + const StringMap& rhs) { + return !(lhs <= rhs); +} + +template +inline bool operator>=(const StringMap& lhs, + const StringMap& 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 +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.