mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix up preallocated array to deallocate memory.
I made a wrong assumption that the allocators would deallocate the memory when their destructor was being called. Turns out this is not true evidently. Swift SVN r18753
This commit is contained in:
@@ -14,45 +14,47 @@
|
||||
#define SWIFT_BASIC_PREALLOCATEDARRAY_H_
|
||||
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "swift/Basic/NullablePtr.h"
|
||||
#include <type_traits>
|
||||
|
||||
namespace swift {
|
||||
|
||||
/// An array meant for large collections of default constructible elements of
|
||||
/// fixed size. It does one large allocation on construction.
|
||||
template <typename EltTy, typename AllocatorTy=llvm::MallocAllocator>
|
||||
template <typename EltTy, typename AllocatorTy = llvm::MallocAllocator>
|
||||
class PreallocatedArray {
|
||||
static_assert(std::is_default_constructible<EltTy>::value,
|
||||
"EltTy must be default constructable.");
|
||||
unsigned NumElts;
|
||||
Optional<AllocatorTy> Allocator;
|
||||
EltTy *Elt;
|
||||
NullablePtr<AllocatorTy> Allocator;
|
||||
EltTy *Elts;
|
||||
|
||||
public:
|
||||
|
||||
PreallocatedArray(unsigned NumElts)
|
||||
: NumElts(NumElts),
|
||||
Allocator(llvm::MallocAllocator()),
|
||||
Elt(new (Allocator->template Allocate<EltTy>(NumElts)) EltTy[NumElts]) {}
|
||||
: NumElts(NumElts), Allocator(new llvm::MallocAllocator()),
|
||||
Elts(new (Allocator.get()->template Allocate<EltTy>(NumElts))
|
||||
EltTy[NumElts]) {}
|
||||
|
||||
PreallocatedArray(unsigned NumElts, AllocatorTy &Allocator)
|
||||
: NumElts(NumElts),
|
||||
Elt(new (Allocator.template Allocate<EltTy>(NumElts)) EltTy[NumElts]) {}
|
||||
PreallocatedArray(unsigned NumElts, AllocatorTy *InputAllocator)
|
||||
: NumElts(NumElts), Allocator(InputAllocator),
|
||||
Elts(new (Allocator.get()->template Allocate<EltTy>(NumElts)) EltTy[NumElts]) {
|
||||
}
|
||||
|
||||
// Call destructors of data.
|
||||
~PreallocatedArray() {
|
||||
// Call destructors of data.
|
||||
for (unsigned i = 0; i < NumElts; ++i) {
|
||||
Elt[i].~EltTy();
|
||||
Elts[i].~EltTy();
|
||||
}
|
||||
|
||||
// And deallocate the memory.
|
||||
Allocator.get()->template Deallocate<EltTy>(Elts, NumElts);
|
||||
}
|
||||
|
||||
MutableArrayRef<EltTy> getArray() {
|
||||
return MutableArrayRef<EltTy>(Elt, NumElts);
|
||||
return MutableArrayRef<EltTy>(Elts, NumElts);
|
||||
}
|
||||
|
||||
ArrayRef<EltTy> getArray() const {
|
||||
return ArrayRef<EltTy>(Elt, NumElts);
|
||||
}
|
||||
ArrayRef<EltTy> getArray() const { return ArrayRef<EltTy>(Elts, NumElts); }
|
||||
|
||||
using iterator = typename MutableArrayRef<EltTy>::iterator;
|
||||
using const_iterator = typename ArrayRef<EltTy>::iterator;
|
||||
@@ -63,13 +65,15 @@ public:
|
||||
const_iterator begin() const { return getArray().begin(); }
|
||||
const_iterator end() const { return getArray().end(); }
|
||||
|
||||
Range<iterator> getRange() { return {begin(), end()}; }
|
||||
Range<const_iterator> getRange() const { return {begin(), end()}; }
|
||||
Range<iterator> getRange() {
|
||||
return {begin(), end()};
|
||||
}
|
||||
Range<const_iterator> getRange() const {
|
||||
return {begin(), end()};
|
||||
}
|
||||
|
||||
unsigned size() const { return NumElts; }
|
||||
EltTy &operator[](size_t Index) {
|
||||
return getArray()[Index];
|
||||
}
|
||||
EltTy &operator[](size_t Index) { return getArray()[Index]; }
|
||||
};
|
||||
|
||||
} // end namespace swift
|
||||
|
||||
Reference in New Issue
Block a user