General Purpose library for Freestanding C++ and POSIX systems
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

100 行
1.7 KiB

  1. #pragma once
  2. #include "gp_config.hpp"
  3. #include "gp/algorithm/min_max.hpp"
  4. #include "gp/algorithm/tmp_manip.hpp"
  5. #include "gp/buffer.hpp"
  6. #include "gp/math/integer_math.hpp"
  7. #include "gp/allocator/allocator.hpp"
  8. #include <type_traits>
  9. namespace gp {
  10. class arena : public allocator {
  11. gp::optional<gp::reference_wrapper<allocator>> allocator_v;
  12. size_t next;
  13. size_t count;
  14. gp::buffer<char> data;
  15. public:
  16. arena()
  17. : next(0)
  18. , count(0)
  19. , data(gp::buffer<char>(nullptr,nullptr))
  20. {}
  21. arena(allocator& allocator_p, size_t sz)
  22. : allocator_v(allocator_p)
  23. , next(0)
  24. , count(0)
  25. , data(nullptr,nullptr)
  26. {
  27. if(sz != 0)
  28. {
  29. auto v = allocator_v.value().get().allocate(sz);
  30. if(v != nullptr)
  31. {
  32. data=gp::buffer<char>(reinterpret_cast<char*>(v),reinterpret_cast<char*>(v)+sz);
  33. }
  34. }
  35. }
  36. arena(char* pos, size_t sz)
  37. : next(0)
  38. , count(0)
  39. , data(pos,pos+sz)
  40. {}
  41. void reset() {
  42. next = count = 0;
  43. }
  44. virtual void* allocate(size_t sz)
  45. {
  46. size_t align = gp::min((1 << gp::math::log2(sz)), 16);
  47. size_t padding = align - (reinterpret_cast<uintptr_t>(data.begin().data + next)) % align;
  48. auto ret=data.begin()+padding+next;
  49. if(data.contains(ret))
  50. {
  51. count++;
  52. next+=padding+sz;
  53. return ret.data;
  54. }
  55. else
  56. {
  57. return nullptr;
  58. }
  59. }
  60. virtual bool try_reallocate(void*, size_t) {
  61. return false;
  62. }
  63. virtual bool deallocate(void* ptr)
  64. {
  65. if(data.contains((char*)ptr))
  66. {
  67. count--;
  68. if(count==0)
  69. {
  70. for(auto& i : data)
  71. {
  72. i=0;
  73. }
  74. next=0;
  75. }
  76. return true;
  77. }
  78. return false;
  79. }
  80. virtual ~arena()
  81. {
  82. if(allocator_v.has_value())
  83. {
  84. allocator_v.value().get().deallocate(&data[0]);
  85. }
  86. }
  87. };
  88. }