/** *ReturnsapointertoaDwhichcomesbyteOffsetbytesafterS.
*/ template <typename D, typename S> inline D* SkTAddOffset(S* ptr, ptrdiff_t byteOffset) { // The intermediate char* has the same cv-ness as D as this produces better error messages. // This relies on the fact that reinterpret_cast can add constness, but cannot remove it. returnreinterpret_cast<D*>(reinterpret_cast<sknonstd::same_cv_t<char, D>*>(ptr) + byteOffset);
}
template <auto F> using SkFunctionObject =
SkOverloadedFunctionObject<std::remove_pointer_t<decltype(F)>, F>;
/** \class SkAutoTCallVProc
Callafunctionwhenthisgoesoutofscope.Thetemplateusestwo parameters,theobject,andafunctionthatistobecalledinthedestructor. Ifrelease()iscalled,theobjectreferenceissettonull.Iftheobject referenceisnullwhenthedestructoriscalled,wedonotcallthe function.
*/ template <typename T, void (*P)(T*)> class [[nodiscard]] SkAutoTCallVProc
: public std::unique_ptr<T, SkFunctionObject<P>> { using inherited = std::unique_ptr<T, SkFunctionObject<P>>; public: using inherited::inherited;
SkAutoTCallVProc(const SkAutoTCallVProc&) = delete;
SkAutoTCallVProc(SkAutoTCallVProc&& that) : inherited(std::move(that)) {}
operator T*() const { returnthis->get(); }
};
namespace skia_private { /** Allocate an array of T elements on the heap. Once this goes out of scope, the *elementswillbecleanedup"auto"matically.
*/ template <typename T> class AutoTArray { public:
AutoTArray() {} // Allocate size number of T elements explicit AutoTArray(size_t size)
: fData(size > 0 ? new T[check_size_bytes_too_big<T>(size)] : nullptr)
, fSize(size) {}
// TODO: remove when all uses are gone. explicit AutoTArray(int size) : AutoTArray(SkToSizeT(size)) {}
// Reallocates given a new count. Reallocation occurs even if new count equals old count.
SK_REINITIALIZES void reset(size_t count = 0) {
*this = AutoTArray(count);
}
// It's safe to use fItemArray + fSize because if fItemArray is nullptr then adding 0 is // valid and returns nullptr. See [expr.add] in the C++ standard.
T* end() { if (fData == nullptr) {
SkASSERT(fSize == 0);
} returnthis->begin() + fSize;
} const T* end() const { if (fData == nullptr) {
SkASSERT(fSize == 0);
} returnthis->begin() + fSize;
}
/** Like AutoTArray with storage for some number of elements "nested within". The requested number *ofelementstofitinthestorageisspecifiedbykCountRequested.kCountistheactualnumber *ofelementsthatwillfitinthestorage.Iftheruntimenumberofelementsexceedsthespaceof *thestorage,theelementswillliveontheheap.
*/ template <int kCountRequested, typename T> class AutoSTArray { public:
AutoSTArray(const AutoSTArray&) = delete;
AutoSTArray& operator=(const AutoSTArray&) = delete;
/** Initialize with no objects */
AutoSTArray() {
fArray = nullptr;
fCount = 0;
}
/** Allocate count number of T elements */
AutoSTArray(int count) {
fArray = nullptr;
fCount = 0; this->reset(count);
}
~AutoSTArray() { this->reset(0);
}
/** Destroys previous objects in the array and default constructs count number of objects */
SK_REINITIALIZES void reset(int count) {
T* start = begin();
T* iter = end(); while (iter > start) {
(--iter)->~T();
}
SkASSERT(count >= 0); if (fCount != count) { if (fArray != (T*) fStorage) {
sk_free(fArray);
}
private: #ifdefined(SK_BUILD_FOR_GOOGLE3) // Stack frame size is limited for SK_BUILD_FOR_GOOGLE3. 4k is less than the actual max, // but some functions have multiple large stack allocations. static constexpr int kMaxBytes = 4 * 1024; static constexpr int kMinCount = kCountRequested * sizeof(T) > kMaxBytes
? kMaxBytes / sizeof(T)
: kCountRequested; #else static constexpr int kMinCount = kCountRequested; #endif
// Because we are also storing an int, there is a tiny bit of padding that // the C++ compiler adds after fStorage if sizeof(T) <= alignof(T*). // Thus, we can expand how many elements are stored on the stack to make use of this // (e.g. 1 extra element for 4 byte T if kCountRequested was even).
static_assert(alignof(int) <= alignof(T*) || alignof(int) <= alignof(T)); public: static constexpr int kCount =
SkAlignTo(kMinCount*sizeof(T) + sizeof(int), std::max(alignof(T*), alignof(T))) / sizeof(T);
/** Manages an array of T elements, freeing the array in the destructor. *DoesNOTcallanyconstructors/destructorsonT(TmustbePOD).
*/ template <typename T, typename = std::enable_if_t<std::is_trivially_default_constructible<T>::value &&
std::is_trivially_destructible<T>::value>> class AutoTMalloc { public: /** Takes ownership of the ptr. The ptr must be a value which can be passed to sk_free. */ explicit AutoTMalloc(T* ptr = nullptr) : fPtr(ptr) {}
/** Allocates space for 'count' Ts. */ explicit AutoTMalloc(size_t count)
: fPtr(count ? (T*)sk_malloc_throw(count, sizeof(T)) : nullptr) {}
/** Resize the memory area pointed to by the current ptr preserving contents. */ void realloc(size_t count) {
fPtr.reset(count ? (T*)sk_realloc_throw(fPtr.release(), count * sizeof(T)) : nullptr);
}
/** Resize the memory area pointed to by the current ptr without preserving contents. */
SK_REINITIALIZES
T* reset(size_t count = 0) {
fPtr.reset(count ? (T*)sk_malloc_throw(count, sizeof(T)) : nullptr); returnthis->get();
}
// Reallocs the array, can be used to shrink the allocation. Makes no attempt to be intelligent void realloc(size_t count) { if (count > kCount) { if (fPtr == fTStorage) {
fPtr = (T*)sk_malloc_throw(count, sizeof(T));
memcpy((void*)fPtr, fTStorage, kCount * sizeof(T));
} else {
fPtr = (T*)sk_realloc_throw(fPtr, count, sizeof(T));
}
} elseif (count) { if (fPtr != fTStorage) {
fPtr = (T*)sk_realloc_throw(fPtr, count, sizeof(T));
}
} else { this->reset(0);
}
}
private: // Since we use uint32_t storage, we might be able to get more elements for free. static constexpr size_t kCountWithPadding = SkAlign4(kCountRequested*sizeof(T)) / sizeof(T); #ifdefined(SK_BUILD_FOR_GOOGLE3) // Stack frame size is limited for SK_BUILD_FOR_GOOGLE3. 4k is less than the actual max, but some functions // have multiple large stack allocations. static constexpr size_t kMaxBytes = 4 * 1024; static constexpr size_t kMinCount = kCountRequested * sizeof(T) > kMaxBytes
? kMaxBytes / sizeof(T)
: kCountWithPadding; #else static constexpr size_t kMinCount = kCountWithPadding; #endif
template<size_t N, typename C> constexpr auto SkMakeArray(C c)
-> std::array<decltype(c(std::declval<typename std::index_sequence<N>::value_type>())), N> { return SkMakeArrayFromIndexSequence(c, std::make_index_sequence<N>{});
}
#endif
Messung V0.5 in Prozent
¤ 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.0.14Bemerkung:
(vorverarbeitet am 2026-09-30)
¤
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.