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,17 @@ 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 {
439435 StringMapEntryBase **Ptr = nullptr ;
440436
441437public:
438+ using iterator_category = std::forward_iterator_tag;
439+ using value_type = StringMapEntry<ValueTy>;
440+ using difference_type = std::ptrdiff_t ;
441+ using pointer = std::conditional_t <IsConst, const value_type *, value_type *>;
442+ using reference =
443+ std::conditional_t <IsConst, const value_type &, value_type &>;
444+
442445 StringMapIterBase () = default ;
443446
444447 explicit StringMapIterBase (StringMapEntryBase **Bucket,
@@ -448,85 +451,56 @@ class StringMapIterBase
448451 AdvancePastEmptyBuckets ();
449452 }
450453
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- }
454+ reference operator *() const { return *static_cast <value_type *>(*Ptr); }
455+ pointer operator ->() const { return static_cast <value_type *>(*Ptr); }
459456
460- DerivedTy &operator ++() { // Preincrement
457+ StringMapIterBase &operator ++() { // Preincrement
461458 ++Ptr;
462459 AdvancePastEmptyBuckets ();
463- return static_cast <DerivedTy &>( *this ) ;
460+ return *this ;
464461 }
465462
466- DerivedTy operator ++(int ) { // Post-increment
467- DerivedTy Tmp (Ptr );
463+ StringMapIterBase operator ++(int ) { // Post-increment
464+ StringMapIterBase Tmp (* this );
468465 ++*this ;
469466 return Tmp;
470467 }
471468
472- private:
473- void AdvancePastEmptyBuckets () {
474- while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal ())
475- ++ Ptr;
469+ template < bool ToConst,
470+ typename = typename std::enable_if<!IsConst && ToConst>::type>
471+ operator StringMapIterBase<ValueTy, ToConst>() const {
472+ return StringMapIterBase<ValueTy, ToConst>( Ptr, true ) ;
476473 }
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) {}
491474
492- const StringMapEntry<ValueTy> &operator *() const {
493- return *static_cast <const StringMapEntry<ValueTy> *>(*this ->Ptr );
475+ friend bool operator ==(const StringMapIterBase &LHS,
476+ const StringMapIterBase &RHS) {
477+ return LHS.Ptr == RHS.Ptr ;
494478 }
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>>;
502479
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 );
480+ friend bool operator !=(const StringMapIterBase &LHS,
481+ const StringMapIterBase &RHS) {
482+ return !(LHS == RHS);
511483 }
512484
513- operator StringMapConstIterator<ValueTy>() const {
514- return StringMapConstIterator<ValueTy>(this ->Ptr , true );
485+ private:
486+ void AdvancePastEmptyBuckets () {
487+ while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal ())
488+ ++Ptr;
515489 }
516490};
517491
518492template <typename ValueTy>
519493class StringMapKeyIterator
520494 : public iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
521- StringMapConstIterator <ValueTy>,
495+ StringMapIterBase <ValueTy, true >,
522496 std::forward_iterator_tag, StringRef> {
523497 using base = iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
524- StringMapConstIterator <ValueTy>,
498+ StringMapIterBase <ValueTy, true >,
525499 std::forward_iterator_tag, StringRef>;
526500
527501public:
528502 StringMapKeyIterator () = default ;
529- explicit StringMapKeyIterator (StringMapConstIterator <ValueTy> Iter)
503+ explicit StringMapKeyIterator (StringMapIterBase <ValueTy, true > Iter)
530504 : base(std::move(Iter)) {}
531505
532506 StringRef operator *() const { return this ->wrapped ()->getKey (); }
0 commit comments