kj::Arena for fast arena-style allocation.
diff --git a/c++/src/kj/array.c++ b/c++/src/kj/array.c++
index 5ade889..5f5a11c 100644
--- a/c++/src/kj/array.c++
+++ b/c++/src/kj/array.c++
@@ -24,37 +24,26 @@
#include "array.h"
namespace kj {
+
+void ExceptionSafeArrayUtil::construct(size_t count, void (*constructElement)(void*)) {
+ while (count > 0) {
+ constructElement(pos);
+ pos += elementSize;
+ ++constructedElementCount;
+ --count;
+ }
+}
+
+void ExceptionSafeArrayUtil::destroyAll() {
+ while (constructedElementCount > 0) {
+ pos -= elementSize;
+ --constructedElementCount;
+ destroyElement(pos);
+ }
+}
+
namespace _ { // private
-struct HeapArrayDisposer::ExceptionGuard {
- byte* pos;
- size_t elementSize;
- size_t elementCount;
- size_t constructedCount;
- void (*destroyElement)(void*);
-
- ExceptionGuard(void* ptr, size_t elementSize, size_t elementCount,
- void (*destroyElement)(void*))
- : pos(reinterpret_cast<byte*>(ptr) + elementSize * elementCount),
- elementSize(elementSize), elementCount(elementCount),
- destroyElement(destroyElement) {}
-
- ~ExceptionGuard() noexcept(false) {
- if (pos != nullptr) {
- destroyAll();
- operator delete(pos);
- }
- }
-
- void destroyAll() {
- while (elementCount > 0) {
- pos -= elementSize;
- --elementCount;
- destroyElement(pos);
- }
- }
-};
-
void* HeapArrayDisposer::allocateImpl(size_t elementSize, size_t elementCount, size_t capacity,
void (*constructElement)(void*),
void (*destroyElement)(void*)) {
@@ -70,13 +59,9 @@
--elementCount;
}
} else {
- ExceptionGuard guard(result, elementSize, 0, destroyElement);
- while (guard.elementCount < elementCount) {
- constructElement(guard.pos);
- guard.pos += elementSize;
- ++guard.elementCount;
- }
- guard.pos = nullptr;
+ ExceptionSafeArrayUtil guard(result, elementSize, 0, destroyElement);
+ guard.construct(elementCount, constructElement);
+ guard.release();
}
return result;
@@ -90,11 +75,9 @@
if (destroyElement == nullptr) {
operator delete(firstElement);
} else {
- ExceptionGuard guard(firstElement, elementSize, elementCount, destroyElement);
+ KJ_DEFER(operator delete(firstElement));
+ ExceptionSafeArrayUtil guard(firstElement, elementSize, elementCount, destroyElement);
guard.destroyAll();
-
- // If an exception is thrown, we'll continue the destruction process in ExceptionGuard's
- // destructor. If _that_ throws an exception, the program terminates according to C++ rules.
}
}