2121#include " llvm/Support/PointerLikeTypeTraits.h"
2222#include < initializer_list>
2323#include < iterator>
24+ #include < type_traits>
2425
2526namespace llvm {
2627
27- template <typename ValueTy> class StringMapConstIterator ;
28- template <typename ValueTy> class StringMapIterator ;
28+ template <typename ValueTy, bool IsConst> class StringMapIterBase ;
2929template <typename ValueTy> class StringMapKeyIterator ;
3030
3131// / StringMapImpl - This is the base class of StringMap that is shared among
@@ -217,8 +217,8 @@ class LLVM_ALLOCATORHOLDER_EMPTYBASE StringMap
217217 using value_type = StringMapEntry<ValueTy>;
218218 using size_type = size_t ;
219219
220- using const_iterator = StringMapConstIterator <ValueTy>;
221- using iterator = StringMapIterator <ValueTy>;
220+ using const_iterator = StringMapIterBase <ValueTy, true >;
221+ using iterator = StringMapIterBase <ValueTy, false >;
222222
223223 iterator begin () { return iterator (TheTable, NumBuckets == 0 ); }
224224 iterator end () { return iterator (TheTable + NumBuckets, true ); }
@@ -431,14 +431,19 @@ class LLVM_ALLOCATORHOLDER_EMPTYBASE StringMap
431431 }
432432};
433433
434- template <typename DerivedTy, typename ValueTy>
435- class StringMapIterBase
436- : public iterator_facade_base<DerivedTy, std::forward_iterator_tag,
437- ValueTy> {
438- protected:
434+ template <typename ValueTy, bool IsConst> class StringMapIterBase {
435+ using EntryTy = std::conditional_t <IsConst, const StringMapEntry<ValueTy>,
436+ StringMapEntry<ValueTy>>;
437+
439438 StringMapEntryBase **Ptr = nullptr ;
440439
441440public:
441+ using iterator_category = std::forward_iterator_tag;
442+ using value_type = EntryTy;
443+ using difference_type = std::ptrdiff_t ;
444+ using pointer = value_type *;
445+ using reference = value_type &;
446+
442447 StringMapIterBase () = default ;
443448
444449 explicit StringMapIterBase (StringMapEntryBase **Bucket,
@@ -448,85 +453,56 @@ class StringMapIterBase
448453 AdvancePastEmptyBuckets ();
449454 }
450455
451- DerivedTy &operator =(const DerivedTy &Other) {
452- Ptr = Other.Ptr ;
453- return static_cast <DerivedTy &>(*this );
454- }
455-
456- friend bool operator ==(const DerivedTy &LHS, const DerivedTy &RHS) {
457- return LHS.Ptr == RHS.Ptr ;
458- }
456+ reference operator *() const { return *static_cast <EntryTy *>(*Ptr); }
457+ pointer operator ->() const { return &operator *(); }
459458
460- DerivedTy &operator ++() { // Preincrement
459+ StringMapIterBase &operator ++() { // Preincrement
461460 ++Ptr;
462461 AdvancePastEmptyBuckets ();
463- return static_cast <DerivedTy &>( *this ) ;
462+ return *this ;
464463 }
465464
466- DerivedTy operator ++(int ) { // Post-increment
467- DerivedTy Tmp (Ptr );
465+ StringMapIterBase operator ++(int ) { // Post-increment
466+ StringMapIterBase Tmp (* this );
468467 ++*this ;
469468 return Tmp;
470469 }
471470
472- private:
473- void AdvancePastEmptyBuckets () {
474- while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal ())
475- ++ Ptr;
471+ template < bool ToConst,
472+ typename = typename std::enable_if<!IsConst && ToConst>::type>
473+ operator StringMapIterBase<ValueTy, ToConst>() const {
474+ return StringMapIterBase<ValueTy, ToConst>( Ptr, true ) ;
476475 }
477- };
478-
479- template <typename ValueTy>
480- class StringMapConstIterator
481- : public StringMapIterBase<StringMapConstIterator<ValueTy>,
482- const StringMapEntry<ValueTy>> {
483- using base = StringMapIterBase<StringMapConstIterator<ValueTy>,
484- const StringMapEntry<ValueTy>>;
485-
486- public:
487- StringMapConstIterator () = default ;
488- explicit StringMapConstIterator (StringMapEntryBase **Bucket,
489- bool NoAdvance = false )
490- : base(Bucket, NoAdvance) {}
491476
492- const StringMapEntry<ValueTy> &operator *() const {
493- return *static_cast <const StringMapEntry<ValueTy> *>(*this ->Ptr );
477+ friend bool operator ==(const StringMapIterBase &LHS,
478+ const StringMapIterBase &RHS) {
479+ return LHS.Ptr == RHS.Ptr ;
494480 }
495- };
496-
497- template <typename ValueTy>
498- class StringMapIterator : public StringMapIterBase <StringMapIterator<ValueTy>,
499- StringMapEntry<ValueTy>> {
500- using base =
501- StringMapIterBase<StringMapIterator<ValueTy>, StringMapEntry<ValueTy>>;
502481
503- public:
504- StringMapIterator () = default ;
505- explicit StringMapIterator (StringMapEntryBase **Bucket,
506- bool NoAdvance = false )
507- : base(Bucket, NoAdvance) {}
508-
509- StringMapEntry<ValueTy> &operator *() const {
510- return *static_cast <StringMapEntry<ValueTy> *>(*this ->Ptr );
482+ friend bool operator !=(const StringMapIterBase &LHS,
483+ const StringMapIterBase &RHS) {
484+ return !(LHS == RHS);
511485 }
512486
513- operator StringMapConstIterator<ValueTy>() const {
514- return StringMapConstIterator<ValueTy>(this ->Ptr , true );
487+ private:
488+ void AdvancePastEmptyBuckets () {
489+ while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal ())
490+ ++Ptr;
515491 }
516492};
517493
518494template <typename ValueTy>
519495class StringMapKeyIterator
520496 : public iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
521- StringMapConstIterator <ValueTy>,
497+ StringMapIterBase <ValueTy, true >,
522498 std::forward_iterator_tag, StringRef> {
523499 using base = iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
524- StringMapConstIterator <ValueTy>,
500+ StringMapIterBase <ValueTy, true >,
525501 std::forward_iterator_tag, StringRef>;
526502
527503public:
528504 StringMapKeyIterator () = default ;
529- explicit StringMapKeyIterator (StringMapConstIterator <ValueTy> Iter)
505+ explicit StringMapKeyIterator (StringMapIterBase <ValueTy, true > Iter)
530506 : base(std::move(Iter)) {}
531507
532508 StringRef operator *() const { return this ->wrapped ()->getKey (); }
0 commit comments