STLAllocator.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. JPH_NAMESPACE_BEGIN
  6. /// Default implementation of AllocatorHasReallocate which tells if an allocator has a reallocate function
  7. template <class T> struct AllocatorHasReallocate { static constexpr bool sValue = false; };
  8. #ifndef JPH_DISABLE_CUSTOM_ALLOCATOR
  9. /// STL allocator that forwards to our allocation functions
  10. template <typename T>
  11. class STLAllocator
  12. {
  13. public:
  14. using value_type = T;
  15. /// Pointer to type
  16. using pointer = T *;
  17. using const_pointer = const T *;
  18. /// Reference to type.
  19. /// Can be removed in C++20.
  20. using reference = T &;
  21. using const_reference = const T &;
  22. using size_type = size_t;
  23. using difference_type = ptrdiff_t;
  24. /// The allocator is stateless
  25. using is_always_equal = std::true_type;
  26. /// Allocator supports moving
  27. using propagate_on_container_move_assignment = std::true_type;
  28. /// Constructor
  29. inline STLAllocator() = default;
  30. /// Constructor from other allocator
  31. template <typename T2>
  32. inline STLAllocator(const STLAllocator<T2> &) { }
  33. /// If this allocator needs to fall back to aligned allocations because the type requires it
  34. static constexpr bool needs_aligned_allocate = alignof(T) > (JPH_CPU_ADDRESS_BITS == 32? 8 : 16);
  35. /// Allocate memory
  36. inline pointer allocate(size_type inN)
  37. {
  38. if constexpr (needs_aligned_allocate)
  39. return pointer(AlignedAllocate(inN * sizeof(value_type), alignof(T)));
  40. else
  41. return pointer(Allocate(inN * sizeof(value_type)));
  42. }
  43. /// Should we expose a reallocate function?
  44. static constexpr bool has_reallocate = std::is_trivially_copyable<T>() && !needs_aligned_allocate;
  45. /// Reallocate memory
  46. template <bool has_reallocate_v = has_reallocate, typename = std::enable_if_t<has_reallocate_v>>
  47. inline pointer reallocate(pointer inOldPointer, size_type inOldSize, size_type inNewSize)
  48. {
  49. JPH_ASSERT(inNewSize > 0); // Reallocating to zero size is implementation dependent, so we don't allow it
  50. return pointer(Reallocate(inOldPointer, inOldSize * sizeof(value_type), inNewSize * sizeof(value_type)));
  51. }
  52. /// Free memory
  53. inline void deallocate(pointer inPointer, size_type)
  54. {
  55. if constexpr (needs_aligned_allocate)
  56. AlignedFree(inPointer);
  57. else
  58. Free(inPointer);
  59. }
  60. /// Allocators are stateless so assumed to be equal
  61. inline bool operator == (const STLAllocator<T> &) const
  62. {
  63. return true;
  64. }
  65. inline bool operator != (const STLAllocator<T> &) const
  66. {
  67. return false;
  68. }
  69. /// Converting to allocator for other type
  70. template <typename T2>
  71. struct rebind
  72. {
  73. using other = STLAllocator<T2>;
  74. };
  75. };
  76. /// The STLAllocator implements the reallocate function if the alignment of the class is smaller or equal to the default alignment for the platform
  77. template <class T> struct AllocatorHasReallocate<STLAllocator<T>> { static constexpr bool sValue = STLAllocator<T>::has_reallocate; };
  78. #else
  79. template <typename T> using STLAllocator = std::allocator<T>;
  80. #endif // !JPH_DISABLE_CUSTOM_ALLOCATOR
  81. // Declare STL containers that use our allocator
  82. using String = std::basic_string<char, std::char_traits<char>, STLAllocator<char>>;
  83. using IStringStream = std::basic_istringstream<char, std::char_traits<char>, STLAllocator<char>>;
  84. JPH_NAMESPACE_END
  85. #if (!defined(JPH_PLATFORM_WINDOWS) || defined(JPH_COMPILER_MINGW)) && !defined(JPH_DISABLE_CUSTOM_ALLOCATOR)
  86. namespace std
  87. {
  88. /// Declare std::hash for String, for some reason on Linux based platforms template deduction takes the wrong variant
  89. template <>
  90. struct hash<JPH::String>
  91. {
  92. inline size_t operator () (const JPH::String &inRHS) const
  93. {
  94. return hash<string_view> { } (inRHS);
  95. }
  96. };
  97. }
  98. #endif // (!JPH_PLATFORM_WINDOWS || JPH_COMPILER_MINGW) && !JPH_DISABLE_CUSTOM_ALLOCATOR