#include <cassert>
#include <cstddef>
#include <functional>
#include <new>
#include <unordered_map>
#include <utility>
template <std::size_t N>
class stack_store
{
public:
stack_store() = default;
stack_store(stack_store const&) = delete;
stack_store& operator=(stack_store const&) = delete;
char* allocate(std::size_t n)
{
assert(pointer_in_buffer(ptr_) &&
"stack_allocator has outlived stack_store");
n = align(n);
if (buf_ + N >= ptr_ + n)
{
auto r(ptr_);
ptr_ += n;
return r;
}
else
{
return static_cast<char*>(::operator new(n));
}
}
void deallocate(char* const p, std::size_t n) noexcept
{
assert(pointer_in_buffer(ptr_) &&
"stack_allocator has outlived stack_store");
if (pointer_in_buffer(p))
{
n = align(n);
if (p + n == ptr_)
{
ptr_ = p;
}
// else do nothing
}
else
{
::operator delete(p);
}
}
void reset() noexcept { ptr_ = buf_; }
static constexpr ::std::size_t size() noexcept { return N; }
::std::size_t used() const { return ::std::size_t(ptr_ - buf_); }
private:
static constexpr ::std::size_t align(::std::size_t const n) noexcept
{
return (n + (alignment - 1)) & -alignment;
}
bool pointer_in_buffer(char* const p) noexcept
{
return (buf_ <= p) && (p <= buf_ + N);
}
private:
static constexpr auto const alignment = alignof(::max_align_t);
char* ptr_{buf_};
alignas(::max_align_t) char buf_[N];
};
template <class T, std::size_t N>
class stack_allocator
{
public:
using store_type = stack_store<N>;
using size_type = ::std::size_t;
using difference_type = ::std::ptrdiff_t;
using pointer = T*;
using const_pointer = T const*;
using reference = T&;
using const_reference = T const&;
using value_type = T;
template <class U> struct rebind { using other = stack_allocator<U, N>; };
stack_allocator() = default;
stack_allocator(stack_store<N>& s) noexcept : store_(&s) { }
template <class U>
stack_allocator(stack_allocator<U, N> const& other) noexcept :
store_(other.store_)
{
}
stack_allocator& operator=(stack_allocator const&) = delete;
T* allocate(::std::size_t const n)
{
return static_cast<T*>(static_cast<void*>(
store_->allocate(n * sizeof(T))));
}
void deallocate(T* const p, ::std::size_t const n) noexcept
{
store_->deallocate(static_cast<char*>(static_cast<void*>(p)),
n * sizeof(T));
}
/*
template <class U, class ...A>
void construct(U* const p, A&& ...args)
{
new (p) U(::std::forward<A>(args)...);
}
template <class U>
void destroy(U* const p)
{
p->~U();
}
*/
template <class U, std::size_t M>
inline bool operator==(stack_allocator<U, M> const& rhs) const noexcept
{
return store_ == rhs.store_;
}
template <class U, std::size_t M>
inline bool operator!=(stack_allocator<U, M> const& rhs) const noexcept
{
return !(*this == rhs);
}
private:
template <class U, std::size_t M> friend class stack_allocator;
store_type* store_{};
};
namespace std
{
// string
template<class CharT> class char_traits;
template<class CharT, class Traits, class Allocator> class basic_string;
// unordered_map
template<class Key, class T, class Hash, class Pred, class Alloc>
class unordered_map;
// vector
template <class T, class Alloc> class vector;
}
using stack_string = ::std::basic_string<char, ::std::char_traits<char>,
stack_allocator<char, 128> >;
template <class Key, class T, class Hash = ::std::hash<Key>,
class Pred = ::std::equal_to<Key> >
using stack_unordered_map = ::std::unordered_map<Key, T, Hash, Pred,
stack_allocator<::std::pair<Key const, T>, 256> >;
template <typename T>
using stack_vector = ::std::vector<T, stack_allocator<T, 256> >;
int main()
{
stack_unordered_map<int, int>::allocator_type::store_type s;
stack_unordered_map<int, int> u(10, stack_unordered_map<int, int>::hasher(),
stack_unordered_map<int, int>::key_equal(), s);
return 0;
}
CiNpbmNsdWRlIDxjYXNzZXJ0PgoKI2luY2x1ZGUgPGNzdGRkZWY+CgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCiNpbmNsdWRlIDxuZXc+CgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KCiNpbmNsdWRlIDx1dGlsaXR5PgoKdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IE4+CmNsYXNzIHN0YWNrX3N0b3JlCnsKcHVibGljOgogIHN0YWNrX3N0b3JlKCkgPSBkZWZhdWx0OwoKICBzdGFja19zdG9yZShzdGFja19zdG9yZSBjb25zdCYpID0gZGVsZXRlOwoKICBzdGFja19zdG9yZSYgb3BlcmF0b3I9KHN0YWNrX3N0b3JlIGNvbnN0JikgPSBkZWxldGU7CgogIGNoYXIqIGFsbG9jYXRlKHN0ZDo6c2l6ZV90IG4pCiAgewogICAgYXNzZXJ0KHBvaW50ZXJfaW5fYnVmZmVyKHB0cl8pICYmCiAgICAgICJzdGFja19hbGxvY2F0b3IgaGFzIG91dGxpdmVkIHN0YWNrX3N0b3JlIik7CgogICAgbiA9IGFsaWduKG4pOwoKICAgIGlmIChidWZfICsgTiA+PSBwdHJfICsgbikKICAgIHsKICAgICAgYXV0byByKHB0cl8pOwoKICAgICAgcHRyXyArPSBuOwoKICAgICAgcmV0dXJuIHI7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxjaGFyKj4oOjpvcGVyYXRvciBuZXcobikpOwogICAgfQogIH0KCiAgdm9pZCBkZWFsbG9jYXRlKGNoYXIqIGNvbnN0IHAsIHN0ZDo6c2l6ZV90IG4pIG5vZXhjZXB0CiAgewogICAgYXNzZXJ0KHBvaW50ZXJfaW5fYnVmZmVyKHB0cl8pICYmCiAgICAgICJzdGFja19hbGxvY2F0b3IgaGFzIG91dGxpdmVkIHN0YWNrX3N0b3JlIik7CgogICAgaWYgKHBvaW50ZXJfaW5fYnVmZmVyKHApKQogICAgewogICAgICBuID0gYWxpZ24obik7CgogICAgICBpZiAocCArIG4gPT0gcHRyXykKICAgICAgewogICAgICAgIHB0cl8gPSBwOwogICAgICB9CiAgICAgIC8vIGVsc2UgZG8gbm90aGluZwogICAgfQogICAgZWxzZQogICAgewogICAgICA6Om9wZXJhdG9yIGRlbGV0ZShwKTsKICAgIH0KICB9CgogIHZvaWQgcmVzZXQoKSBub2V4Y2VwdCB7IHB0cl8gPSBidWZfOyB9CgogIHN0YXRpYyBjb25zdGV4cHIgOjpzdGQ6OnNpemVfdCBzaXplKCkgbm9leGNlcHQgeyByZXR1cm4gTjsgfQoKICA6OnN0ZDo6c2l6ZV90IHVzZWQoKSBjb25zdCB7IHJldHVybiA6OnN0ZDo6c2l6ZV90KHB0cl8gLSBidWZfKTsgfQoKcHJpdmF0ZToKICBzdGF0aWMgY29uc3RleHByIDo6c3RkOjpzaXplX3QgYWxpZ24oOjpzdGQ6OnNpemVfdCBjb25zdCBuKSBub2V4Y2VwdAogIHsKICAgIHJldHVybiAobiArIChhbGlnbm1lbnQgLSAxKSkgJiAtYWxpZ25tZW50OwogIH0KCiAgYm9vbCBwb2ludGVyX2luX2J1ZmZlcihjaGFyKiBjb25zdCBwKSBub2V4Y2VwdAogIHsKICAgIHJldHVybiAoYnVmXyA8PSBwKSAmJiAocCA8PSBidWZfICsgTik7CiAgfQoKcHJpdmF0ZToKICBzdGF0aWMgY29uc3RleHByIGF1dG8gY29uc3QgYWxpZ25tZW50ID0gYWxpZ25vZig6Om1heF9hbGlnbl90KTsKCiAgY2hhciogcHRyX3tidWZffTsKCiAgYWxpZ25hcyg6Om1heF9hbGlnbl90KSBjaGFyIGJ1Zl9bTl07Cn07Cgp0ZW1wbGF0ZSA8Y2xhc3MgVCwgc3RkOjpzaXplX3QgTj4KY2xhc3Mgc3RhY2tfYWxsb2NhdG9yCnsKcHVibGljOgogIHVzaW5nIHN0b3JlX3R5cGUgPSBzdGFja19zdG9yZTxOPjsKCiAgdXNpbmcgc2l6ZV90eXBlID0gOjpzdGQ6OnNpemVfdDsKCiAgdXNpbmcgZGlmZmVyZW5jZV90eXBlID0gOjpzdGQ6OnB0cmRpZmZfdDsKCiAgdXNpbmcgcG9pbnRlciA9IFQqOwogIHVzaW5nIGNvbnN0X3BvaW50ZXIgPSBUIGNvbnN0KjsKCiAgdXNpbmcgcmVmZXJlbmNlID0gVCY7CiAgdXNpbmcgY29uc3RfcmVmZXJlbmNlID0gVCBjb25zdCY7CgogIHVzaW5nIHZhbHVlX3R5cGUgPSBUOwoKICB0ZW1wbGF0ZSA8Y2xhc3MgVT4gc3RydWN0IHJlYmluZCB7IHVzaW5nIG90aGVyID0gc3RhY2tfYWxsb2NhdG9yPFUsIE4+OyB9OwoKICBzdGFja19hbGxvY2F0b3IoKSA9IGRlZmF1bHQ7CgogIHN0YWNrX2FsbG9jYXRvcihzdGFja19zdG9yZTxOPiYgcykgbm9leGNlcHQgOiBzdG9yZV8oJnMpIHsgfQoKICB0ZW1wbGF0ZSA8Y2xhc3MgVT4KICBzdGFja19hbGxvY2F0b3Ioc3RhY2tfYWxsb2NhdG9yPFUsIE4+IGNvbnN0JiBvdGhlcikgbm9leGNlcHQgOgogICAgc3RvcmVfKG90aGVyLnN0b3JlXykKICB7CiAgfQoKICBzdGFja19hbGxvY2F0b3ImIG9wZXJhdG9yPShzdGFja19hbGxvY2F0b3IgY29uc3QmKSA9IGRlbGV0ZTsKCiAgVCogYWxsb2NhdGUoOjpzdGQ6OnNpemVfdCBjb25zdCBuKQogIHsKICAgIHJldHVybiBzdGF0aWNfY2FzdDxUKj4oc3RhdGljX2Nhc3Q8dm9pZCo+KAogICAgICBzdG9yZV8tPmFsbG9jYXRlKG4gKiBzaXplb2YoVCkpKSk7CiAgfQoKICB2b2lkIGRlYWxsb2NhdGUoVCogY29uc3QgcCwgOjpzdGQ6OnNpemVfdCBjb25zdCBuKSBub2V4Y2VwdAogIHsKICAgIHN0b3JlXy0+ZGVhbGxvY2F0ZShzdGF0aWNfY2FzdDxjaGFyKj4oc3RhdGljX2Nhc3Q8dm9pZCo+KHApKSwKICAgICAgbiAqIHNpemVvZihUKSk7CiAgfQoKLyoKICB0ZW1wbGF0ZSA8Y2xhc3MgVSwgY2xhc3MgLi4uQT4KICB2b2lkIGNvbnN0cnVjdChVKiBjb25zdCBwLCBBJiYgLi4uYXJncykKICB7CiAgICBuZXcgKHApIFUoOjpzdGQ6OmZvcndhcmQ8QT4oYXJncykuLi4pOwogIH0KCiAgdGVtcGxhdGUgPGNsYXNzIFU+CiAgdm9pZCBkZXN0cm95KFUqIGNvbnN0IHApCiAgewogICAgcC0+flUoKTsKICB9CiovCgogIHRlbXBsYXRlIDxjbGFzcyBVLCBzdGQ6OnNpemVfdCBNPgogIGlubGluZSBib29sIG9wZXJhdG9yPT0oc3RhY2tfYWxsb2NhdG9yPFUsIE0+IGNvbnN0JiByaHMpIGNvbnN0IG5vZXhjZXB0CiAgewogICAgcmV0dXJuIHN0b3JlXyA9PSByaHMuc3RvcmVfOwogIH0KCiAgdGVtcGxhdGUgPGNsYXNzIFUsIHN0ZDo6c2l6ZV90IE0+CiAgaW5saW5lIGJvb2wgb3BlcmF0b3IhPShzdGFja19hbGxvY2F0b3I8VSwgTT4gY29uc3QmIHJocykgY29uc3Qgbm9leGNlcHQKICB7CiAgICByZXR1cm4gISgqdGhpcyA9PSByaHMpOwogIH0KCnByaXZhdGU6CiAgdGVtcGxhdGUgPGNsYXNzIFUsIHN0ZDo6c2l6ZV90IE0+IGZyaWVuZCBjbGFzcyBzdGFja19hbGxvY2F0b3I7CgogIHN0b3JlX3R5cGUqIHN0b3JlX3t9Owp9OwoKbmFtZXNwYWNlIHN0ZAp7CiAgLy8gc3RyaW5nCiAgdGVtcGxhdGU8Y2xhc3MgQ2hhclQ+IGNsYXNzIGNoYXJfdHJhaXRzOwoKICB0ZW1wbGF0ZTxjbGFzcyBDaGFyVCwgY2xhc3MgVHJhaXRzLCBjbGFzcyBBbGxvY2F0b3I+IGNsYXNzIGJhc2ljX3N0cmluZzsKCiAgLy8gdW5vcmRlcmVkX21hcAogIHRlbXBsYXRlPGNsYXNzIEtleSwgY2xhc3MgVCwgY2xhc3MgSGFzaCwgY2xhc3MgUHJlZCwgY2xhc3MgQWxsb2M+CiAgICBjbGFzcyB1bm9yZGVyZWRfbWFwOwoKICAvLyB2ZWN0b3IKICB0ZW1wbGF0ZSA8Y2xhc3MgVCwgY2xhc3MgQWxsb2M+IGNsYXNzIHZlY3RvcjsKfQoKdXNpbmcgc3RhY2tfc3RyaW5nID0gOjpzdGQ6OmJhc2ljX3N0cmluZzxjaGFyLCA6OnN0ZDo6Y2hhcl90cmFpdHM8Y2hhcj4sCiAgc3RhY2tfYWxsb2NhdG9yPGNoYXIsIDEyOD4gPjsKCnRlbXBsYXRlIDxjbGFzcyBLZXksIGNsYXNzIFQsIGNsYXNzIEhhc2ggPSA6OnN0ZDo6aGFzaDxLZXk+LAogIGNsYXNzIFByZWQgPSA6OnN0ZDo6ZXF1YWxfdG88S2V5PiA+CnVzaW5nIHN0YWNrX3Vub3JkZXJlZF9tYXAgPSA6OnN0ZDo6dW5vcmRlcmVkX21hcDxLZXksIFQsIEhhc2gsIFByZWQsCiAgc3RhY2tfYWxsb2NhdG9yPDo6c3RkOjpwYWlyPEtleSBjb25zdCwgVD4sIDI1Nj4gPjsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp1c2luZyBzdGFja192ZWN0b3IgPSA6OnN0ZDo6dmVjdG9yPFQsIHN0YWNrX2FsbG9jYXRvcjxULCAyNTY+ID47CgppbnQgbWFpbigpCnsKICBzdGFja191bm9yZGVyZWRfbWFwPGludCwgaW50Pjo6YWxsb2NhdG9yX3R5cGU6OnN0b3JlX3R5cGUgczsKICBzdGFja191bm9yZGVyZWRfbWFwPGludCwgaW50PiB1KDEwLCBzdGFja191bm9yZGVyZWRfbWFwPGludCwgaW50Pjo6aGFzaGVyKCksCiAgICBzdGFja191bm9yZGVyZWRfbWFwPGludCwgaW50Pjo6a2V5X2VxdWFsKCksIHMpOwogIHJldHVybiAwOwp9
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);
^