Utility.cppm 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. module;
  2. #include <new>
  3. export module Core.Utility;
  4. export import Core.Types;
  5. import Core.Meta;
  6. import Core.Std;
  7. import Core.New;
  8. #define SOURCE const std::source_location& l = std::source_location::current()
  9. export namespace std {
  10. using std::source_location;
  11. }
  12. #ifdef CHECK_MEMORY
  13. export void* operator new(size_t count, const std::source_location& l) noexcept;
  14. export void* operator new[](
  15. size_t count, const std::source_location& l) noexcept;
  16. #endif
  17. export namespace Core {
  18. template<typename T, typename C = int>
  19. C popCount(const T& t) noexcept {
  20. static constexpr C map[16] = {0, 1, 1, 2, 1, 2, 2, 3,
  21. 1, 2, 2, 3, 2, 3, 3, 4};
  22. C sum = 0;
  23. for(size_t i = 0; i < sizeof(T) * 8; i += 4) {
  24. sum += map[(t >> i) & 0xF];
  25. }
  26. return sum;
  27. }
  28. using ExitHandler = void (*)(int, void*);
  29. [[noreturn]] void exitWithHandler(int value, SOURCE) noexcept;
  30. void setExitHandler(ExitHandler h, void* data) noexcept;
  31. using OutOfMemoryHandler = void (*)(void*);
  32. void setOutOfMemoryHandler(OutOfMemoryHandler h, void* data) noexcept;
  33. #ifdef CHECK_MEMORY
  34. void* allocateRaw(size_t n, SOURCE) noexcept;
  35. void* zeroAllocateRaw(size_t n, SOURCE) noexcept;
  36. void* reallocateRaw(void* p, size_t n, SOURCE) noexcept;
  37. void deallocateRaw(void* p, SOURCE) noexcept;
  38. template<typename T, typename... Args>
  39. T* newWithSource(Args&&... args) noexcept {
  40. static_assert(noexcept(new(std::source_location::current())
  41. T(Core::forward<Args>(args)...)));
  42. return new(std::source_location::current())
  43. T(Core::forward<Args>(args)...);
  44. }
  45. template<typename T>
  46. T* newWithSourceN(size_t n) noexcept {
  47. static_assert(noexcept(new(std::source_location::current()) T[n]));
  48. return new(std::source_location::current()) T[n];
  49. }
  50. #else
  51. void* allocateRaw(size_t n) noexcept;
  52. void* zeroAllocateRaw(size_t n) noexcept;
  53. void* reallocateRaw(void* p, size_t n) noexcept;
  54. void deallocateRaw(void* p) noexcept;
  55. template<typename T, typename... Args>
  56. T* newWithSource(Args&&... args) noexcept {
  57. static_assert(
  58. noexcept(new(std::nothrow) T(Core::forward<Args>(args)...)));
  59. return new(std::nothrow) T(Core::forward<Args>(args)...);
  60. }
  61. template<typename T>
  62. T* newWithSourceN(size_t n) noexcept {
  63. static_assert(noexcept(new(std::nothrow) T[n]));
  64. return new(std::nothrow) T[n];
  65. }
  66. #endif
  67. void printMemoryReport() noexcept;
  68. template<typename T>
  69. void deleteWithSource(T* p) noexcept {
  70. delete p;
  71. }
  72. template<typename T>
  73. void deleteWithSourceN(T* p) noexcept {
  74. delete[] p;
  75. }
  76. template<typename T>
  77. void bubbleSort(T* data, size_t n) noexcept {
  78. bool swapped = true;
  79. while(swapped && n > 0) {
  80. swapped = false;
  81. n--;
  82. for(size_t i = 0; i < n; i++) {
  83. if(data[i] > data[i + 1]) {
  84. swap(data[i], data[i + 1]);
  85. swapped = true;
  86. }
  87. }
  88. }
  89. }
  90. }