diff options
author | mcheshkov <mcheshkov@yandex-team.ru> | 2022-02-10 16:46:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:15 +0300 |
commit | e9d19cec64684c9c1e6b0c98297e5b895cf904fe (patch) | |
tree | 2768b1223e96a8a0610a93d18425d9647c1123c8 /contrib/libs/icu/common/cmemory.h | |
parent | 60040c91ffe701a84689b2c6310ff845e65cff42 (diff) | |
download | ydb-e9d19cec64684c9c1e6b0c98297e5b895cf904fe.tar.gz |
Restoring authorship annotation for <mcheshkov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/icu/common/cmemory.h')
-rw-r--r-- | contrib/libs/icu/common/cmemory.h | 504 |
1 files changed, 252 insertions, 252 deletions
diff --git a/contrib/libs/icu/common/cmemory.h b/contrib/libs/icu/common/cmemory.h index 8d60442021..9121f3f8b5 100644 --- a/contrib/libs/icu/common/cmemory.h +++ b/contrib/libs/icu/common/cmemory.h @@ -1,4 +1,4 @@ -// © 2016 and later: Unicode, Inc. and others. +// © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** @@ -50,7 +50,7 @@ #define UPRV_LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) #define uprv_memset(buffer, mark, size) U_STANDARD_CPP_NAMESPACE memset(buffer, mark, size) #define uprv_memcmp(buffer1, buffer2, size) U_STANDARD_CPP_NAMESPACE memcmp(buffer1, buffer2,size) -#define uprv_memchr(ptr, value, num) U_STANDARD_CPP_NAMESPACE memchr(ptr, value, num) +#define uprv_memchr(ptr, value, num) U_STANDARD_CPP_NAMESPACE memchr(ptr, value, num) U_CAPI void * U_EXPORT2 uprv_malloc(size_t s) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR(1); @@ -69,32 +69,32 @@ uprv_calloc(size_t num, size_t size) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR2(1,2); * For example, with a mask of 3, the macro gets the 2 least significant bits, * which will be 0 if the pointer is 32-bit (4-byte) aligned. * - * uintptr_t is the most appropriate integer type to cast to. + * uintptr_t is the most appropriate integer type to cast to. */ -#define U_POINTER_MASK_LSB(ptr, mask) ((uintptr_t)(ptr) & (mask)) +#define U_POINTER_MASK_LSB(ptr, mask) ((uintptr_t)(ptr) & (mask)) /** - * Create & return an instance of "type" in statically allocated storage. - * e.g. - * static std::mutex *myMutex = STATIC_NEW(std::mutex); - * To destroy an object created in this way, invoke the destructor explicitly, e.g. - * myMutex->~mutex(); - * DO NOT use delete. - * DO NOT use with class UMutex, which has specific support for static instances. - * - * STATIC_NEW is intended for use when - * - We want a static (or global) object. - * - We don't want it to ever be destructed, or to explicitly control destruction, - * to avoid use-after-destruction problems. - * - We want to avoid an ordinary heap allocated object, - * to avoid the possibility of memory allocation failures, and - * to avoid memory leak reports, from valgrind, for example. - * This is defined as a macro rather than a template function because each invocation - * must define distinct static storage for the object being returned. + * Create & return an instance of "type" in statically allocated storage. + * e.g. + * static std::mutex *myMutex = STATIC_NEW(std::mutex); + * To destroy an object created in this way, invoke the destructor explicitly, e.g. + * myMutex->~mutex(); + * DO NOT use delete. + * DO NOT use with class UMutex, which has specific support for static instances. + * + * STATIC_NEW is intended for use when + * - We want a static (or global) object. + * - We don't want it to ever be destructed, or to explicitly control destruction, + * to avoid use-after-destruction problems. + * - We want to avoid an ordinary heap allocated object, + * to avoid the possibility of memory allocation failures, and + * to avoid memory leak reports, from valgrind, for example. + * This is defined as a macro rather than a template function because each invocation + * must define distinct static storage for the object being returned. */ -#define STATIC_NEW(type) [] () { \ - alignas(type) static char storage[sizeof(type)]; \ - return new(storage) type();} () +#define STATIC_NEW(type) [] () { \ + alignas(type) static char storage[sizeof(type)]; \ + return new(storage) type();} () /** * Heap clean up function, called from u_cleanup() @@ -122,9 +122,9 @@ uprv_deleteUObject(void *obj); #ifdef __cplusplus -#include <utility> -#include "unicode/uobject.h" - +#include <utility> +#include "unicode/uobject.h" + U_NAMESPACE_BEGIN /** @@ -164,7 +164,7 @@ public: * @return *this */ LocalMemory<T> &operator=(LocalMemory<T> &&src) U_NOEXCEPT { - uprv_free(LocalPointerBase<T>::ptr); + uprv_free(LocalPointerBase<T>::ptr); LocalPointerBase<T>::ptr=src.ptr; src.ptr=NULL; return *this; @@ -271,49 +271,49 @@ inline T *LocalMemory<T>::allocateInsteadAndCopy(int32_t newCapacity, int32_t le * * Unlike LocalMemory and LocalArray, this class never adopts * (takes ownership of) another array. - * - * WARNING: MaybeStackArray only works with primitive (plain-old data) types. - * It does NOT know how to call a destructor! If you work with classes with - * destructors, consider: - * - * - LocalArray in localpointer.h if you know the length ahead of time - * - MaybeStackVector if you know the length at runtime + * + * WARNING: MaybeStackArray only works with primitive (plain-old data) types. + * It does NOT know how to call a destructor! If you work with classes with + * destructors, consider: + * + * - LocalArray in localpointer.h if you know the length ahead of time + * - MaybeStackVector if you know the length at runtime */ template<typename T, int32_t stackCapacity> class MaybeStackArray { public: - // No heap allocation. Use only on the stack. - static void* U_EXPORT2 operator new(size_t) U_NOEXCEPT = delete; - static void* U_EXPORT2 operator new[](size_t) U_NOEXCEPT = delete; -#if U_HAVE_PLACEMENT_NEW - static void* U_EXPORT2 operator new(size_t, void*) U_NOEXCEPT = delete; -#endif - + // No heap allocation. Use only on the stack. + static void* U_EXPORT2 operator new(size_t) U_NOEXCEPT = delete; + static void* U_EXPORT2 operator new[](size_t) U_NOEXCEPT = delete; +#if U_HAVE_PLACEMENT_NEW + static void* U_EXPORT2 operator new(size_t, void*) U_NOEXCEPT = delete; +#endif + /** * Default constructor initializes with internal T[stackCapacity] buffer. */ MaybeStackArray() : ptr(stackArray), capacity(stackCapacity), needToRelease(FALSE) {} /** - * Automatically allocates the heap array if the argument is larger than the stack capacity. - * Intended for use when an approximate capacity is known at compile time but the true - * capacity is not known until runtime. - */ - MaybeStackArray(int32_t newCapacity) : MaybeStackArray() { - if (capacity < newCapacity) { resize(newCapacity); } - } - /** + * Automatically allocates the heap array if the argument is larger than the stack capacity. + * Intended for use when an approximate capacity is known at compile time but the true + * capacity is not known until runtime. + */ + MaybeStackArray(int32_t newCapacity) : MaybeStackArray() { + if (capacity < newCapacity) { resize(newCapacity); } + } + /** * Destructor deletes the array (if owned). */ ~MaybeStackArray() { releaseArray(); } /** - * Move constructor: transfers ownership or copies the stack array. - */ - MaybeStackArray(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT; - /** - * Move assignment: transfers ownership or copies the stack array. - */ - MaybeStackArray<T, stackCapacity> &operator=(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT; - /** + * Move constructor: transfers ownership or copies the stack array. + */ + MaybeStackArray(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT; + /** + * Move assignment: transfers ownership or copies the stack array. + */ + MaybeStackArray<T, stackCapacity> &operator=(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT; + /** * Returns the array capacity (number of T items). * @return array capacity */ @@ -390,11 +390,11 @@ private: uprv_free(ptr); } } - void resetToStackArray() { - ptr=stackArray; - capacity=stackCapacity; - needToRelease=FALSE; - } + void resetToStackArray() { + ptr=stackArray; + capacity=stackCapacity; + needToRelease=FALSE; + } /* No comparison operators with other MaybeStackArray's. */ bool operator==(const MaybeStackArray & /*other*/) {return FALSE;} bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;} @@ -404,34 +404,34 @@ private: }; template<typename T, int32_t stackCapacity> -icu::MaybeStackArray<T, stackCapacity>::MaybeStackArray( - MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT - : ptr(src.ptr), capacity(src.capacity), needToRelease(src.needToRelease) { - if (src.ptr == src.stackArray) { - ptr = stackArray; - uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity); - } else { - src.resetToStackArray(); // take ownership away from src - } -} - -template<typename T, int32_t stackCapacity> -inline MaybeStackArray <T, stackCapacity>& -MaybeStackArray<T, stackCapacity>::operator=(MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT { - releaseArray(); // in case this instance had its own memory allocated - capacity = src.capacity; - needToRelease = src.needToRelease; - if (src.ptr == src.stackArray) { - ptr = stackArray; - uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity); - } else { - ptr = src.ptr; - src.resetToStackArray(); // take ownership away from src - } - return *this; -} - -template<typename T, int32_t stackCapacity> +icu::MaybeStackArray<T, stackCapacity>::MaybeStackArray( + MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT + : ptr(src.ptr), capacity(src.capacity), needToRelease(src.needToRelease) { + if (src.ptr == src.stackArray) { + ptr = stackArray; + uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity); + } else { + src.resetToStackArray(); // take ownership away from src + } +} + +template<typename T, int32_t stackCapacity> +inline MaybeStackArray <T, stackCapacity>& +MaybeStackArray<T, stackCapacity>::operator=(MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT { + releaseArray(); // in case this instance had its own memory allocated + capacity = src.capacity; + needToRelease = src.needToRelease; + if (src.ptr == src.stackArray) { + ptr = stackArray; + uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity); + } else { + ptr = src.ptr; + src.resetToStackArray(); // take ownership away from src + } + return *this; +} + +template<typename T, int32_t stackCapacity> inline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) { if(newCapacity>0) { #if U_DEBUG && defined(UPRV_MALLOC_COUNT) @@ -480,7 +480,7 @@ inline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32 uprv_memcpy(p, ptr, (size_t)length*sizeof(T)); } resultCapacity=length; - resetToStackArray(); + resetToStackArray(); return p; } @@ -497,13 +497,13 @@ inline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32 template<typename H, typename T, int32_t stackCapacity> class MaybeStackHeaderAndArray { public: - // No heap allocation. Use only on the stack. - static void* U_EXPORT2 operator new(size_t) U_NOEXCEPT = delete; - static void* U_EXPORT2 operator new[](size_t) U_NOEXCEPT = delete; -#if U_HAVE_PLACEMENT_NEW - static void* U_EXPORT2 operator new(size_t, void*) U_NOEXCEPT = delete; -#endif - + // No heap allocation. Use only on the stack. + static void* U_EXPORT2 operator new(size_t) U_NOEXCEPT = delete; + static void* U_EXPORT2 operator new[](size_t) U_NOEXCEPT = delete; +#if U_HAVE_PLACEMENT_NEW + static void* U_EXPORT2 operator new(size_t, void*) U_NOEXCEPT = delete; +#endif + /** * Default constructor initializes with internal H+T[stackCapacity] buffer. */ @@ -661,159 +661,159 @@ inline H *MaybeStackHeaderAndArray<H, T, stackCapacity>::orphanOrClone(int32_t l return p; } -/** - * A simple memory management class that creates new heap allocated objects (of - * any class that has a public constructor), keeps track of them and eventually - * deletes them all in its own destructor. - * - * A typical use-case would be code like this: - * - * MemoryPool<MyType> pool; - * - * MyType* o1 = pool.create(); - * if (o1 != nullptr) { - * foo(o1); - * } - * - * MyType* o2 = pool.create(1, 2, 3); - * if (o2 != nullptr) { - * bar(o2); - * } - * - * // MemoryPool will take care of deleting the MyType objects. - * - * It doesn't do anything more than that, and is intentionally kept minimalist. - */ -template<typename T, int32_t stackCapacity = 8> -class MemoryPool : public UMemory { -public: - MemoryPool() : fCount(0), fPool() {} - - ~MemoryPool() { - for (int32_t i = 0; i < fCount; ++i) { - delete fPool[i]; - } - } - - MemoryPool(const MemoryPool&) = delete; - MemoryPool& operator=(const MemoryPool&) = delete; - - MemoryPool(MemoryPool&& other) U_NOEXCEPT : fCount(other.fCount), - fPool(std::move(other.fPool)) { - other.fCount = 0; - } - - MemoryPool& operator=(MemoryPool&& other) U_NOEXCEPT { - fCount = other.fCount; - fPool = std::move(other.fPool); - other.fCount = 0; - return *this; - } - - /** - * Creates a new object of typename T, by forwarding any and all arguments - * to the typename T constructor. - * - * @param args Arguments to be forwarded to the typename T constructor. - * @return A pointer to the newly created object, or nullptr on error. - */ - template<typename... Args> - T* create(Args&&... args) { - int32_t capacity = fPool.getCapacity(); - if (fCount == capacity && - fPool.resize(capacity == stackCapacity ? 4 * capacity : 2 * capacity, - capacity) == nullptr) { - return nullptr; - } - return fPool[fCount++] = new T(std::forward<Args>(args)...); - } - - /** - * @return Number of elements that have been allocated. - */ - int32_t count() const { - return fCount; - } - -protected: - int32_t fCount; - MaybeStackArray<T*, stackCapacity> fPool; -}; - -/** - * An internal Vector-like implementation based on MemoryPool. - * - * Heap-allocates each element and stores pointers. - * - * To append an item to the vector, use emplaceBack. - * - * MaybeStackVector<MyType> vector; - * MyType* element = vector.emplaceBack(); - * if (!element) { - * status = U_MEMORY_ALLOCATION_ERROR; - * } - * // do stuff with element - * - * To loop over the vector, use a for loop with indices: - * - * for (int32_t i = 0; i < vector.length(); i++) { - * MyType* element = vector[i]; - * } - */ -template<typename T, int32_t stackCapacity = 8> -class MaybeStackVector : protected MemoryPool<T, stackCapacity> { -public: - using MemoryPool<T, stackCapacity>::MemoryPool; - using MemoryPool<T, stackCapacity>::operator=; - - template<typename... Args> - T* emplaceBack(Args&&... args) { - return this->create(args...); - } - - int32_t length() const { - return this->fCount; - } - - T** getAlias() { - return this->fPool.getAlias(); - } - - /** - * Array item access (read-only). - * No index bounds check. - * @param i array index - * @return reference to the array item - */ - const T* operator[](ptrdiff_t i) const { - return this->fPool[i]; - } - - /** - * Array item access (writable). - * No index bounds check. - * @param i array index - * @return reference to the array item - */ - T* operator[](ptrdiff_t i) { - return this->fPool[i]; - } - - /** - * Append all the items from another MaybeStackVector to this one. - */ - void appendAll(const MaybeStackVector& other, UErrorCode& status) { - for (int32_t i = 0; i < other.fCount; i++) { - T* item = emplaceBack(*other[i]); - if (!item) { - status = U_MEMORY_ALLOCATION_ERROR; - return; - } - } - } -}; - - +/** + * A simple memory management class that creates new heap allocated objects (of + * any class that has a public constructor), keeps track of them and eventually + * deletes them all in its own destructor. + * + * A typical use-case would be code like this: + * + * MemoryPool<MyType> pool; + * + * MyType* o1 = pool.create(); + * if (o1 != nullptr) { + * foo(o1); + * } + * + * MyType* o2 = pool.create(1, 2, 3); + * if (o2 != nullptr) { + * bar(o2); + * } + * + * // MemoryPool will take care of deleting the MyType objects. + * + * It doesn't do anything more than that, and is intentionally kept minimalist. + */ +template<typename T, int32_t stackCapacity = 8> +class MemoryPool : public UMemory { +public: + MemoryPool() : fCount(0), fPool() {} + + ~MemoryPool() { + for (int32_t i = 0; i < fCount; ++i) { + delete fPool[i]; + } + } + + MemoryPool(const MemoryPool&) = delete; + MemoryPool& operator=(const MemoryPool&) = delete; + + MemoryPool(MemoryPool&& other) U_NOEXCEPT : fCount(other.fCount), + fPool(std::move(other.fPool)) { + other.fCount = 0; + } + + MemoryPool& operator=(MemoryPool&& other) U_NOEXCEPT { + fCount = other.fCount; + fPool = std::move(other.fPool); + other.fCount = 0; + return *this; + } + + /** + * Creates a new object of typename T, by forwarding any and all arguments + * to the typename T constructor. + * + * @param args Arguments to be forwarded to the typename T constructor. + * @return A pointer to the newly created object, or nullptr on error. + */ + template<typename... Args> + T* create(Args&&... args) { + int32_t capacity = fPool.getCapacity(); + if (fCount == capacity && + fPool.resize(capacity == stackCapacity ? 4 * capacity : 2 * capacity, + capacity) == nullptr) { + return nullptr; + } + return fPool[fCount++] = new T(std::forward<Args>(args)...); + } + + /** + * @return Number of elements that have been allocated. + */ + int32_t count() const { + return fCount; + } + +protected: + int32_t fCount; + MaybeStackArray<T*, stackCapacity> fPool; +}; + +/** + * An internal Vector-like implementation based on MemoryPool. + * + * Heap-allocates each element and stores pointers. + * + * To append an item to the vector, use emplaceBack. + * + * MaybeStackVector<MyType> vector; + * MyType* element = vector.emplaceBack(); + * if (!element) { + * status = U_MEMORY_ALLOCATION_ERROR; + * } + * // do stuff with element + * + * To loop over the vector, use a for loop with indices: + * + * for (int32_t i = 0; i < vector.length(); i++) { + * MyType* element = vector[i]; + * } + */ +template<typename T, int32_t stackCapacity = 8> +class MaybeStackVector : protected MemoryPool<T, stackCapacity> { +public: + using MemoryPool<T, stackCapacity>::MemoryPool; + using MemoryPool<T, stackCapacity>::operator=; + + template<typename... Args> + T* emplaceBack(Args&&... args) { + return this->create(args...); + } + + int32_t length() const { + return this->fCount; + } + + T** getAlias() { + return this->fPool.getAlias(); + } + + /** + * Array item access (read-only). + * No index bounds check. + * @param i array index + * @return reference to the array item + */ + const T* operator[](ptrdiff_t i) const { + return this->fPool[i]; + } + + /** + * Array item access (writable). + * No index bounds check. + * @param i array index + * @return reference to the array item + */ + T* operator[](ptrdiff_t i) { + return this->fPool[i]; + } + + /** + * Append all the items from another MaybeStackVector to this one. + */ + void appendAll(const MaybeStackVector& other, UErrorCode& status) { + for (int32_t i = 0; i < other.fCount; i++) { + T* item = emplaceBack(*other[i]); + if (!item) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + } + } +}; + + U_NAMESPACE_END #endif /* __cplusplus */ |