blob: 7da2c106a6406d6f120cb5b12fc59b7cc365adf9 [file] [log] [blame]
From 0000000000000000000000000000000000000000 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 12/31] 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 34dfbf83c681f4e81a9dadd9382ddca6ef8d6c1d..c133e84f9b2e3a225cdac782c011fadbf07adab2 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) {
@@ -432,11 +432,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>
@@ -495,6 +511,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 dcdfdfd7a8e3fcc4019538a4fc9e158aeda0a8b8..b2a726633b48b179abfd24a5de110a2301e0f877 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.