Make the two StringMap iterators support iterator_facade_base. This fixes some usage scenarios when passing begin and end to various STL algorithms. After doing that, it's easy to make a StringMapKeysIterator that only iterates keys, so I've done that as well.
Details
Diff Detail
Event Timeline
Seems weird to have 'keys' on a StringSet, perhaps? (& to test StringSet in the StringMap unit test - as much as I realize the two types are very closely related)
Also, I'm wondering if keys() is necessary even on StringMap - I'd have thought a general-purpose "iterator of the first element of a pair" would suffice, but then remembered that StringMaps are special and their values are not pair<key, value> but have special accessors for the key, etc. So perhaps a lambda-driven iterator adapter... at which point, yeah, I can understand the utility of having that wrapped up in a reusable form.
llvm/include/llvm/ADT/StringExtras.h | ||
---|---|---|
255 ↗ | (On Diff #92433) | most of the other "iterator pair or range" algorithms use the same name for both (eg: all the llvm::any/all/none_of clones that take a range use the same name) - maybe use the same name here too ('join' rather than 'join_range') unless that causes some ambiguities? Also - this seems like an unrelated change for this patch (& arguably could use test coverage if it is going to be committed). Guess maybe it slipped into this change. |
llvm/include/llvm/ADT/StringMap.h | ||
474 | Generally it's advised that any op overload that can be a non-member should be, to allow equal implicit conversions on both sides. (it can still be a friend, though: friend bool operator==(LHS, RHS) { return LHS.Ptr == RHS.Ptr; } | |
539 | op* that returns by value - does that cause problems for op->? I forget... | |
llvm/unittests/Support/StringMap.cpp | ||
38 ↗ | (On Diff #92433) | In retrospect, maybe this function should be called To(Small)Vector? (Since there's no standard library function it's trying to emulate, etc - and it actually produces a SmallVector, not a std::vector, so the name is a bit vague/misleading (& makes the int non-type template parameter unclear/confusing)) |
llvm/include/llvm/ADT/StringExtras.h | ||
---|---|---|
255 ↗ | (On Diff #92433) | Yea I almost called it join, but then saw that we have join and join_items so join_range seemed to fit nicely. That said, join_items was introduced because of an ambiguity with join, but join_range won't have that ambiguity, so we could still call it join. |
llvm/include/llvm/ADT/StringMap.h | ||
539 | Should be fine, the StringRef should live until the end of the sequence point. |
- Fixed issue with returning by value from operator*.
- Moved the test from Support to ADT, since there was already an existing StringMapTest class there that I hadn't noticed.
- Removed the join changes that had snuck in. I'll commit those separately.
Some optional bits/pieces. (also - could include test coverage for op->. Or perhaps better/alternatively: put a static_assert in iterator_adapter_base to ensure that the return type of op* is a reference type?)
llvm/unittests/ADT/StringMapTest.cpp | ||
---|---|---|
287–300 | Not sure this test is necessary (I mean, depending on your perspective) - since it's testing the same API in StringMap that's inherited by StringSet - there's no new/interesting code under test here, compared to the previous test. (should StringSet's iterators actually be key iterators, rather than a 'keys()' operation on a set, which doesn't quite make sense - it only has keys, no values, so why would there be two different ranges to iterate over?) |
llvm/unittests/ADT/StringMapTest.cpp | ||
---|---|---|
287–300 |
True, but the same could be set for join_range vs join in the other patch. It doesn't matter to me either way though.
I could rename the function in StringSet by bringing keys() into protected scope with a using declaration, then make a function in StringSet called values() which simply returns the result of keys(). Thoughts? |
Generally it's advised that any op overload that can be a non-member should be, to allow equal implicit conversions on both sides. (it can still be a friend, though: