heap_allocator.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #pragma once
  2. #include "Internal/heap_allocator.inl.h"
  3. #include "Algorithm.h"
  4. namespace baselib
  5. {
  6. BASELIB_CPP_INTERFACE
  7. {
  8. // Heap allocator implementation providing platform dependent system heap allocation.
  9. //
  10. // Allocations are guaranteed to be aligned to at least the value of `default_alignment`.
  11. // For optimal performance, platform aligned allocation calls are only used when `default_alignment` exceeds platform minimum alignment guarantee.
  12. // This allocator is a stateless allocator (empty class).
  13. //
  14. // Notes on operation failure of allocator methods:
  15. // Operation failures will currently trigger process abort by the underlying system.
  16. // As a result the heap allocator currently will never return `nullptr`/`false` to signal failure, as is standard behaviour (nor any error state information).
  17. //
  18. template<uint32_t default_alignment = 8>
  19. class heap_allocator
  20. {
  21. using impl = detail::heap_allocator<default_alignment>;
  22. static_assert((default_alignment <= impl::max_alignment), "'default_alignment' exceeded max value");
  23. static_assert((default_alignment != 0), "'default_alignment' must not be a zero value");
  24. static_assert(::baselib::Algorithm::IsPowerOfTwo(default_alignment), "'default_alignment' must be a power of two value");
  25. public:
  26. // Allocated memory is guaranteed to always be aligned to at least the value of `alignment`.
  27. static constexpr uint32_t alignment = default_alignment;
  28. // Typedefs
  29. typedef Baselib_ErrorState error_state;
  30. // Allocates a memory block large enough to hold `size` number of bytes. Zero size is valid.
  31. //
  32. // \returns Address to memory block of allocated memory.
  33. void* allocate(size_t size) const
  34. {
  35. error_state result = Baselib_ErrorState_Create();
  36. return impl::allocate(size, &result);
  37. }
  38. // Allocates a memory block large enough to hold `size` number of bytes. Zero size is valid.
  39. //
  40. // \returns Address to memory block of allocated memory.
  41. void* allocate(size_t size, error_state *error_state_ptr) const
  42. {
  43. return impl::allocate(size, error_state_ptr);
  44. }
  45. // Reallocates previously allocated or reallocated memory block pointer reference `ptr` from `old_size` to `new_size` number of bytes.
  46. // Passing `nullptr` in `ptr` yield the same result as calling `allocate`.
  47. //
  48. // \returns Address to memory block of reallocated memory.
  49. void* reallocate(void* ptr, size_t old_size, size_t new_size) const
  50. {
  51. error_state result = Baselib_ErrorState_Create();
  52. return impl::reallocate(ptr, old_size, new_size, &result);
  53. }
  54. // Reallocates previously allocated or reallocated memory block pointer reference `ptr` from `old_size` to `new_size` number of bytes.
  55. // Passing `nullptr` in `ptr` yield the same result as calling `allocate`.
  56. //
  57. // \returns Address to memory block of reallocated memory.
  58. void* reallocate(void* ptr, size_t old_size, size_t new_size, error_state *error_state_ptr) const
  59. {
  60. return impl::reallocate(ptr, old_size, new_size, error_state_ptr);
  61. }
  62. // Deallocates memory block previously allocated or reallocated with `size` pointed to by `ptr`.
  63. // Passing `nullptr` in `ptr` result in a no-op.
  64. //
  65. // \returns Always returns `true` (see notes on operation failure).
  66. bool deallocate(void* ptr, size_t size) const
  67. {
  68. error_state result = Baselib_ErrorState_Create();
  69. return impl::deallocate(ptr, size, &result);
  70. }
  71. // Deallocates memory block previously allocated or reallocated with `size` pointed to by `ptr`.
  72. // Passing `nullptr` in `ptr` result in a no-op.
  73. //
  74. // \returns Always returns `true` (see notes on operation failure).
  75. bool deallocate(void* ptr, size_t size, error_state *error_state_ptr) const
  76. {
  77. return impl::deallocate(ptr, size, error_state_ptr);
  78. }
  79. // Calculate optimal allocation size given `size`.
  80. //
  81. // \returns Optimal size when allocating memory given `size`.
  82. constexpr size_t optimal_size(size_t size) const
  83. {
  84. return impl::optimal_size(size);
  85. }
  86. };
  87. }
  88. }