void SkTDStorage::reserve(int newCapacity) {
SkASSERT(newCapacity >= 0); if (newCapacity > fCapacity) { // Establish the maximum number of elements that includes a valid count for end. In the // largest case end() = &fArray[INT_MAX] which is 1 after the last indexable element. static constexpr int kMaxCount = INT_MAX;
// Assume that the array will max out. int expandedReserve = kMaxCount; if (kMaxCount - newCapacity > 4) { // Add 1/4 more than we need. Add 4 to ensure this grows by at least 1. Pin to // kMaxCount if no room for 1/4 growth. int growth = 4 + ((newCapacity + 4) >> 2); // Read this line as: if (count + growth < kMaxCount) { ... } // It's rewritten to avoid signed integer overflow. if (kMaxCount - newCapacity > growth) {
expandedReserve = newCapacity + growth;
}
}
// With a T size of 1, the above allocator produces the progression of 7, 15, ... Since, // the sizeof max_align_t is often 16, there is no reason to allocate anything less than // 16 bytes. This eliminates a realloc when pushing back bytes to an SkTDArray. if (fSizeOfT == 1) { // Round up to the multiple of 16.
expandedReserve = (expandedReserve + 15) & ~15;
}
void SkTDStorage::shrink_to_fit() { if (fCapacity != fSize) {
fCapacity = fSize; // Because calling realloc with size of 0 is implementation defined, force to a good state // by freeing fStorage. if (fCapacity > 0) {
fStorage = static_cast<std::byte*>(sk_realloc_throw(fStorage, this->bytes(fCapacity)));
} else {
sk_free(fStorage);
fStorage = nullptr;
}
}
}
void SkTDStorage::erase(int index, int count) {
SkASSERT(count >= 0);
SkASSERT(fSize >= count);
SkASSERT(0 <= index && index <= fSize);
if (count > 0) { // Check that the resulting size fits in an int. This will abort if not. constint newCount = this->calculateSizeOrDie(-count);
this->moveTail(index, index + count, fSize);
this->resize(newCount);
}
}
void SkTDStorage::removeShuffle(int index) {
SkASSERT(fSize > 0);
SkASSERT(0 <= index && index < fSize); // Check that the new count is valid. constint newCount = this->calculateSizeOrDie(-1);
this->moveTail(index, fSize - 1, fSize);
this->resize(newCount);
}
if (src != nullptr) {
this->copySrc(index, src, count);
}
}
return this->address(index);
}
booloperator==(const SkTDStorage& a, const SkTDStorage& b) { return a.size() == b.size() && (a.empty() || !memcmp(a.data(), b.data(), a.bytes(a.size())));
}
int SkTDStorage::calculateSizeOrDie(int delta) { // Check that count will not go negative.
SkASSERT_RELEASE(-fSize <= delta);
// We take care to avoid overflow here. // Because count and delta are both signed 32-bit ints, the sum of count and delta is at // most 4294967294, which fits fine in uint32_t. Proof follows in assert.
static_assert(UINT32_MAX >= (uint32_t)INT_MAX + (uint32_t)INT_MAX);
uint32_t testCount = (uint32_t)fSize + (uint32_t)delta;
SkASSERT_RELEASE(SkTFitsIn<int>(testCount)); return SkToInt(testCount);
}
void SkTDStorage::moveTail(int to, int tailStart, int tailEnd) {
SkASSERT(0 <= to && to <= fSize);
SkASSERT(0 <= tailStart && tailStart <= tailEnd && tailEnd <= fSize); if (to != tailStart && tailStart != tailEnd) {
this->copySrc(to, this->address(tailStart), tailEnd - tailStart);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.