memory.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #pragma once
  2. #include "common.h"
  3. #include <type_traits>
  4. namespace pkpy{
  5. template <typename T>
  6. struct shared_ptr {
  7. int* counter;
  8. T* _t() const noexcept { return (T*)(counter + 1); }
  9. void _inc_counter() { if(counter) ++(*counter); }
  10. void _dec_counter() { if(counter && --(*counter) == 0) {((T*)(counter + 1))->~T(); free(counter);} }
  11. public:
  12. shared_ptr() : counter(nullptr) {}
  13. shared_ptr(int* counter) : counter(counter) {}
  14. shared_ptr(const shared_ptr& other) : counter(other.counter) {
  15. _inc_counter();
  16. }
  17. shared_ptr(shared_ptr&& other) noexcept : counter(other.counter) {
  18. other.counter = nullptr;
  19. }
  20. ~shared_ptr() { _dec_counter(); }
  21. bool operator==(const shared_ptr& other) const { return counter == other.counter; }
  22. bool operator!=(const shared_ptr& other) const { return counter != other.counter; }
  23. bool operator<(const shared_ptr& other) const { return counter < other.counter; }
  24. bool operator>(const shared_ptr& other) const { return counter > other.counter; }
  25. bool operator<=(const shared_ptr& other) const { return counter <= other.counter; }
  26. bool operator>=(const shared_ptr& other) const { return counter >= other.counter; }
  27. bool operator==(std::nullptr_t) const { return counter == nullptr; }
  28. bool operator!=(std::nullptr_t) const { return counter != nullptr; }
  29. shared_ptr& operator=(const shared_ptr& other) {
  30. _dec_counter();
  31. counter = other.counter;
  32. _inc_counter();
  33. return *this;
  34. }
  35. shared_ptr& operator=(shared_ptr&& other) noexcept {
  36. _dec_counter();
  37. counter = other.counter;
  38. other.counter = nullptr;
  39. return *this;
  40. }
  41. T& operator*() const { return *_t(); }
  42. T* operator->() const { return _t(); }
  43. T* get() const { return _t(); }
  44. int use_count() const {
  45. return counter ? *counter : 0;
  46. }
  47. void reset(){
  48. _dec_counter();
  49. counter = nullptr;
  50. }
  51. };
  52. template <typename T, typename... Args>
  53. shared_ptr<T> make_sp(Args&&... args) {
  54. int* p = (int*)malloc(sizeof(int) + sizeof(T));
  55. *p = 1;
  56. new(p+1) T(std::forward<Args>(args)...);
  57. return shared_ptr<T>(p);
  58. }
  59. template<typename T, int __Bucket, bool __ZeroInit>
  60. struct FreeListA {
  61. std::vector<T*> buckets[__Bucket+1];
  62. T* alloc(int n){
  63. static_assert(std::is_standard_layout_v<T>);
  64. T* p;
  65. if(n > __Bucket || buckets[n].empty()){
  66. p = (T*)malloc(sizeof(T) * n);
  67. }else{
  68. p = buckets[n].back();
  69. buckets[n].pop_back();
  70. }
  71. if constexpr(__ZeroInit){
  72. // the constructor of T should be equivalent to zero initialization
  73. memset((void*)p, 0, sizeof(T) * n);
  74. }
  75. return p;
  76. }
  77. void dealloc(T* p, int n){
  78. if(p == nullptr) return;
  79. if(n > __Bucket || buckets[n].size() >= 80){
  80. free(p);
  81. }else{
  82. buckets[n].push_back(p);
  83. }
  84. }
  85. ~FreeListA(){
  86. for(int i=0; i<=__Bucket; i++){
  87. for(T* p : buckets[i]) free(p);
  88. }
  89. }
  90. };
  91. }; // namespace pkpy