General Purpose library for Freestanding C++ and POSIX systems
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

98 рядки
1.5 KiB

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