StackAllocator.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #ifndef STACKALLOCATOR_H
  2. #define STACKALLOCATOR_H
  3. #include <new>
  4. #include <type_traits>
  5. namespace StackAllocator {
  6. struct Pointer {
  7. int lastPointer;
  8. int pointer;
  9. };
  10. Pointer allocate(int bytesPerElement, int& elements);
  11. void free(const Pointer& p);
  12. int grow(const Pointer& p, int bytesPerElement, int elements);
  13. void* get(const Pointer& p);
  14. template<typename T>
  15. class Array final {
  16. int length;
  17. Pointer dataPointer;
  18. public:
  19. Array(int n) : length(n), dataPointer(StackAllocator::allocate(sizeof(T), length)) {
  20. for(int i = 0; i < length; i++) {
  21. new((*this) + i) T;
  22. }
  23. }
  24. ~Array() {
  25. for(int i = 0; i < length; i++) {
  26. (*this)[i].~T();
  27. }
  28. StackAllocator::free(dataPointer);
  29. }
  30. Array(const Array&) = delete;
  31. Array& operator=(const Array&) = delete;
  32. Array(Array&&) = delete;
  33. Array& operator=(Array&&) = delete;
  34. int getLength() const {
  35. return length;
  36. }
  37. int grow(int n) {
  38. int add = StackAllocator::grow(dataPointer, sizeof(T), n);
  39. for(int i = length; i < length + add; i++) {
  40. new((*this) + i) T();
  41. }
  42. length += add;
  43. return add;
  44. }
  45. T& operator[](int index) {
  46. return static_cast<T*>(StackAllocator::get(dataPointer))[index];
  47. }
  48. const T& operator[](int index) const {
  49. return static_cast<T*>(StackAllocator::get(dataPointer))[index];
  50. }
  51. operator T*() {
  52. return static_cast<T*>(StackAllocator::get(dataPointer));
  53. }
  54. };
  55. template<typename T>
  56. class Object final {
  57. int length;
  58. Pointer dataPointer;
  59. public:
  60. Object() : length(1), dataPointer(StackAllocator::allocate(sizeof(T), length)) {
  61. if(!hasError()) {
  62. new(StackAllocator::get(dataPointer)) T;
  63. }
  64. }
  65. ~Object() {
  66. if(!hasError()) {
  67. (*this)->~T();
  68. }
  69. StackAllocator::free(dataPointer);
  70. }
  71. Object(const Object&) = delete;
  72. Object& operator=(const Object&) = delete;
  73. Object(Object&&) = delete;
  74. Object& operator=(Object&&) = delete;
  75. bool hasError() {
  76. return length != 1;
  77. }
  78. T* operator->() {
  79. return static_cast<T*>(StackAllocator::get(dataPointer));
  80. }
  81. operator T&() {
  82. return *static_cast<T*>(StackAllocator::get(dataPointer));
  83. }
  84. };
  85. }
  86. #endif