StackAllocator.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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)
  20. : length(n),
  21. dataPointer(StackAllocator::allocate(sizeof(T), length)) {
  22. for(int i = 0; i < length; i++) {
  23. new((*this) + i) T;
  24. }
  25. }
  26. ~Array() {
  27. for(int i = 0; i < length; i++) {
  28. (*this)[i].~T();
  29. }
  30. StackAllocator::free(dataPointer);
  31. }
  32. Array(const Array&) = delete;
  33. Array& operator=(const Array&) = delete;
  34. Array(Array&&) = delete;
  35. Array& operator=(Array&&) = delete;
  36. int getLength() const {
  37. return length;
  38. }
  39. int grow(int n) {
  40. int add = StackAllocator::grow(dataPointer, sizeof(T), n);
  41. for(int i = length; i < length + add; i++) {
  42. new((*this) + i) T();
  43. }
  44. length += add;
  45. return add;
  46. }
  47. T& operator[](int index) {
  48. return static_cast<T*>(StackAllocator::get(dataPointer))[index];
  49. }
  50. const T& operator[](int index) const {
  51. return static_cast<T*>(StackAllocator::get(dataPointer))[index];
  52. }
  53. operator T*() {
  54. return static_cast<T*>(StackAllocator::get(dataPointer));
  55. }
  56. };
  57. template<typename T>
  58. class Object final {
  59. int length;
  60. Pointer dataPointer;
  61. public:
  62. Object()
  63. : length(1),
  64. dataPointer(StackAllocator::allocate(sizeof(T), length)) {
  65. if(!hasError()) {
  66. new(StackAllocator::get(dataPointer)) T;
  67. }
  68. }
  69. ~Object() {
  70. if(!hasError()) {
  71. (*this)->~T();
  72. }
  73. StackAllocator::free(dataPointer);
  74. }
  75. Object(const Object&) = delete;
  76. Object& operator=(const Object&) = delete;
  77. Object(Object&&) = delete;
  78. Object& operator=(Object&&) = delete;
  79. bool hasError() {
  80. return length != 1;
  81. }
  82. T* operator->() {
  83. return static_cast<T*>(StackAllocator::get(dataPointer));
  84. }
  85. operator T&() {
  86. return *static_cast<T*>(StackAllocator::get(dataPointer));
  87. }
  88. };
  89. }
  90. #endif