123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- #ifndef STACKALLOCATOR_H
- #define STACKALLOCATOR_H
- #include <new>
- #include <type_traits>
- namespace StackAllocator {
- struct Pointer {
- int lastPointer;
- int pointer;
- };
- Pointer allocate(int bytesPerElement, int& elements);
- void free(const Pointer& p);
- int grow(const Pointer& p, int bytesPerElement, int elements);
- void* get(const Pointer& p);
- template<typename T>
- class Array final {
- int length;
- Pointer dataPointer;
- public:
- Array(int n) : length(n), dataPointer(StackAllocator::allocate(sizeof(T), length)) {
- for(int i = 0; i < length; i++) {
- new((*this) + i) T;
- }
- }
- ~Array() {
- for(int i = 0; i < length; i++) {
- (*this)[i].~T();
- }
- StackAllocator::free(dataPointer);
- }
- Array(const Array&) = delete;
- Array& operator=(const Array&) = delete;
- Array(Array&&) = delete;
- Array& operator=(Array&&) = delete;
- int getLength() const {
- return length;
- }
- int grow(int n) {
- int add = StackAllocator::grow(dataPointer, sizeof(T), n);
- for(int i = length; i < length + add; i++) {
- new((*this) + i) T();
- }
- length += add;
- return add;
- }
- T& operator[](int index) {
- return static_cast<T*>(StackAllocator::get(dataPointer))[index];
- }
- const T& operator[](int index) const {
- return static_cast<T*>(StackAllocator::get(dataPointer))[index];
- }
- operator T*() {
- return static_cast<T*>(StackAllocator::get(dataPointer));
- }
- };
- template<typename T>
- class Object final {
- int length;
- Pointer dataPointer;
- public:
- Object() : length(1), dataPointer(StackAllocator::allocate(sizeof(T), length)) {
- if(!hasError()) {
- new(StackAllocator::get(dataPointer)) T;
- }
- }
- ~Object() {
- if(!hasError()) {
- (*this)->~T();
- }
- StackAllocator::free(dataPointer);
- }
- Object(const Object&) = delete;
- Object& operator=(const Object&) = delete;
- Object(Object&&) = delete;
- Object& operator=(Object&&) = delete;
- bool hasError() {
- return length != 1;
- }
- T* operator->() {
- return static_cast<T*>(StackAllocator::get(dataPointer));
- }
- operator T&() {
- return *static_cast<T*>(StackAllocator::get(dataPointer));
- }
- };
- }
- #endif
|