General Purpose library for Freestanding C++ and POSIX systems
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

98 righe
1.5 KiB

  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, 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. template<typename T = typename std::enable_if<gp::has_allocator_interface<page_allocator>::value,int>::type>
  20. arena(size_t sz)
  21. :last(0)
  22. ,count(0)
  23. ,data(nullptr,nullptr)
  24. {
  25. if(sz!=0)
  26. {
  27. auto v=allocator.allocate(sz);
  28. if(v!=nullptr)
  29. {
  30. data=gp::buffer<char>(reinterpret_cast<char*>(v),reinterpret_cast<char*>(v)+sz);
  31. }
  32. }
  33. }
  34. arena(char* pos,size_t sz)
  35. :last(0)
  36. ,count(0)
  37. ,data(pos,pos+sz)
  38. {
  39. }
  40. void* allocate(size_t sz)
  41. {
  42. [[maybe_unused]]
  43. size_t mod = 0;
  44. if constexpr (align != 1)
  45. {
  46. mod = align - ((intptr_t)data.begin())%align;
  47. }
  48. auto ret=data.begin()+last+mod;
  49. if(data.contains(ret))
  50. {
  51. count++;
  52. last+=sz+mod;
  53. return &*(ret);
  54. }
  55. else
  56. {
  57. return nullptr;
  58. }
  59. }
  60. constexpr bool try_reallocate(void*, size_t) {
  61. return false;
  62. }
  63. 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. last=0;
  75. }
  76. return true;
  77. }
  78. return false;
  79. }
  80. ~arena()
  81. {
  82. if constexpr(gp::has_allocator_interface<page_allocator>::value)
  83. {
  84. allocator.deallocate(&data[0]);
  85. }
  86. }
  87. };
  88. }