#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< void >
> TestContainer;
int main( )
{
TestContainer x;
x.insert ( TestContainer:: value_type ( Foo( ) , Bar( ) ) ) ;
return 0 ;
}
I2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CiNpbmNsdWRlIDxtZW1vcnk+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpjbGFzcyBUZXN0QWxsb2NhdG9yOwoKdGVtcGxhdGU8PgpjbGFzcyBUZXN0QWxsb2NhdG9yPHZvaWQ+CnsKcHVibGljOgogIHR5cGVkZWYgdm9pZCAqIHBvaW50ZXI7CiAgdHlwZWRlZiBjb25zdCB2b2lkICogY29uc3RfcG9pbnRlcjsKICB0eXBlZGVmIHZvaWQgdmFsdWVfdHlwZTsKICB0eXBlZGVmIHNpemVfdCBzaXplX3R5cGU7CiAgdHlwZWRlZiBwdHJkaWZmX3QgZGlmZmVyZW5jZV90eXBlOwogIC8vdHlwZWRlZiBUICYgcmVmZXJlbmNlOyBub3QgcG9zc2libGUgZm9yIHZvaWQKICAvL3R5cGVkZWYgY29uc3QgVCAmIGNvbnN0X3JlZmVyZW5jZTsgbm90IHBvc3NpYmxlIGZvciB2b2lkCiAgCiAgdGVtcGxhdGU8dHlwZW5hbWUgVT4KICBzdHJ1Y3QgcmViaW5kCiAgewogICAgdHlwZWRlZiBUZXN0QWxsb2NhdG9yPFU+IG90aGVyOyAgCiAgfTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CmNsYXNzIFRlc3RBbGxvY2F0b3IKewpwdWJsaWM6CiAgdHlwZWRlZiBUICogcG9pbnRlcjsKICB0eXBlZGVmIGNvbnN0IFQgKiBjb25zdF9wb2ludGVyOwogIHR5cGVkZWYgVCAmIHJlZmVyZW5jZTsKICB0eXBlZGVmIGNvbnN0IFQgJiBjb25zdF9yZWZlcmVuY2U7CiAgdHlwZWRlZiBUIHZhbHVlX3R5cGU7CiAgdHlwZWRlZiBzaXplX3Qgc2l6ZV90eXBlOwogIHR5cGVkZWYgcHRyZGlmZl90IGRpZmZlcmVuY2VfdHlwZTsKICAKICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgogIHN0cnVjdCByZWJpbmQKICB7CiAgICB0eXBlZGVmIFRlc3RBbGxvY2F0b3I8VT4gb3RoZXI7ICAKICB9OwogIAogIFRlc3RBbGxvY2F0b3IoKSB7IH0KICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgogIFRlc3RBbGxvY2F0b3IoY29uc3QgVGVzdEFsbG9jYXRvcjxVPiAmb3RoZXIpIHsgfQogIAogIHBvaW50ZXIgYWxsb2NhdGUoaW50IG4sIHBvaW50ZXIgaGludD0wKSB7IHJldHVybiBuZXcgVFtuXTsgfQogIHBvaW50ZXIgZGVhbGxvY2F0ZShwb2ludGVyIHAsIHNpemVfdCBuKSB7IGRlbGV0ZVtdIHA7IH0KICBwb2ludGVyIGFkZHJlc3MocmVmZXJlbmNlIHgpIHsgcmV0dXJuICZ4OyB9IC8vIGhhY2shIHNob3VsZCBiZSBzdGQ6OmFkZHJlc3NvZih4KTsKICB2b2lkIGNvbnN0cnVjdChwb2ludGVyIHAsIGNvbnN0X3JlZmVyZW5jZSB2YWwpIHsgbmV3IChwKSB2YWx1ZV90eXBlKHZhbCk7IH0KICB2b2lkIGRlc3Ryb3kocG9pbnRlciBwKSB7IHAtPn52YWx1ZV90eXBlKCk7IH0KfTsKCnN0cnVjdCBGb28KewogICAgaW50IGEsIGI7CiAgICBib29sIG9wZXJhdG9yIDwoY29uc3QgRm9vICZyKSBjb25zdAogICAgewogICAgICAgIHJldHVybiBhIDwgci5hOwogICAgfQp9OwoKc3RydWN0IEJhciB7IGZsb2F0IGEsIGI7IH07CgpzdHJ1Y3QgVHJpdmlhbEhhc2gKewogICAgc2l6ZV90IG9wZXJhdG9yKCkoY29uc3QgRm9vICZhKSBjb25zdAogICAgewogICAgICAgIHJldHVybiBhLmE7CiAgICB9Cn07CgpzdHJ1Y3QgVHJpdmlhbEVxdWFsCnsKICAgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBGb28gJmEsIGNvbnN0IEZvbyAmYikgY29uc3QKICAgIHsKICAgICAgICByZXR1cm4gYS5hID09IGIuYTsKICAgIH0KfTsKCnR5cGVkZWYgc3RkOjp1bm9yZGVyZWRfbWFwPAogIEZvbywgQmFyLAogIFRyaXZpYWxIYXNoLAogIFRyaXZpYWxFcXVhbCwKICBUZXN0QWxsb2NhdG9yPHZvaWQ+Cj4gVGVzdENvbnRhaW5lcjsKCmludCBtYWluKCkKewogICAgVGVzdENvbnRhaW5lciB4OwogICAgeC5pbnNlcnQoVGVzdENvbnRhaW5lcjo6dmFsdWVfdHlwZShGb28oKSwgQmFyKCkpKTsKICAgIHJldHVybiAwOwp9Cg==
compilation info
In file included from /usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/unordered_map:45:0,
from prog.cpp:1:
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/hashtable.h: In instantiation of 'std::_Hashtable<Foo, std::pair<const Foo, Bar>, TestAllocator<void>, std::_Select1st<std::pair<const Foo, Bar> >, TrivialEqual, TrivialHash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>':
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/unordered_map.h:49:5: instantiated from 'std::__unordered_map<Foo, Bar, TrivialHash, TrivialEqual, TestAllocator<void>, false>'
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/unordered_map.h:222:5: instantiated from 'std::unordered_map<Foo, Bar, TrivialHash, TrivialEqual, TestAllocator<void> >'
prog.cpp:91:19: instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/hashtable.h:140:59: error: no type named 'reference' in 'class TestAllocator<void>'
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/hashtable.h:141:59: error: no type named 'const_reference' in 'class TestAllocator<void>'
stdout