#include <unordered_map>
#include <memory>
template<typename T>
class TestAllocator;
template<>
class TestAllocator<void>
{
public:
typedef void * pointer;
typedef const void * const_pointer;
typedef void value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
//typedef T & reference; not possible for void
//typedef const T & const_reference; not possible for void
template<typename U>
struct rebind
{
typedef TestAllocator<U> other;
};
};
template<typename T>
class TestAllocator
{
public:
typedef T * pointer;
typedef const T * const_pointer;
typedef T & reference;
typedef const T & const_reference;
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
template<typename U>
struct rebind
{
typedef TestAllocator<U> other;
};
TestAllocator() { }
template<typename U>
TestAllocator(const TestAllocator<U> &other) { }
pointer allocate(int n, pointer hint=0) { return new T[n]; }
pointer deallocate(pointer p, size_t n) { delete[] p; }
pointer address(reference x) { return &x; } // hack! should be std::addressof(x);
void construct(pointer p, const_reference val) { new (p) value_type(val); }
void destroy(pointer p) { p->~value_type(); }
};
struct Foo
{
int a, b;
bool operator <(const Foo &r) const
{
return a < r.a;
}
};
struct Bar { float a, b; };
struct TrivialHash
{
size_t operator()(const Foo &a) const
{
return a.a;
}
};
struct TrivialEqual
{
bool operator()(const Foo &a, const Foo &b) const
{
return a.a == b.a;
}
};
typedef std::unordered_map<
Foo, Bar,
TrivialHash,
TrivialEqual,
TestAllocator<int>
> TestContainer;
int main()
{
TestContainer x;
x.insert(TestContainer::value_type(Foo(), Bar()));
return 0;
}
I2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDxtZW1vcnk+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpjbGFzcyBUZXN0QWxsb2NhdG9yOwoKdGVtcGxhdGU8PgpjbGFzcyBUZXN0QWxsb2NhdG9yPHZvaWQ+CnsKcHVibGljOgogIHR5cGVkZWYgdm9pZCAqIHBvaW50ZXI7CiAgdHlwZWRlZiBjb25zdCB2b2lkICogY29uc3RfcG9pbnRlcjsKICB0eXBlZGVmIHZvaWQgdmFsdWVfdHlwZTsKICB0eXBlZGVmIHNpemVfdCBzaXplX3R5cGU7CiAgdHlwZWRlZiBwdHJkaWZmX3QgZGlmZmVyZW5jZV90eXBlOwogIC8vdHlwZWRlZiBUICYgcmVmZXJlbmNlOyBub3QgcG9zc2libGUgZm9yIHZvaWQKICAvL3R5cGVkZWYgY29uc3QgVCAmIGNvbnN0X3JlZmVyZW5jZTsgbm90IHBvc3NpYmxlIGZvciB2b2lkCiAgCiAgdGVtcGxhdGU8dHlwZW5hbWUgVT4KICBzdHJ1Y3QgcmViaW5kCiAgewogICAgdHlwZWRlZiBUZXN0QWxsb2NhdG9yPFU+IG90aGVyOyAgCiAgfTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmNsYXNzIFRlc3RBbGxvY2F0b3IKewpwdWJsaWM6CiAgdHlwZWRlZiBUICogcG9pbnRlcjsKICB0eXBlZGVmIGNvbnN0IFQgKiBjb25zdF9wb2ludGVyOwogIHR5cGVkZWYgVCAmIHJlZmVyZW5jZTsKICB0eXBlZGVmIGNvbnN0IFQgJiBjb25zdF9yZWZlcmVuY2U7CiAgdHlwZWRlZiBUIHZhbHVlX3R5cGU7CiAgdHlwZWRlZiBzaXplX3Qgc2l6ZV90eXBlOwogIHR5cGVkZWYgcHRyZGlmZl90IGRpZmZlcmVuY2VfdHlwZTsKICAKICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgogIHN0cnVjdCByZWJpbmQKICB7CiAgICB0eXBlZGVmIFRlc3RBbGxvY2F0b3I8VT4gb3RoZXI7ICAKICB9OwogIAogIFRlc3RBbGxvY2F0b3IoKSB7IH0KICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgogIFRlc3RBbGxvY2F0b3IoY29uc3QgVGVzdEFsbG9jYXRvcjxVPiAmb3RoZXIpIHsgfQogIAogIHBvaW50ZXIgYWxsb2NhdGUoaW50IG4sIHBvaW50ZXIgaGludD0wKSB7IHJldHVybiBuZXcgVFtuXTsgfQogIHBvaW50ZXIgZGVhbGxvY2F0ZShwb2ludGVyIHAsIHNpemVfdCBuKSB7IGRlbGV0ZVtdIHA7IH0KICBwb2ludGVyIGFkZHJlc3MocmVmZXJlbmNlIHgpIHsgcmV0dXJuICZ4OyB9IC8vIGhhY2shIHNob3VsZCBiZSBzdGQ6OmFkZHJlc3NvZih4KTsKICB2b2lkIGNvbnN0cnVjdChwb2ludGVyIHAsIGNvbnN0X3JlZmVyZW5jZSB2YWwpIHsgbmV3IChwKSB2YWx1ZV90eXBlKHZhbCk7IH0KICB2b2lkIGRlc3Ryb3kocG9pbnRlciBwKSB7IHAtPn52YWx1ZV90eXBlKCk7IH0KfTsKCnN0cnVjdCBGb28KewogICAgaW50IGEsIGI7CiAgICBib29sIG9wZXJhdG9yIDwoY29uc3QgRm9vICZyKSBjb25zdAogICAgewogICAgICAgIHJldHVybiBhIDwgci5hOwogICAgfQp9OwoKc3RydWN0IEJhciB7IGZsb2F0IGEsIGI7IH07CgpzdHJ1Y3QgVHJpdmlhbEhhc2gKewogICAgc2l6ZV90IG9wZXJhdG9yKCkoY29uc3QgRm9vICZhKSBjb25zdAogICAgewogICAgICAgIHJldHVybiBhLmE7CiAgICB9Cn07CgpzdHJ1Y3QgVHJpdmlhbEVxdWFsCnsKICAgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBGb28gJmEsIGNvbnN0IEZvbyAmYikgY29uc3QKICAgIHsKICAgICAgICByZXR1cm4gYS5hID09IGIuYTsKICAgIH0KfTsKCnR5cGVkZWYgc3RkOjp1bm9yZGVyZWRfbWFwPAogIEZvbywgQmFyLAogIFRyaXZpYWxIYXNoLAogIFRyaXZpYWxFcXVhbCwKICBUZXN0QWxsb2NhdG9yPGludD4KPiBUZXN0Q29udGFpbmVyOwoKaW50IG1haW4oKQp7CiAgICBUZXN0Q29udGFpbmVyIHg7CiAgICB4Lmluc2VydChUZXN0Q29udGFpbmVyOjp2YWx1ZV90eXBlKEZvbygpLCBCYXIoKSkpOwogICAgcmV0dXJuIDA7Cn0K