Advertisement
Guest User

Untitled

a guest
Apr 26th, 2015
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.45 KB | None | 0 0
  1. template <class Tp>
  2. struct SimpleAllocator {
  3. typedef Tp value_type;
  4. SimpleAllocator(аргументы конструктора);
  5.  
  6. template <class T> SimpleAllocator(const SimpleAllocator<T>& other);
  7.  
  8. Tp* allocate(std::size_t n);
  9. void deallocate(Tp* p, std::size_t n);
  10. };
  11.  
  12. template <class T, class U>
  13. bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
  14. template <class T, class U>
  15. bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&);
  16.  
  17. /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/basic_string.h:114:41: error: 'rebind' following the 'template' keyword does not refer to a template
  18. typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
  19.  
  20. 1>S:MSVS2013VCincludexstring(664): error C2903: 'rebind' : symbol is neither a class template nor a function template
  21.  
  22. #include <cassert>
  23. #include <memory>
  24. #include <vector>
  25. #include <deque>
  26.  
  27. class Arena {
  28. public:
  29. Arena() {}
  30. ~Arena() {
  31. assert(m_allocations == 0);
  32. }
  33.  
  34. void* allocate(std::size_t n) {
  35. if (n > m_available) {
  36. m_chunks.emplace_back(100500);
  37. m_available = m_chunks.back().size();
  38. m_memory = &m_chunks.back().front();
  39. }
  40.  
  41. auto mem = m_memory;
  42. m_available -= n;
  43. m_memory += n;
  44. ++m_allocations;
  45. return mem;
  46. }
  47. void deallocate(void* p, std::size_t n) {
  48. --m_allocations;
  49. auto mem = (unsigned char*)p;
  50. if (mem + n == m_memory) {
  51. m_memory = mem;
  52. m_available += n;
  53. }
  54. }
  55.  
  56. private:
  57. std::deque<std::vector<unsigned char>> m_chunks;
  58. std::size_t m_available = 0;
  59. unsigned char* m_memory;
  60. int m_allocations = 0;
  61. };
  62.  
  63. template <class T>
  64. struct ArenaAllocator {
  65. using value_type = T;
  66.  
  67. using Traits = std::allocator_traits<ArenaAllocator<T>>;
  68.  
  69. #if !defined _MSC_VER
  70. // libstdc++ использует конструктор по умолчанию:
  71. // __a == _Alloc()
  72. ArenaAllocator() : m_arena(nullptr) {}
  73.  
  74. // libstdc++ требует следующие определения
  75. using size_type = typename std::allocator<T>::size_type;
  76. using difference_type = typename std::allocator<T>::difference_type;
  77. using pointer = typename std::allocator<T>::pointer;
  78. using const_pointer = typename std::allocator<T>::const_pointer;
  79. // "reference" не входит Allocator Requirements,
  80. // но libstdc++ думает что она всегда работает с std::allocator.
  81. using reference = typename std::allocator<T>::reference;
  82. using const_reference = typename std::allocator<T>::const_reference;
  83. #endif
  84.  
  85. explicit ArenaAllocator(Arena& arena) : m_arena(&arena) {}
  86. template<class U> ArenaAllocator(const ArenaAllocator<U>& other) : m_arena(other.m_arena) {}
  87.  
  88. T* allocate(std::size_t n) { return (T*)m_arena->allocate(n * sizeof(T)); }
  89. void deallocate(T* p, std::size_t n) { m_arena->deallocate(p, n * sizeof(T)); }
  90.  
  91. // требуется в VC++ и libstdc++
  92. template<class U, class... Args> void construct(U* p, Args&&... args) { std::allocator<T>().construct(p, std::forward<Args>(args)...); }
  93. template<class U> void destroy(U* p) { std::allocator<T>().destroy(p); }
  94. template<class U> struct rebind { using other = ArenaAllocator<U>; };
  95.  
  96. Arena* m_arena;
  97. };
  98.  
  99. template<class T, class U> bool operator==(const ArenaAllocator<T>& lhs, const ArenaAllocator<U>& rhs) { return lhs.m_arena == rhs.m_arena; }
  100. template<class T, class U> bool operator!=(const ArenaAllocator<T>& lhs, const ArenaAllocator<U>& rhs) { return !(lhs == rhs); }
  101.  
  102. #include <deque>
  103. #include <functional>
  104. #include <list>
  105. #include <map>
  106. #include <memory>
  107. #include <set>
  108. #include <string>
  109. #include <unordered_set>
  110. #include <unordered_map>
  111. #include <vector>
  112.  
  113. using a_string = std::basic_string<char, std::char_traits<char>, ArenaAllocator<char>>;
  114.  
  115. template <class T> using a_vector = std::vector<T, ArenaAllocator<T>>;
  116. template <class T> using a_deque= std::deque<T, ArenaAllocator<T>>;
  117. template <class T> using a_list = std::list<T, ArenaAllocator<T>>;
  118. template <class K> using a_set = std::set<K, std::less<K>, ArenaAllocator<K>>;
  119. template <class K, class V> using a_map = std::map<K, V, std::less<K>, ArenaAllocator<std::pair<const K, V>>>;
  120. template <class K> using a_unordered_set = std::unordered_set<K, std::hash<K>, std::equal_to<K>, ArenaAllocator<K>>;
  121. template <class K, class V> using a_unordered_map = std::unordered_map<K, std::hash<K>, std::equal_to<K>, ArenaAllocator<std::pair<const K, V>>>;
  122.  
  123. struct X {};
  124.  
  125. int main() {
  126. Arena arena;
  127. ArenaAllocator<char> arena_allocator(arena);
  128.  
  129. a_string s_empty(arena_allocator);
  130. a_string s_123("123", arena_allocator);
  131.  
  132. a_vector<int> v_int({1, 2, 3}, arena_allocator);
  133. a_vector<X> v_x(42, X{}, arena_allocator);
  134. a_vector<a_string> v_str({s_empty, s_123}, arena_allocator);
  135. a_vector<a_string> v_str_copy(v_str, arena_allocator);
  136. a_deque<int> d_int({1, 2, 3}, arena_allocator);
  137. a_list<int> l_int({1, 2, 3}, arena_allocator);
  138. a_set<int> s_int({1, 2, 3}, std::less<int>{}, arena_allocator);
  139. a_map<a_string, int> m_str_int(arena_allocator);
  140. a_unordered_set<int> us_int(arena_allocator);
  141.  
  142. auto p = std::allocate_shared<int>(arena_allocator, 123);
  143.  
  144. #if 0 // этот код не работает в VC++ и g++
  145. a_unordered_map<a_string, int> um_str_int(arena_allocator);
  146. std::function<void()> f(std::allocator_arg_t{}, arena_allocator, []{});
  147. #endif
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement