14 #ifndef LLVM_ADT_DENSEMAP_H
15 #define LLVM_ADT_DENSEMAP_H
38 template <
typename KeyT,
typename ValueT>
40 KeyT &
getFirst() {
return std::pair<KeyT, ValueT>::first; }
41 const KeyT &
getFirst()
const {
return std::pair<KeyT, ValueT>::first; }
42 ValueT &
getSecond() {
return std::pair<KeyT, ValueT>::second; }
43 const ValueT &
getSecond()
const {
return std::pair<KeyT, ValueT>::second; }
48 typename KeyT,
typename ValueT,
typename KeyInfoT = DenseMapInfo<KeyT>,
49 typename Bucket = detail::DenseMapPair<KeyT, ValueT>,
bool IsConst =
false>
52 template <
typename DerivedT,
typename KeyT,
typename ValueT,
typename KeyInfoT,
69 return iterator(getBucketsEnd(), getBucketsEnd(), *
this,
true);
76 return const_iterator(getBucketsEnd(), getBucketsEnd(), *
this,
true);
80 return getNumEntries() == 0;
82 unsigned size()
const {
return getNumEntries(); }
87 if (Size > getNumBuckets())
93 if (getNumEntries() == 0 && getNumTombstones() == 0)
return;
97 if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
103 unsigned NumEntries = getNumEntries();
104 for (BucketT *
P = getBuckets(), *E = getBucketsEnd();
P != E; ++
P) {
105 if (!KeyInfoT::isEqual(
P->getFirst(), EmptyKey)) {
106 if (!KeyInfoT::isEqual(
P->getFirst(), TombstoneKey)) {
107 P->getSecond().~ValueT();
110 P->getFirst() = EmptyKey;
113 assert(NumEntries == 0 &&
"Node count imbalance!");
120 const BucketT *TheBucket;
121 return LookupBucketFor(Val, TheBucket) ? 1 : 0;
126 if (LookupBucketFor(Val, TheBucket))
127 return iterator(TheBucket, getBucketsEnd(), *
this,
true);
131 const BucketT *TheBucket;
132 if (LookupBucketFor(Val, TheBucket))
142 template<
class LookupKeyT>
145 if (LookupBucketFor(Val, TheBucket))
146 return iterator(TheBucket, getBucketsEnd(), *
this,
true);
149 template<
class LookupKeyT>
151 const BucketT *TheBucket;
152 if (LookupBucketFor(Val, TheBucket))
160 const BucketT *TheBucket;
161 if (LookupBucketFor(Val, TheBucket))
162 return TheBucket->getSecond();
169 std::pair<iterator, bool>
insert(
const std::pair<KeyT, ValueT> &KV) {
171 if (LookupBucketFor(KV.first, TheBucket))
172 return std::make_pair(
iterator(TheBucket, getBucketsEnd(), *
this,
true),
176 TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
177 return std::make_pair(
iterator(TheBucket, getBucketsEnd(), *
this,
true),
184 std::pair<iterator, bool>
insert(std::pair<KeyT, ValueT> &&KV) {
186 if (LookupBucketFor(KV.first, TheBucket))
187 return std::make_pair(
iterator(TheBucket, getBucketsEnd(), *
this,
true),
191 TheBucket = InsertIntoBucket(std::move(KV.first),
192 std::move(KV.second),
194 return std::make_pair(
iterator(TheBucket, getBucketsEnd(), *
this,
true),
199 template<
typename InputIt>
208 if (!LookupBucketFor(Val, TheBucket))
211 TheBucket->getSecond().~ValueT();
213 decrementNumEntries();
214 incrementNumTombstones();
218 BucketT *TheBucket = &*
I;
219 TheBucket->getSecond().~ValueT();
221 decrementNumEntries();
222 incrementNumTombstones();
227 if (LookupBucketFor(Key, TheBucket))
230 return *InsertIntoBucket(Key, ValueT(), TheBucket);
239 if (LookupBucketFor(Key, TheBucket))
242 return *InsertIntoBucket(std::move(Key), ValueT(), TheBucket);
253 return Ptr >= getBuckets() && Ptr < getBucketsEnd();
265 if (getNumBuckets() == 0)
269 for (BucketT *
P = getBuckets(), *E = getBucketsEnd();
P != E; ++
P) {
270 if (!KeyInfoT::isEqual(
P->getFirst(), EmptyKey) &&
271 !KeyInfoT::isEqual(
P->getFirst(), TombstoneKey))
272 P->getSecond().~ValueT();
273 P->getFirst().~KeyT();
281 assert((getNumBuckets() & (getNumBuckets()-1)) == 0 &&
282 "# initial buckets must be a power of two!");
284 for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
285 new (&B->getFirst()) KeyT(EmptyKey);
294 for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) {
295 if (!KeyInfoT::isEqual(B->getFirst(), EmptyKey) &&
296 !KeyInfoT::isEqual(B->getFirst(), TombstoneKey)) {
299 bool FoundVal = LookupBucketFor(B->getFirst(), DestBucket);
301 assert(!FoundVal &&
"Key already in new map?");
302 DestBucket->getFirst() = std::move(B->getFirst());
303 new (&DestBucket->getSecond()) ValueT(std::move(B->getSecond()));
304 incrementNumEntries();
307 B->getSecond().~ValueT();
309 B->getFirst().~KeyT();
313 template <
typename OtherBaseT>
316 assert(&other !=
this);
317 assert(getNumBuckets() == other.getNumBuckets());
319 setNumEntries(other.getNumEntries());
320 setNumTombstones(other.getNumTombstones());
323 memcpy(getBuckets(), other.getBuckets(),
324 getNumBuckets() *
sizeof(BucketT));
326 for (
size_t i = 0; i < getNumBuckets(); ++i) {
327 new (&getBuckets()[i].getFirst())
328 KeyT(other.getBuckets()[i].getFirst());
329 if (!KeyInfoT::isEqual(getBuckets()[i].getFirst(),
getEmptyKey()) &&
331 new (&getBuckets()[i].getSecond())
332 ValueT(other.getBuckets()[i].getSecond());
337 return KeyInfoT::getHashValue(Val);
339 template<
typename LookupKeyT>
341 return KeyInfoT::getHashValue(Val);
344 return KeyInfoT::getEmptyKey();
347 return KeyInfoT::getTombstoneKey();
351 unsigned getNumEntries()
const {
352 return static_cast<const DerivedT *
>(
this)->getNumEntries();
354 void setNumEntries(
unsigned Num) {
355 static_cast<DerivedT *
>(
this)->setNumEntries(Num);
357 void incrementNumEntries() {
358 setNumEntries(getNumEntries() + 1);
360 void decrementNumEntries() {
361 setNumEntries(getNumEntries() - 1);
363 unsigned getNumTombstones()
const {
364 return static_cast<const DerivedT *
>(
this)->getNumTombstones();
366 void setNumTombstones(
unsigned Num) {
367 static_cast<DerivedT *
>(
this)->setNumTombstones(Num);
369 void incrementNumTombstones() {
370 setNumTombstones(getNumTombstones() + 1);
372 void decrementNumTombstones() {
373 setNumTombstones(getNumTombstones() - 1);
375 const BucketT *getBuckets()
const {
376 return static_cast<const DerivedT *
>(
this)->getBuckets();
378 BucketT *getBuckets() {
379 return static_cast<DerivedT *
>(
this)->getBuckets();
381 unsigned getNumBuckets()
const {
382 return static_cast<const DerivedT *
>(
this)->getNumBuckets();
384 BucketT *getBucketsEnd() {
385 return getBuckets() + getNumBuckets();
387 const BucketT *getBucketsEnd()
const {
388 return getBuckets() + getNumBuckets();
391 void grow(
unsigned AtLeast) {
392 static_cast<DerivedT *
>(
this)->grow(AtLeast);
395 void shrink_and_clear() {
396 static_cast<DerivedT *
>(
this)->shrink_and_clear();
400 BucketT *InsertIntoBucket(
const KeyT &Key,
const ValueT &Value,
401 BucketT *TheBucket) {
402 TheBucket = InsertIntoBucketImpl(Key, TheBucket);
404 TheBucket->getFirst() = Key;
405 new (&TheBucket->getSecond()) ValueT(Value);
409 BucketT *InsertIntoBucket(
const KeyT &Key, ValueT &&Value,
410 BucketT *TheBucket) {
411 TheBucket = InsertIntoBucketImpl(Key, TheBucket);
413 TheBucket->getFirst() = Key;
414 new (&TheBucket->getSecond()) ValueT(std::move(Value));
418 BucketT *InsertIntoBucket(KeyT &&Key, ValueT &&Value, BucketT *TheBucket) {
419 TheBucket = InsertIntoBucketImpl(Key, TheBucket);
421 TheBucket->getFirst() = std::move(Key);
422 new (&TheBucket->getSecond()) ValueT(std::move(Value));
426 BucketT *InsertIntoBucketImpl(
const KeyT &Key, BucketT *TheBucket) {
438 unsigned NewNumEntries = getNumEntries() + 1;
439 unsigned NumBuckets = getNumBuckets();
441 this->grow(NumBuckets * 2);
442 LookupBucketFor(Key, TheBucket);
443 NumBuckets = getNumBuckets();
444 }
else if (
LLVM_UNLIKELY(NumBuckets-(NewNumEntries+getNumTombstones()) <=
446 this->grow(NumBuckets);
447 LookupBucketFor(Key, TheBucket);
453 incrementNumEntries();
457 if (!KeyInfoT::isEqual(TheBucket->getFirst(), EmptyKey))
458 decrementNumTombstones();
467 template<
typename LookupKeyT>
468 bool LookupBucketFor(
const LookupKeyT &Val,
469 const BucketT *&FoundBucket)
const {
470 const BucketT *BucketsPtr = getBuckets();
471 const unsigned NumBuckets = getNumBuckets();
473 if (NumBuckets == 0) {
474 FoundBucket =
nullptr;
479 const BucketT *FoundTombstone =
nullptr;
482 assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
483 !KeyInfoT::isEqual(Val, TombstoneKey) &&
484 "Empty/Tombstone value shouldn't be inserted into map!");
487 unsigned ProbeAmt = 1;
489 const BucketT *ThisBucket = BucketsPtr + BucketNo;
491 if (
LLVM_LIKELY(KeyInfoT::isEqual(Val, ThisBucket->getFirst()))) {
492 FoundBucket = ThisBucket;
498 if (
LLVM_LIKELY(KeyInfoT::isEqual(ThisBucket->getFirst(), EmptyKey))) {
501 FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
507 if (KeyInfoT::isEqual(ThisBucket->getFirst(), TombstoneKey) &&
509 FoundTombstone = ThisBucket;
513 BucketNo += ProbeAmt++;
514 BucketNo &= (NumBuckets-1);
518 template <
typename LookupKeyT>
519 bool LookupBucketFor(
const LookupKeyT &Val, BucketT *&FoundBucket) {
520 const BucketT *ConstFoundBucket;
522 ->LookupBucketFor(Val, ConstFoundBucket);
523 FoundBucket =
const_cast<BucketT *
>(ConstFoundBucket);
533 return getNumBuckets() *
sizeof(BucketT);
537 template <
typename KeyT,
typename ValueT,
538 typename KeyInfoT = DenseMapInfo<KeyT>,
539 typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
541 KeyT, ValueT, KeyInfoT, BucketT> {
549 unsigned NumTombstones;
554 init(NumInitBuckets);
567 template<
typename InputIt>
575 operator delete(Buckets);
583 std::swap(NumTombstones, RHS.NumTombstones);
595 operator delete(Buckets);
603 operator delete(Buckets);
604 if (allocateBuckets(other.NumBuckets)) {
612 void init(
unsigned InitBuckets) {
613 if (allocateBuckets(InitBuckets)) {
622 unsigned OldNumBuckets = NumBuckets;
623 BucketT *OldBuckets = Buckets;
625 allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(
NextPowerOf2(AtLeast-1))));
635 operator delete(OldBuckets);
639 unsigned OldNumEntries = NumEntries;
643 unsigned NewNumBuckets = 0;
645 NewNumBuckets = std::max(64, 1 << (
Log2_32_Ceil(OldNumEntries) + 1));
646 if (NewNumBuckets == NumBuckets) {
651 operator delete(Buckets);
656 unsigned getNumEntries()
const {
659 void setNumEntries(
unsigned Num) {
663 unsigned getNumTombstones()
const {
664 return NumTombstones;
666 void setNumTombstones(
unsigned Num) {
670 BucketT *getBuckets()
const {
674 unsigned getNumBuckets()
const {
678 bool allocateBuckets(
unsigned Num) {
680 if (NumBuckets == 0) {
685 Buckets =
static_cast<BucketT*
>(
operator new(
sizeof(BucketT) * NumBuckets));
690 template <
typename KeyT,
typename ValueT,
unsigned InlineBuckets = 4,
691 typename KeyInfoT = DenseMapInfo<KeyT>,
692 typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
695 SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>, KeyT,
696 ValueT, KeyInfoT, BucketT> {
703 unsigned NumEntries : 31;
704 unsigned NumTombstones;
717 init(NumInitBuckets);
730 template<
typename InputIt>
742 unsigned TmpNumEntries = RHS.NumEntries;
743 RHS.NumEntries = NumEntries;
744 NumEntries = TmpNumEntries;
745 std::swap(NumTombstones, RHS.NumTombstones);
749 if (Small && RHS.Small) {
754 for (
unsigned i = 0, e = InlineBuckets; i != e; ++i) {
755 BucketT *LHSB = &getInlineBuckets()[i],
756 *RHSB = &RHS.getInlineBuckets()[i];
757 bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->getFirst(), EmptyKey) &&
758 !KeyInfoT::isEqual(LHSB->getFirst(), TombstoneKey));
759 bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->getFirst(), EmptyKey) &&
760 !KeyInfoT::isEqual(RHSB->getFirst(), TombstoneKey));
761 if (hasLHSValue && hasRHSValue) {
767 std::swap(LHSB->getFirst(), RHSB->getFirst());
769 new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
770 LHSB->getSecond().~ValueT();
771 }
else if (hasRHSValue) {
772 new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond()));
773 RHSB->getSecond().~ValueT();
778 if (!Small && !RHS.Small) {
779 std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets);
780 std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets);
788 LargeRep TmpRep = std::move(*LargeSide.getLargeRep());
789 LargeSide.getLargeRep()->~LargeRep();
790 LargeSide.Small =
true;
795 for (
unsigned i = 0, e = InlineBuckets; i != e; ++i) {
796 BucketT *NewB = &LargeSide.getInlineBuckets()[i],
797 *OldB = &SmallSide.getInlineBuckets()[i];
798 new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst()));
799 OldB->getFirst().~KeyT();
800 if (!KeyInfoT::isEqual(NewB->getFirst(), EmptyKey) &&
801 !KeyInfoT::isEqual(NewB->getFirst(), TombstoneKey)) {
802 new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond()));
803 OldB->getSecond().~ValueT();
809 SmallSide.Small =
false;
810 new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
831 if (other.getNumBuckets() > InlineBuckets) {
833 new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets()));
838 void init(
unsigned InitBuckets) {
840 if (InitBuckets > InlineBuckets) {
842 new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets));
848 if (AtLeast >= InlineBuckets)
849 AtLeast = std::max<unsigned>(64,
NextPowerOf2(AtLeast-1));
852 if (AtLeast < InlineBuckets)
857 BucketT *TmpBegin =
reinterpret_cast<BucketT *
>(TmpStorage.buffer);
858 BucketT *TmpEnd = TmpBegin;
864 for (BucketT *
P = getBuckets(), *E =
P + InlineBuckets;
P != E; ++
P) {
865 if (!KeyInfoT::isEqual(
P->getFirst(), EmptyKey) &&
866 !KeyInfoT::isEqual(
P->getFirst(), TombstoneKey)) {
867 assert(
size_t(TmpEnd - TmpBegin) < InlineBuckets &&
868 "Too many inline buckets!");
869 new (&TmpEnd->getFirst()) KeyT(std::move(
P->getFirst()));
870 new (&TmpEnd->getSecond()) ValueT(std::move(
P->getSecond()));
872 P->getSecond().~ValueT();
874 P->getFirst().~KeyT();
880 new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
885 LargeRep OldRep = std::move(*getLargeRep());
886 getLargeRep()->~LargeRep();
887 if (AtLeast <= InlineBuckets) {
890 new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
896 operator delete(OldRep.Buckets);
900 unsigned OldSize = this->
size();
904 unsigned NewNumBuckets = 0;
907 if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
910 if ((Small && NewNumBuckets <= InlineBuckets) ||
911 (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
921 unsigned getNumEntries()
const {
924 void setNumEntries(
unsigned Num) {
925 assert(Num < INT_MAX &&
"Cannot support more than INT_MAX entries");
929 unsigned getNumTombstones()
const {
930 return NumTombstones;
932 void setNumTombstones(
unsigned Num) {
936 const BucketT *getInlineBuckets()
const {
941 return reinterpret_cast<const BucketT *
>(storage.buffer);
943 BucketT *getInlineBuckets() {
944 return const_cast<BucketT *
>(
945 const_cast<const SmallDenseMap *
>(
this)->getInlineBuckets());
947 const LargeRep *getLargeRep()
const {
950 return reinterpret_cast<const LargeRep *
>(storage.buffer);
952 LargeRep *getLargeRep() {
953 return const_cast<LargeRep *
>(
957 const BucketT *getBuckets()
const {
958 return Small ? getInlineBuckets() : getLargeRep()->Buckets;
960 BucketT *getBuckets() {
961 return const_cast<BucketT *
>(
964 unsigned getNumBuckets()
const {
965 return Small ? InlineBuckets : getLargeRep()->NumBuckets;
968 void deallocateBuckets() {
972 operator delete(getLargeRep()->Buckets);
973 getLargeRep()->~LargeRep();
976 LargeRep allocateBuckets(
unsigned Num) {
977 assert(Num > InlineBuckets &&
"Must allocate more buckets than are inline");
979 static_cast<BucketT*
>(
operator new(
sizeof(BucketT) * Num)), Num
985 template <
typename KeyT,
typename ValueT,
typename KeyInfoT,
typename Bucket,
987 class DenseMapIterator : DebugEpochBase::HandleBase {
988 typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true> ConstIterator;
994 typedef typename std::conditional<IsConst, const Bucket, Bucket>::type
1005 bool NoAdvance =
false)
1007 assert(isHandleInSync() &&
"invalid construction!");
1008 if (!NoAdvance) AdvancePastEmptyBuckets();
1014 template <
bool IsConstSrc,
1015 typename =
typename std::enable_if<!IsConstSrc && IsConst>::type>
1021 assert(isHandleInSync() &&
"invalid iterator access!");
1025 assert(isHandleInSync() &&
"invalid iterator access!");
1030 assert((!Ptr || isHandleInSync()) &&
"handle not in sync!");
1031 assert((!RHS.Ptr || RHS.
isHandleInSync()) &&
"handle not in sync!");
1033 "comparing incomparable iterators!");
1034 return Ptr == RHS.Ptr;
1037 assert((!Ptr || isHandleInSync()) &&
"handle not in sync!");
1038 assert((!RHS.Ptr || RHS.
isHandleInSync()) &&
"handle not in sync!");
1040 "comparing incomparable iterators!");
1041 return Ptr != RHS.Ptr;
1045 assert(isHandleInSync() &&
"invalid iterator access!");
1047 AdvancePastEmptyBuckets();
1051 assert(isHandleInSync() &&
"invalid iterator access!");
1056 void AdvancePastEmptyBuckets() {
1057 const KeyT
Empty = KeyInfoT::getEmptyKey();
1058 const KeyT Tombstone = KeyInfoT::getTombstoneKey();
1060 while (Ptr != End && (KeyInfoT::isEqual(Ptr->getFirst(),
Empty) ||
1061 KeyInfoT::isEqual(Ptr->getFirst(), Tombstone)))
1066 template<
typename KeyT,
typename ValueT,
typename KeyInfoT>
1067 static inline size_t
unsigned Log2_32_Ceil(uint32_t Value)
Log2_32_Ceil - This function returns the ceil log base 2 of the specified value, 32 if the value is z...
ValueT & operator[](const KeyT &Key)
void copyFrom(const DenseMap &other)
void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd)
#define LLVM_ATTRIBUTE_UNUSED_RESULT
const_iterator find_as(const LookupKeyT &Val) const
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
#define LLVM_UNLIKELY(EXPR)
#define LLVM_LIKELY(EXPR)
const KeyT & getFirst() const
std::forward_iterator_tag iterator_category
void init(unsigned InitBuckets)
const_iterator begin() const
static const KeyT getTombstoneKey()
DenseMap(unsigned NumInitBuckets=0)
const_iterator end() const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
size_t getMemorySize() const
Return the approximate size (in bytes) of the actual map.
const void * getEpochAddress() const
const void * getPointerIntoBucketsArray() const
getPointerIntoBucketsArray() - Return an opaque pointer into the buckets array.
SmallDenseMap(SmallDenseMap &&other)
static const KeyT getEmptyKey()
void copyFrom(const DenseMapBase< OtherBaseT, KeyT, ValueT, KeyInfoT, BucketT > &other)
SmallDenseMap(unsigned NumInitBuckets=0)
void grow(unsigned AtLeast)
value_type & FindAndConstruct(const KeyT &Key)
bool isHandleInSync() const
bool erase(const KeyT &Val)
DenseMap(DenseMap &&other)
SmallDenseMap(const SmallDenseMap &other)
static unsigned getHashValue(const LookupKeyT &Val)
bool operator!=(const ConstIterator &RHS) const
void grow(unsigned AtLeast)
DenseMap(const DenseMap &other)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
std::conditional< IsConst, const Bucket, Bucket >::type value_type
uint64_t NextPowerOf2(uint64_t A)
NextPowerOf2 - Returns the next power of two (in 64-bits) that is strictly greater than A...
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
void insert(InputIt I, InputIt E)
insert - Range insertion of pairs.
void resize(size_type Size)
Grow the densemap so that it has at least Size buckets. Does not shrink.
SmallDenseMap & operator=(const SmallDenseMap &other)
isPodLike - This is a type trait that is used to determine whether a given type can be copied around ...
DenseMapIterator operator++(int)
static size_t capacity_in_bytes(const DenseMap< KeyT, ValueT, KeyInfoT > &X)
void swap(SmallDenseMap &RHS)
DenseMap & operator=(const DenseMap &other)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
SmallDenseMap & operator=(SmallDenseMap &&other)
void copyFrom(const SmallDenseMap &other)
bool isPointerIntoBucketsArray(const void *Ptr) const
isPointerIntoBucketsArray - Return true if the specified pointer points somewhere into the DenseMap's...
void init(unsigned InitBuckets)
DenseMapIterator & operator++()
ValueT & operator[](KeyT &&Key)
const_iterator find(const KeyT &Val) const
iterator find(const KeyT &Val)
std::pair< iterator, bool > insert(std::pair< KeyT, ValueT > &&KV)
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive, key type.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
const ValueT & getSecond() const
value_type & FindAndConstruct(KeyT &&Key)
SmallDenseMap(const InputIt &I, const InputIt &E)
DenseMap(const InputIt &I, const InputIt &E)
DenseMapIterator(const DenseMapIterator< KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc > &I)
bool operator==(const ConstIterator &RHS) const
DenseMap & operator=(DenseMap &&other)
reference operator*() const
DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch, bool NoAdvance=false)
ptrdiff_t difference_type
static unsigned getHashValue(const KeyT &Val)
pointer operator->() const