mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-07 22:44:49 +00:00
ICU-20202 Add an internal helper class to own heap allocated objects.
This will be used first to replace existing locally defined memory management helper classes such as CharStringPool (uloc_tag.cpp) and CodePointMatcherWarehouse (numparse_affixes.h), then in new code.
This commit is contained in:
parent
21a8698951
commit
d62f5ae5d8
1 changed files with 75 additions and 0 deletions
|
@ -122,6 +122,8 @@ uprv_deleteUObject(void *obj);
|
|||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <utility>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
|
@ -675,6 +677,79 @@ 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>
|
||||
class MemoryPool {
|
||||
enum { STACK_CAPACITY = 8 };
|
||||
public:
|
||||
MemoryPool() : count(0), pool() {}
|
||||
|
||||
~MemoryPool() {
|
||||
for (int32_t i = 0; i < count; ++i) {
|
||||
delete pool[i];
|
||||
}
|
||||
}
|
||||
|
||||
MemoryPool(const MemoryPool&) = delete;
|
||||
MemoryPool& operator=(const MemoryPool&) = delete;
|
||||
|
||||
MemoryPool(MemoryPool&& other) U_NOEXCEPT : count(other.count),
|
||||
pool(std::move(other.pool)) {
|
||||
other.count = 0;
|
||||
}
|
||||
|
||||
MemoryPool& operator=(MemoryPool&& other) U_NOEXCEPT {
|
||||
count = other.count;
|
||||
pool = std::move(other.pool);
|
||||
other.count = 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 = pool.getCapacity();
|
||||
if (count == capacity &&
|
||||
pool.resize(capacity == STACK_CAPACITY ? 32 : 2 * capacity,
|
||||
capacity) == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return pool[count++] = new T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t count;
|
||||
MaybeStackArray<T*, STACK_CAPACITY> pool;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
|
Loading…
Add table
Reference in a new issue