/// CopyFrom - implement operator= from a smallptrset that has the same pointer /// type, but may have a different small size. void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) { if (isSmall() && RHS.isSmall()) assert(CurArraySize == RHS.CurArraySize && "Cannot assign sets with different small sizes"); // If we're becoming small, prepare to insert into our stack space if (RHS.isSmall()) { if (!isSmall()) free(CurArray); CurArray = SmallArray; // Otherwise, allocate new heap space (unless we were the same size) } else if (CurArraySize != RHS.CurArraySize) { if (isSmall()) CurArray = (const void**)malloc(sizeof(void*) * RHS.CurArraySize); else CurArray = (const void**)realloc(CurArray, sizeof(void*)*RHS.CurArraySize); assert(CurArray && "Failed to allocate memory?"); } // Copy over the new array size CurArraySize = RHS.CurArraySize; // Copy over the contents from the other set memcpy(CurArray, RHS.CurArray, sizeof(void*)*CurArraySize); NumElements = RHS.NumElements; NumTombstones = RHS.NumTombstones; }
void SmallPtrSetImpl::swap(SmallPtrSetImpl &RHS) { if (this == &RHS) return; // We can only avoid copying elements if neither set is small. if (!this->isSmall() && !RHS.isSmall()) { std::swap(this->CurArray, RHS.CurArray); std::swap(this->CurArraySize, RHS.CurArraySize); std::swap(this->NumElements, RHS.NumElements); std::swap(this->NumTombstones, RHS.NumTombstones); return; } // FIXME: From here on we assume that both sets have the same small size. // If only RHS is small, copy the small elements into LHS and move the pointer // from LHS to RHS. if (!this->isSmall() && RHS.isSmall()) { std::copy(RHS.SmallArray, RHS.SmallArray+RHS.CurArraySize, this->SmallArray); std::swap(this->NumElements, RHS.NumElements); std::swap(this->CurArraySize, RHS.CurArraySize); RHS.CurArray = this->CurArray; RHS.NumTombstones = this->NumTombstones; this->CurArray = this->SmallArray; this->NumTombstones = 0; return; } // If only LHS is small, copy the small elements into RHS and move the pointer // from RHS to LHS. if (this->isSmall() && !RHS.isSmall()) { std::copy(this->SmallArray, this->SmallArray+this->CurArraySize, RHS.SmallArray); std::swap(RHS.NumElements, this->NumElements); std::swap(RHS.CurArraySize, this->CurArraySize); this->CurArray = RHS.CurArray; this->NumTombstones = RHS.NumTombstones; RHS.CurArray = RHS.SmallArray; RHS.NumTombstones = 0; return; } // Both a small, just swap the small elements. assert(this->isSmall() && RHS.isSmall()); assert(this->CurArraySize == RHS.CurArraySize); std::swap_ranges(this->SmallArray, this->SmallArray+this->CurArraySize, RHS.SmallArray); std::swap(this->NumElements, RHS.NumElements); }
SmallPtrSetImpl::SmallPtrSetImpl(const SmallPtrSetImpl& that) { NumElements = that.NumElements; NumTombstones = 0; if (that.isSmall()) { CurArraySize = that.CurArraySize; CurArray = &SmallArray[0]; memcpy(CurArray, that.CurArray, sizeof(void*)*CurArraySize); } else { CurArraySize = that.NumElements < 64 ? 128 : that.NumElements*2; CurArray = new void*[CurArraySize+1]; memset(CurArray, -1, CurArraySize*sizeof(void*)); // The end pointer, always valid, is set to a valid element to help the // iterator. CurArray[CurArraySize] = 0; // Copy over all valid entries. for (void **BucketPtr = that.CurArray, **E = that.CurArray+CurArraySize; BucketPtr != E; ++BucketPtr) { // Copy over the element if it is valid. void *Elt = *BucketPtr; if (Elt != getTombstoneMarker() && Elt != getEmptyMarker()) *const_cast<void**>(FindBucketFor(Elt)) = Elt; } } }
SmallPtrSetImpl::SmallPtrSetImpl(const SmallPtrSetImpl& that) { // If we're becoming small, prepare to insert into our stack space if (that.isSmall()) { CurArray = &SmallArray[0]; // Otherwise, allocate new heap space (unless we were the same size) } else { CurArray = (const void**)malloc(sizeof(void*) * (that.CurArraySize+1)); assert(CurArray && "Failed to allocate memory?"); } // Copy over the new array size CurArraySize = that.CurArraySize; // Copy over the contents from the other set memcpy(CurArray, that.CurArray, sizeof(void*)*(CurArraySize+1)); NumElements = that.NumElements; NumTombstones = that.NumTombstones; }