General Purpose library for Freestanding C++ and POSIX systems
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

71 rader
1.4 KiB

  1. #pragma once
  2. #include "gp/ring_list.hpp"
  3. #include "gp/allocator/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. template<typename bootstrapper>
  12. aggregator(bootstrapper&& allocator_v)
  13. : contents{
  14. new(allocator_v.allocate(sizeof(local_container::node)))
  15. local_container::node(
  16. new(allocator_v.allocate(sizeof(bootstrapper))) std::remove_reference_t<bootstrapper>(gp::forward<bootstrapper&&>(allocator_v))
  17. ),
  18. *this
  19. }
  20. , mark{contents.explore()}
  21. {}
  22. template<typename s_allocator>
  23. bool insert(s_allocator&& value) {
  24. return contents.insert<
  25. std::remove_reference_t<
  26. s_allocator
  27. >
  28. >(gp::forward<s_allocator>(value));
  29. }
  30. virtual void* allocate(size_t sz) {
  31. auto cpy = mark;
  32. do{
  33. if(auto allocated = (*mark).allocate(sz))
  34. {
  35. return allocated;
  36. }
  37. ++mark;
  38. }while(cpy != mark);
  39. return nullptr;
  40. }
  41. virtual bool deallocate(void* ptr) {
  42. auto cpy = mark;
  43. do{
  44. if((*cpy).deallocate(ptr))
  45. {
  46. return true;
  47. }
  48. --cpy;
  49. }while(cpy != mark);
  50. return false;
  51. }
  52. virtual bool try_reallocate(void* ptr, size_t sz) {
  53. auto cpy = mark;
  54. do{
  55. if((*cpy).try_reallocate(ptr, sz))
  56. {
  57. return true;
  58. }
  59. --cpy;
  60. }while(cpy != mark);
  61. return false;
  62. }
  63. };
  64. }