Memory.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * This source file is part of RmlUi, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://github.com/mikke89/RmlUi
  5. *
  6. * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
  7. * Copyright (c) 2019-2023 The RmlUi Team, and contributors
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. *
  27. */
  28. #ifndef RMLUI_CORE_MEMORY_H
  29. #define RMLUI_CORE_MEMORY_H
  30. #include "../../Include/RmlUi/Core/Traits.h"
  31. #include "../../Include/RmlUi/Core/Types.h"
  32. namespace Rml {
  33. namespace Detail {
  34. /**
  35. Basic stack allocator.
  36. A very cheap allocator which only moves a pointer up and down during allocation and deallocation, respectively.
  37. The allocator is initialized with some fixed memory. If it runs out, it falls back to malloc.
  38. Warning: Using this is dangerous as deallocation must happen in exact reverse order of allocation.
  39. Do not use this class directly.
  40. */
  41. class BasicStackAllocator {
  42. public:
  43. BasicStackAllocator(size_t N);
  44. ~BasicStackAllocator() noexcept;
  45. void* allocate(size_t alignment, size_t byte_size);
  46. void deallocate(void* obj) noexcept;
  47. private:
  48. const size_t N;
  49. byte* data;
  50. void* p;
  51. };
  52. BasicStackAllocator& GetGlobalBasicStackAllocator();
  53. } /* namespace Detail */
  54. /**
  55. Global stack allocator.
  56. Can very cheaply allocate memory using the global stack allocator. Memory will be allocated from the
  57. heap on the very first construction of a global stack allocator, and will persist and be re-used after.
  58. Falls back to malloc if there is not enough space left.
  59. Warning: Using this is dangerous as deallocation must happen in exact reverse order of allocation.
  60. Memory is shared between different global stack allocators. Should only be used for highly localized code,
  61. where memory is allocated and then quickly thrown away.
  62. */
  63. template <typename T>
  64. class GlobalStackAllocator {
  65. public:
  66. using value_type = T;
  67. GlobalStackAllocator() = default;
  68. template <class U>
  69. constexpr GlobalStackAllocator(const GlobalStackAllocator<U>&) noexcept
  70. {}
  71. T* allocate(size_t num_objects) { return static_cast<T*>(Detail::GetGlobalBasicStackAllocator().allocate(alignof(T), num_objects * sizeof(T))); }
  72. void deallocate(T* ptr, size_t) noexcept { Detail::GetGlobalBasicStackAllocator().deallocate(ptr); }
  73. };
  74. template <class T, class U>
  75. bool operator==(const GlobalStackAllocator<T>&, const GlobalStackAllocator<U>&)
  76. {
  77. return true;
  78. }
  79. template <class T, class U>
  80. bool operator!=(const GlobalStackAllocator<T>&, const GlobalStackAllocator<U>&)
  81. {
  82. return false;
  83. }
  84. /**
  85. A poor man's dynamic array.
  86. Constructs N objects on initialization which are default initialized. Can not be resized.
  87. */
  88. template <typename T, typename Alloc>
  89. class DynamicArray : Alloc, NonCopyMoveable {
  90. public:
  91. DynamicArray(size_t N) : N(N)
  92. {
  93. p = Alloc::allocate(N);
  94. for (size_t i = 0; i < N; i++)
  95. new (p + i) T;
  96. }
  97. ~DynamicArray() noexcept
  98. {
  99. for (size_t i = 0; i < N; i++)
  100. p[i].~T();
  101. Alloc::deallocate(p, N);
  102. }
  103. T* data() noexcept { return p; }
  104. T& operator[](size_t i) noexcept { return p[i]; }
  105. private:
  106. size_t N;
  107. T* p;
  108. };
  109. } // namespace Rml
  110. #endif