fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <list>
  4. #include <limits>
  5.  
  6. using namespace std;
  7.  
  8. struct memory_manager
  9. {
  10. memory_manager() : allocations(0) {}
  11.  
  12. void* allocate(size_t s)
  13. {
  14. ++allocations;
  15. return new char[s];
  16. }
  17.  
  18. void deallocate(void* mem)
  19. {
  20. delete[] reinterpret_cast<char*>(mem);
  21. --allocations;
  22. }
  23.  
  24. size_t allocations;
  25. }
  26. the_manager;
  27.  
  28. template <typename T>
  29. class custom_allocator
  30. {
  31. public:
  32. typedef T value_type;
  33. typedef value_type* pointer;
  34. typedef value_type const* const_pointer;
  35. typedef value_type& reference;
  36. typedef value_type const& const_reference;
  37. typedef size_t size_type;
  38. typedef ptrdiff_t difference_type;
  39.  
  40. pointer allocate(size_type size, const void* = nullptr)
  41. {
  42. void* mem = the_manager.allocate(size * sizeof(value_type));
  43. return reinterpret_cast<pointer>(mem);
  44. }
  45.  
  46. void deallocate(pointer mem, size_type)
  47. {
  48. the_manager.deallocate(mem);
  49. }
  50.  
  51. size_type max_size() const
  52. {
  53. return numeric_limits<size_t>::max() / sizeof(value_type);
  54. }
  55.  
  56. ////////////////////////////////////////////////////////////////////////////
  57. // boilerplate follows
  58. custom_allocator() {}
  59.  
  60. custom_allocator(const custom_allocator&) {}
  61.  
  62. template <typename Other>
  63. custom_allocator(const custom_allocator<Other>&) {}
  64.  
  65. custom_allocator& operator=(const custom_allocator&) { return *this; }
  66.  
  67. template <class other>
  68. custom_allocator& operator=(const custom_allocator<other>&) { return *this; }
  69.  
  70. template <typename Other>
  71. struct rebind { typedef custom_allocator<Other> other; };
  72.  
  73. pointer address(reference ref) const
  74. {
  75. return &ref;
  76. }
  77.  
  78. const_pointer address(const_reference ref) const
  79. {
  80. return &ref;
  81. }
  82.  
  83. void construct(pointer ptr, const value_type& val)
  84. {
  85. ::new(ptr)value_type(val);
  86. }
  87.  
  88. void destroy(pointer ptr)
  89. {
  90. ptr->~value_type();
  91. }
  92. };
  93.  
  94. template <typename T>
  95. using custom_vector = std::vector<T, custom_allocator<T>>;
  96.  
  97. template <typename T>
  98. using custom_list = std::list<T, custom_allocator<T>>;
  99.  
  100. struct custom_tag {};
  101. custom_tag the_tag;
  102.  
  103. void* operator new(size_t size, const custom_tag&)
  104. {
  105. return the_manager.allocate(size);
  106. }
  107.  
  108. void operator delete(void* mem, const custom_tag&)
  109. {
  110. the_manager.deallocate(mem);
  111. }
  112.  
  113.  
  114. #define custom_new new(the_tag)
  115. #define custom_delete(mem) ::operator delete(mem, the_tag);
  116. #define custom_delete_ar(mem) ::operator delete[](mem, the_tag);
  117.  
  118. int main()
  119. {
  120. auto x = custom_new custom_list<int>;
  121.  
  122. custom_delete(x);
  123.  
  124. cout << the_manager.allocations << endl;
  125.  
  126. return 0;
  127. }
  128.  
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
0