General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

86 line
2.0 KiB

  1. #pragma once
  2. #include "gp/containers/ring_list.hpp"
  3. #include "gp/utils/allocators/allocator.hpp"
  4. #include <stddef.h>
  5. namespace gp {
  6. class aggregator : public allocator {
  7. using local_container = ring_list<allocator, true>;
  8. local_container contents;
  9. local_container::explorer mark;
  10. public:
  11. /**
  12. * @brief Construct a new aggregator object from a bootstraping allocator
  13. *
  14. * @tparam bootstrapper the type of allocator pushed in
  15. * @param allocator_v the allocator moved inside the new aggregator
  16. */
  17. template<typename bootstrapper>
  18. aggregator(bootstrapper&& allocator_v)
  19. : contents{
  20. new(allocator_v.allocate(sizeof(local_container::node)))
  21. local_container::node(
  22. new(allocator_v.allocate(sizeof(bootstrapper))) std::remove_reference_t<bootstrapper>(gp::forward<bootstrapper&&>(allocator_v))
  23. ),
  24. *this
  25. }
  26. , mark{contents.explore()}
  27. {}
  28. /**
  29. * @brief inserts a new allocator within the aggregator
  30. *
  31. * @tparam s_allocator the type of newly inserted allocator
  32. * @param value the inserted allocator
  33. * @return true if the insertion was successful
  34. * @return false if the insertion failed and the allocator is lost to the abyss of time
  35. */
  36. template<typename s_allocator>
  37. bool insert(s_allocator&& value) {
  38. return contents.insert<
  39. std::remove_reference_t<
  40. s_allocator
  41. >
  42. >(gp::forward<s_allocator>(value));
  43. }
  44. virtual void* allocate(size_t sz) {
  45. auto cpy = mark;
  46. do{
  47. if(auto allocated = (*mark).allocate(sz))
  48. {
  49. return allocated;
  50. }
  51. ++mark;
  52. }while(cpy != mark);
  53. return nullptr;
  54. }
  55. virtual bool deallocate(void* ptr) {
  56. auto cpy = mark;
  57. do{
  58. if((*cpy).deallocate(ptr))
  59. {
  60. return true;
  61. }
  62. --cpy;
  63. }while(cpy != mark);
  64. return false;
  65. }
  66. virtual bool try_reallocate(void* ptr, size_t sz) {
  67. auto cpy = mark;
  68. do{
  69. if((*cpy).try_reallocate(ptr, sz))
  70. {
  71. return true;
  72. }
  73. --cpy;
  74. }while(cpy != mark);
  75. return false;
  76. }
  77. };
  78. }