#include <list>
#include <vector>
#include <array>
template < typename K, typename V, typename H = std:: hash < K> , typename P = std:: equal_to < K> , typename A = std:: allocator < std:: pair < const K, V>>> class hash_map {
struct item {
std:: pair < const K, V> data;
std:: size_t cached_hash;
} ;
std:: list < item, A> data;
H hash;
P predicate;
static const auto items_per_bucket = 5 ; // Arbitrary- determine by profile if performance undesirable
public :
struct iterator {
iterator( typename std:: list < item, A> :: iterator arg)
: it( arg) { }
typename std:: list < item, A> :: iterator it;
std:: pair < const K, V> & operator* ( ) { return it- > data; }
std:: pair < const K, V> * operator- > ( ) { return & it- > data; }
bool operator== ( iterator other) {
return it == other.it ;
}
iterator operator++ ( int ) {
auto ret( * this ) ;
++ it;
return ret;
}
iterator& operator++ ( ) {
++ it;
return * this ;
}
iterator operator-- ( int ) {
auto ret( * this ) ;
-- it;
return ret;
}
iterator& operator-- ( ) {
-- it;
return * this ;
}
} ;
iterator begin( ) { return iterator( data.begin ( ) ) ; }
iterator end( ) { return iterator( data.end ( ) ) ; }
std:: size_t size( ) const { return data.size ( ) ; }
void clear( ) { data.clear ( ) ; buckets.clear ( ) ; }
private :
std:: vector < std:: vector < iterator>> buckets;
void insert_into_buckets( iterator it) {
if ( buckets.size ( ) == 0 )
rehash( 10 ) ; // Arbitrary- determine by profile if performance undesirable
auto && bucket = buckets[ it- > cached_hash % buckets.size ( ) ] ;
if ( bucket.size ( ) >= items_per_bucket)
rehash( buckets.size ( ) * 2 ) ;
buckets[ it- > cached_hash % buckets.size ( ) ] .push_back ( it) ;
}
public :
void rehash( std:: size_t size) {
auto oldbuckets = std:: move ( buckets) ;
buckets.resize ( size) ;
for ( auto && iterators : oldbuckets) {
for ( auto && i : iterators) {
insert_into_buckets( i) ;
}
}
}
std:: pair < iterator, bool > insert( K k, V v) {
auto it = find( k) ;
if ( it == end( ) ) {
std:: size_t val = hash( k) ;
data.push_back ( item { { std:: move ( k) , std:: move ( v) } , val } ) ;
try {
insert_into_buckets( -- data.end ( ) ) ;
} catch ( ...) {
data.pop_back ( ) ;
throw ;
}
return { -- data.end ( ) , true } ;
}
return { it, false } ;
}
template < typename AK> iterator find( AK&& k) {
return find( std:: forward < AK> ( k) , hash, predicate) ;
}
template < typename AK, typename AH> iterator find( AK&& k, AH&& h) {
return find( std:: forward < AK> ( k) , std:: forward < AH> ( h) , predicate) ;
}
template < typename AK, typename AH, typename AP> iterator find( AK&& k, AH&& h, AP&& p) {
auto && bucket = buckets[ h( k) % buckets.size ( ) ] ;
for ( auto it : bucket) {
if ( p( k, it- > data.first ) )
return it;
}
return end( ) ;
}
template < typename AK> iterator erase( AK&& k) {
return erase( find( std:: forward < AK> ( k) , hash, predicate) ) ;
}
template < typename AK, typename AH> iterator erase( AK&& k, AH&& h) {
return erase( find( std:: forward < AK> ( k) , std:: forward < AH> ( h) , predicate) ) ;
}
template < typename AK, typename AH, typename AP> iterator erase( AK&& k, AH&& h, AP&& p) {
return erase( find( std:: forward < AK> ( k) , std:: forward < AH> ( h) , std: forward< AP> ( p) ) ) ;
}
iterator erase( iterator it) {
auto && bucket = buckets[ it.it - > cached_hash % buckets.size ( ) ] ;
for ( int i = 0 ; i < bucket.size ( ) ; i++ ) {
if ( bucket[ i] == it) {
bucket.erase ( bucket.begin ( ) + i) ;
return data.erase ( it.it ) ;
}
}
return end( ) ;
}
template < typename AK> V& operator[ ] ( AK&& ak) {
auto it = find( std:: forward < AK> ( ak) ) ;
if ( it == end( ) )
return insert( ak, V( ) ) .first - > data.second ;
return it- > data.second ;
}
} ;
int main( ) {
hash_map< int , int > x;
auto y = x.begin ( ) ;
auto z = x.end ( ) ;
x.erase ( y) ;
}
I2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxhcnJheT4KCnRlbXBsYXRlPHR5cGVuYW1lIEssIHR5cGVuYW1lIFYsIHR5cGVuYW1lIEggPSBzdGQ6Omhhc2g8Sz4sIHR5cGVuYW1lIFAgPSBzdGQ6OmVxdWFsX3RvPEs+LCB0eXBlbmFtZSBBID0gc3RkOjphbGxvY2F0b3I8c3RkOjpwYWlyPGNvbnN0IEssIFY+Pj4gY2xhc3MgaGFzaF9tYXAgewogICAgc3RydWN0IGl0ZW0gewogICAgICAgIHN0ZDo6cGFpcjxjb25zdCBLLCBWPiBkYXRhOwogICAgICAgIHN0ZDo6c2l6ZV90IGNhY2hlZF9oYXNoOwogICAgfTsKICAgIHN0ZDo6bGlzdDxpdGVtLCBBPiBkYXRhOwogICAgSCBoYXNoOwogICAgUCBwcmVkaWNhdGU7CiAgICBzdGF0aWMgY29uc3QgYXV0byBpdGVtc19wZXJfYnVja2V0ID0gNTsgLy8gQXJiaXRyYXJ5LSBkZXRlcm1pbmUgYnkgcHJvZmlsZSBpZiBwZXJmb3JtYW5jZSB1bmRlc2lyYWJsZQpwdWJsaWM6CgogICAgc3RydWN0IGl0ZXJhdG9yIHsKICAgICAgICBpdGVyYXRvcih0eXBlbmFtZSBzdGQ6Omxpc3Q8aXRlbSwgQT46Oml0ZXJhdG9yIGFyZykKICAgICAgICAgICAgOiBpdChhcmcpIHt9CgogICAgICAgIHR5cGVuYW1lIHN0ZDo6bGlzdDxpdGVtLCBBPjo6aXRlcmF0b3IgaXQ7CgogICAgICAgIHN0ZDo6cGFpcjxjb25zdCBLLCBWPiYgb3BlcmF0b3IqKCkgeyByZXR1cm4gaXQtPmRhdGE7IH0KICAgICAgICBzdGQ6OnBhaXI8Y29uc3QgSywgVj4qIG9wZXJhdG9yLT4oKSB7IHJldHVybiAmaXQtPmRhdGE7IH0KCiAgICAgICAgYm9vbCBvcGVyYXRvcj09KGl0ZXJhdG9yIG90aGVyKSB7CiAgICAgICAgICAgIHJldHVybiBpdCA9PSBvdGhlci5pdDsKICAgICAgICB9CgogICAgICAgIGl0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSB7CiAgICAgICAgICAgIGF1dG8gcmV0KCp0aGlzKTsKICAgICAgICAgICAgKytpdDsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgaXRlcmF0b3ImIG9wZXJhdG9yKysoKSB7CiAgICAgICAgICAgICsraXQ7CiAgICAgICAgICAgIHJldHVybiAqdGhpczsKICAgICAgICB9CiAgICAgICAgaXRlcmF0b3Igb3BlcmF0b3ItLShpbnQpIHsKICAgICAgICAgICAgYXV0byByZXQoKnRoaXMpOwogICAgICAgICAgICAtLWl0OwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBpdGVyYXRvciYgb3BlcmF0b3ItLSgpIHsKICAgICAgICAgICAgLS1pdDsKICAgICAgICAgICAgcmV0dXJuICp0aGlzOwogICAgICAgIH0KCiAgICB9OwoKICAgIGl0ZXJhdG9yIGJlZ2luKCkgeyByZXR1cm4gaXRlcmF0b3IoZGF0YS5iZWdpbigpKTsgfQogICAgaXRlcmF0b3IgZW5kKCkgeyByZXR1cm4gaXRlcmF0b3IoZGF0YS5lbmQoKSk7IH0KICAgIHN0ZDo6c2l6ZV90IHNpemUoKSBjb25zdCB7IHJldHVybiBkYXRhLnNpemUoKTsgfQogICAgdm9pZCBjbGVhcigpIHsgZGF0YS5jbGVhcigpOyBidWNrZXRzLmNsZWFyKCk7IH0KCnByaXZhdGU6CiAgICBzdGQ6OnZlY3RvcjxzdGQ6OnZlY3RvcjxpdGVyYXRvcj4+IGJ1Y2tldHM7CgogICAgdm9pZCBpbnNlcnRfaW50b19idWNrZXRzKGl0ZXJhdG9yIGl0KSB7CiAgICAgICAgaWYgKGJ1Y2tldHMuc2l6ZSgpID09IDApCiAgICAgICAgICAgIHJlaGFzaCgxMCk7IC8vIEFyYml0cmFyeS0gZGV0ZXJtaW5lIGJ5IHByb2ZpbGUgaWYgcGVyZm9ybWFuY2UgdW5kZXNpcmFibGUKICAgICAgICBhdXRvJiYgYnVja2V0ID0gYnVja2V0c1tpdC0+Y2FjaGVkX2hhc2ggJSBidWNrZXRzLnNpemUoKV07CiAgICAgICAgaWYgKGJ1Y2tldC5zaXplKCkgPj0gaXRlbXNfcGVyX2J1Y2tldCkKICAgICAgICAgICAgcmVoYXNoKGJ1Y2tldHMuc2l6ZSgpICogMik7CiAgICAgICAgYnVja2V0c1tpdC0+Y2FjaGVkX2hhc2ggJSBidWNrZXRzLnNpemUoKV0ucHVzaF9iYWNrKGl0KTsKICAgIH0KcHVibGljOgogICAgdm9pZCByZWhhc2goc3RkOjpzaXplX3Qgc2l6ZSkgewogICAgICAgIGF1dG8gb2xkYnVja2V0cyA9IHN0ZDo6bW92ZShidWNrZXRzKTsKICAgICAgICBidWNrZXRzLnJlc2l6ZShzaXplKTsKICAgICAgICBmb3IoYXV0byYmIGl0ZXJhdG9ycyA6IG9sZGJ1Y2tldHMpIHsKICAgICAgICAgICAgZm9yKGF1dG8mJiBpIDogaXRlcmF0b3JzKSB7CiAgICAgICAgICAgICAgICBpbnNlcnRfaW50b19idWNrZXRzKGkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHN0ZDo6cGFpcjxpdGVyYXRvciwgYm9vbD4gaW5zZXJ0KEsgaywgViB2KSB7CiAgICAgICAgYXV0byBpdCA9IGZpbmQoayk7CiAgICAgICAgaWYgKGl0ID09IGVuZCgpKSB7CiAgICAgICAgICAgIHN0ZDo6c2l6ZV90IHZhbCA9IGhhc2goayk7CiAgICAgICAgICAgIGRhdGEucHVzaF9iYWNrKGl0ZW0geyB7IHN0ZDo6bW92ZShrKSwgc3RkOjptb3ZlKHYpIH0sIHZhbCB9KTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGluc2VydF9pbnRvX2J1Y2tldHMoLS1kYXRhLmVuZCgpKTsKICAgICAgICAgICAgfSBjYXRjaCguLi4pIHsKICAgICAgICAgICAgICAgIGRhdGEucG9wX2JhY2soKTsKICAgICAgICAgICAgICAgIHRocm93OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB7IC0tZGF0YS5lbmQoKSwgdHJ1ZSB9OwogICAgICAgIH0KICAgICAgICByZXR1cm4geyBpdCwgZmFsc2UgfTsKICAgIH0KICAgIAogICAgdGVtcGxhdGU8dHlwZW5hbWUgQUs+IGl0ZXJhdG9yIGZpbmQoQUsmJiBrKSB7CiAgICAgICAgcmV0dXJuIGZpbmQoc3RkOjpmb3J3YXJkPEFLPihrKSwgaGFzaCwgcHJlZGljYXRlKTsKICAgIH0KICAgIHRlbXBsYXRlPHR5cGVuYW1lIEFLLCB0eXBlbmFtZSBBSD4gaXRlcmF0b3IgZmluZChBSyYmIGssIEFIJiYgaCkgewogICAgICAgIHJldHVybiBmaW5kKHN0ZDo6Zm9yd2FyZDxBSz4oayksIHN0ZDo6Zm9yd2FyZDxBSD4oaCksIHByZWRpY2F0ZSk7CiAgICB9CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBBSywgdHlwZW5hbWUgQUgsIHR5cGVuYW1lIEFQPiBpdGVyYXRvciBmaW5kKEFLJiYgaywgQUgmJiBoLCBBUCYmIHApIHsKICAgICAgICBhdXRvJiYgYnVja2V0ID0gYnVja2V0c1toKGspICUgYnVja2V0cy5zaXplKCldOwogICAgICAgIGZvcihhdXRvIGl0IDogYnVja2V0KSB7CiAgICAgICAgICAgIGlmIChwKGssIGl0LT5kYXRhLmZpcnN0KSkKICAgICAgICAgICAgICAgIHJldHVybiBpdDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGVuZCgpOwogICAgfQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEFLPiBpdGVyYXRvciBlcmFzZShBSyYmIGspIHsKICAgICAgICByZXR1cm4gZXJhc2UoZmluZChzdGQ6OmZvcndhcmQ8QUs+KGspLCBoYXNoLCBwcmVkaWNhdGUpKTsKICAgIH0KICAgIHRlbXBsYXRlPHR5cGVuYW1lIEFLLCB0eXBlbmFtZSBBSD4gaXRlcmF0b3IgZXJhc2UoQUsmJiBrLCBBSCYmIGgpIHsKICAgICAgICByZXR1cm4gZXJhc2UoZmluZChzdGQ6OmZvcndhcmQ8QUs+KGspLCBzdGQ6OmZvcndhcmQ8QUg+KGgpLCBwcmVkaWNhdGUpKTsKICAgIH0KICAgIHRlbXBsYXRlPHR5cGVuYW1lIEFLLCB0eXBlbmFtZSBBSCwgdHlwZW5hbWUgQVA+IGl0ZXJhdG9yIGVyYXNlKEFLJiYgaywgQUgmJiBoLCBBUCYmIHApIHsKICAgICAgICByZXR1cm4gZXJhc2UoZmluZChzdGQ6OmZvcndhcmQ8QUs+KGspLCBzdGQ6OmZvcndhcmQ8QUg+KGgpLCBzdGQ6Zm9yd2FyZDxBUD4ocCkpKTsKICAgIH0KCiAgICBpdGVyYXRvciBlcmFzZShpdGVyYXRvciBpdCkgewogICAgICAgIGF1dG8mJiBidWNrZXQgPSBidWNrZXRzW2l0Lml0LT5jYWNoZWRfaGFzaCAlIGJ1Y2tldHMuc2l6ZSgpXTsKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgYnVja2V0LnNpemUoKTsgaSsrKSB7CiAgICAgICAgICAgIGlmIChidWNrZXRbaV0gPT0gaXQpIHsKICAgICAgICAgICAgICAgIGJ1Y2tldC5lcmFzZShidWNrZXQuYmVnaW4oKSArIGkpOwogICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZXJhc2UoaXQuaXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBlbmQoKTsKICAgIH0KCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBBSz4gViYgb3BlcmF0b3JbXShBSyYmIGFrKSB7CiAgICAgICAgYXV0byBpdCA9IGZpbmQoc3RkOjpmb3J3YXJkPEFLPihhaykpOwogICAgICAgIGlmIChpdCA9PSBlbmQoKSkKICAgICAgICAgICAgcmV0dXJuIGluc2VydChhaywgVigpKS5maXJzdC0+ZGF0YS5zZWNvbmQ7CiAgICAgICAgcmV0dXJuIGl0LT5kYXRhLnNlY29uZDsKICAgIH0KfTsKaW50IG1haW4oKSB7CiAgICBoYXNoX21hcDxpbnQsIGludD4geDsKICAgIGF1dG8geSA9IHguYmVnaW4oKTsKICAgIGF1dG8geiA9IHguZW5kKCk7CiAgICB4LmVyYXNlKHkpOwp9
compilation info
prog.cpp: In member function 'void hash_map<K, V, H, P, A>::rehash(size_t)':
prog.cpp:70:30: error: expected initializer before ':' token
prog.cpp:75:5: error: expected primary-expression at end of input
prog.cpp:75:5: error: expected ';' at end of input
prog.cpp:75:5: error: expected primary-expression at end of input
prog.cpp:75:5: error: expected ')' at end of input
prog.cpp:75:5: error: expected statement at end of input
prog.cpp:75:5: error: expected '}' at end of input
prog.cpp: In member function 'hash_map<K, V, H, P, A>::iterator hash_map<K, V, H, P, A>::find(AK&&, AH&&, AP&&)':
prog.cpp:101:21: error: expected initializer before ':' token
prog.cpp:105:9: error: expected primary-expression before 'return'
prog.cpp:105:9: error: expected ';' before 'return'
prog.cpp:105:9: error: expected primary-expression before 'return'
prog.cpp:105:9: error: expected ')' before 'return'
prog.cpp: In member function 'hash_map<K, V, H, P, A>::iterator hash_map<K, V, H, P, A>::erase(AK&&, AH&&, AP&&)':
prog.cpp:115:72: error: expected primary-expression before ':' token
stdout