fork download
  1.  
  2. #include <cassert>
  3.  
  4. #include <cstddef>
  5.  
  6. #include <functional>
  7.  
  8. #include <new>
  9.  
  10. #include <unordered_map>
  11.  
  12. #include <utility>
  13.  
  14. template <std::size_t N>
  15. class stack_store
  16. {
  17. public:
  18. stack_store() = default;
  19.  
  20. stack_store(stack_store const&) = delete;
  21.  
  22. stack_store& operator=(stack_store const&) = delete;
  23.  
  24. char* allocate(std::size_t n)
  25. {
  26. assert(pointer_in_buffer(ptr_) &&
  27. "stack_allocator has outlived stack_store");
  28.  
  29. n = align(n);
  30.  
  31. if (buf_ + N >= ptr_ + n)
  32. {
  33. auto r(ptr_);
  34.  
  35. ptr_ += n;
  36.  
  37. return r;
  38. }
  39. else
  40. {
  41. return static_cast<char*>(::operator new(n));
  42. }
  43. }
  44.  
  45. void deallocate(char* const p, std::size_t n) noexcept
  46. {
  47. assert(pointer_in_buffer(ptr_) &&
  48. "stack_allocator has outlived stack_store");
  49.  
  50. if (pointer_in_buffer(p))
  51. {
  52. n = align(n);
  53.  
  54. if (p + n == ptr_)
  55. {
  56. ptr_ = p;
  57. }
  58. // else do nothing
  59. }
  60. else
  61. {
  62. ::operator delete(p);
  63. }
  64. }
  65.  
  66. void reset() noexcept { ptr_ = buf_; }
  67.  
  68. static constexpr ::std::size_t size() noexcept { return N; }
  69.  
  70. ::std::size_t used() const { return ::std::size_t(ptr_ - buf_); }
  71.  
  72. private:
  73. static constexpr ::std::size_t align(::std::size_t const n) noexcept
  74. {
  75. return (n + (alignment - 1)) & -alignment;
  76. }
  77.  
  78. bool pointer_in_buffer(char* const p) noexcept
  79. {
  80. return (buf_ <= p) && (p <= buf_ + N);
  81. }
  82.  
  83. private:
  84. static constexpr auto const alignment = alignof(::max_align_t);
  85.  
  86. char* ptr_{buf_};
  87.  
  88. alignas(::max_align_t) char buf_[N];
  89. };
  90.  
  91. template <class T, std::size_t N>
  92. class stack_allocator
  93. {
  94. public:
  95. using store_type = stack_store<N>;
  96.  
  97. using size_type = ::std::size_t;
  98.  
  99. using difference_type = ::std::ptrdiff_t;
  100.  
  101. using pointer = T*;
  102. using const_pointer = T const*;
  103.  
  104. using reference = T&;
  105. using const_reference = T const&;
  106.  
  107. using value_type = T;
  108.  
  109. template <class U> struct rebind { using other = stack_allocator<U, N>; };
  110.  
  111. stack_allocator() = default;
  112.  
  113. stack_allocator(stack_store<N>& s) noexcept : store_(&s) { }
  114.  
  115. template <class U>
  116. stack_allocator(stack_allocator<U, N> const& other) noexcept :
  117. store_(other.store_)
  118. {
  119. }
  120.  
  121. stack_allocator& operator=(stack_allocator const&) = delete;
  122.  
  123. T* allocate(::std::size_t const n)
  124. {
  125. return static_cast<T*>(static_cast<void*>(
  126. store_->allocate(n * sizeof(T))));
  127. }
  128.  
  129. void deallocate(T* const p, ::std::size_t const n) noexcept
  130. {
  131. store_->deallocate(static_cast<char*>(static_cast<void*>(p)),
  132. n * sizeof(T));
  133. }
  134.  
  135. /*
  136.   template <class U, class ...A>
  137.   void construct(U* const p, A&& ...args)
  138.   {
  139.   new (p) U(::std::forward<A>(args)...);
  140.   }
  141.  
  142.   template <class U>
  143.   void destroy(U* const p)
  144.   {
  145.   p->~U();
  146.   }
  147. */
  148.  
  149. template <class U, std::size_t M>
  150. inline bool operator==(stack_allocator<U, M> const& rhs) const noexcept
  151. {
  152. return store_ == rhs.store_;
  153. }
  154.  
  155. template <class U, std::size_t M>
  156. inline bool operator!=(stack_allocator<U, M> const& rhs) const noexcept
  157. {
  158. return !(*this == rhs);
  159. }
  160.  
  161. private:
  162. template <class U, std::size_t M> friend class stack_allocator;
  163.  
  164. store_type* store_{};
  165. };
  166.  
  167. namespace std
  168. {
  169. // string
  170. template<class CharT> class char_traits;
  171.  
  172. template<class CharT, class Traits, class Allocator> class basic_string;
  173.  
  174. // unordered_map
  175. template<class Key, class T, class Hash, class Pred, class Alloc>
  176. class unordered_map;
  177.  
  178. // vector
  179. template <class T, class Alloc> class vector;
  180. }
  181.  
  182. using stack_string = ::std::basic_string<char, ::std::char_traits<char>,
  183. stack_allocator<char, 128> >;
  184.  
  185. template <class Key, class T, class Hash = ::std::hash<Key>,
  186. class Pred = ::std::equal_to<Key> >
  187. using stack_unordered_map = ::std::unordered_map<Key, T, Hash, Pred,
  188. stack_allocator<::std::pair<Key const, T>, 256> >;
  189.  
  190. template <typename T>
  191. using stack_vector = ::std::vector<T, stack_allocator<T, 256> >;
  192.  
  193. int main()
  194. {
  195. stack_unordered_map<int, int>::allocator_type::store_type s;
  196. stack_unordered_map<int, int> u(10, stack_unordered_map<int, int>::hasher(),
  197. stack_unordered_map<int, int>::key_equal(), s);
  198. return 0;
  199. }
Compilation error #stdin compilation error #stdout 0s 3336KB
stdin
Standard input is empty
compilation info
In file included from /usr/include/c++/4.8/unordered_map:47:0,
                 from prog.cpp:10:
/usr/include/c++/4.8/bits/hashtable.h: In instantiation of ‘void std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::_M_deallocate_node(std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::__node_type*) [with _Key = int; _Value = std::pair<const int, int>; _Alloc = stack_allocator<std::pair<const int, int>, 256u>; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int>; _H1 = std::hash<int>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::__node_type = std::__detail::_Hash_node<std::pair<const int, int>, false>]’:
/usr/include/c++/4.8/bits/hashtable.h:763:28:   required from ‘void std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::_M_deallocate_nodes(std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::__node_type*) [with _Key = int; _Value = std::pair<const int, int>; _Alloc = stack_allocator<std::pair<const int, int>, 256u>; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int>; _H1 = std::hash<int>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::__node_type = std::__detail::_Hash_node<std::pair<const int, int>, false>]’
/usr/include/c++/4.8/bits/hashtable.h:1641:37:   required from ‘void std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::clear() [with _Key = int; _Value = std::pair<const int, int>; _Alloc = stack_allocator<std::pair<const int, int>, 256u>; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int>; _H1 = std::hash<int>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>]’
/usr/include/c++/4.8/bits/hashtable.h:958:13:   required from ‘std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>::~_Hashtable() [with _Key = int; _Value = std::pair<const int, int>; _Alloc = stack_allocator<std::pair<const int, int>, 256u>; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<int>; _H1 = std::hash<int>; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>]’
/usr/include/c++/4.8/bits/unordered_map.h:97:11:   required from here
/usr/include/c++/4.8/bits/hashtable.h:746:7: error: ‘std::_Hashtable<int, std::pair<const int, int>, stack_allocator<std::pair<const int, int>, 256u>, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_Node_allocator_type’ has no member named ‘destroy’
       _M_node_allocator().destroy(__n);
       ^
stdout
Standard output is empty