#include <iostream>
#include <functional>
#include <memory>
#include <map>
#include <unordered_map>
#include <vector>
using namespace std;
static constexpr long total_size = 1000000;
template<typename T>
class CountingAllocator
{
public:
shared_ptr<size_t> d_max = make_shared<size_t>(0u);
using value_type = T;
using pointer = T*;
CountingAllocator() = default;
template <typename S>
CountingAllocator(CountingAllocator<S> const& other): d_max(other.d_max) {}
size_t size() const { return *d_max; }
T* allocate(size_t size) {
size *= sizeof(T);
*d_max += size;
return reinterpret_cast<T*>(operator new(size));
}
void deallocate(void* ptr, size_t) {
operator delete(ptr);
}
friend bool operator== (CountingAllocator const& c0, CountingAllocator const& c1) {
return c0.d_max == c1.d_max;
}
friend bool operator!= (CountingAllocator const& c0, CountingAllocator const& c1) {
return !(c0 == c1);
}
};
template <typename T>
void size(char const* name) {
CountingAllocator<typename T::value_type> allocator;
T m(allocator);
for (int i = 0; i != total_size; ++i) {
m[i] = i;
}
cout << name << "=" << allocator.size() << "\n";
}
int main() {
size<map<long, long long, less<int>, CountingAllocator<pair<long const, long long>>>>("map");
size<unordered_map<long, long long, hash<long>, equal_to<long>, CountingAllocator<pair<long const, long long>>>>("unordered_map");
cout << "array=" << sizeof(long long[total_size]) << "\n";
return 0;
}
ICAgICNpbmNsdWRlIDxpb3N0cmVhbT4KICAgICNpbmNsdWRlIDxmdW5jdGlvbmFsPgogICAgI2luY2x1ZGUgPG1lbW9yeT4KICAgICNpbmNsdWRlIDxtYXA+CiAgICAjaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KICAgICNpbmNsdWRlIDx2ZWN0b3I+CgogICAgdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCiAgICBzdGF0aWMgY29uc3RleHByIGxvbmcgdG90YWxfc2l6ZSA9IDEwMDAwMDA7CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgIGNsYXNzIENvdW50aW5nQWxsb2NhdG9yCiAgICB7CiAgICBwdWJsaWM6CiAgICAgICAgc2hhcmVkX3B0cjxzaXplX3Q+IGRfbWF4ID0gbWFrZV9zaGFyZWQ8c2l6ZV90PigwdSk7CiAgICAgICAgdXNpbmcgdmFsdWVfdHlwZSA9IFQ7CiAgICAgICAgdXNpbmcgcG9pbnRlciA9IFQqOwoKICAgICAgICBDb3VudGluZ0FsbG9jYXRvcigpID0gZGVmYXVsdDsKICAgICAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgUz4KICAgICAgICBDb3VudGluZ0FsbG9jYXRvcihDb3VudGluZ0FsbG9jYXRvcjxTPiBjb25zdCYgb3RoZXIpOiBkX21heChvdGhlci5kX21heCkge30KICAgICAgICBzaXplX3Qgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuICpkX21heDsgfQogICAgICAgIFQqIGFsbG9jYXRlKHNpemVfdCBzaXplKSB7CiAgICAgICAgICAgIHNpemUgKj0gc2l6ZW9mKFQpOwogICAgICAgICAgICAqZF9tYXggKz0gc2l6ZTsKICAgICAgICAgICAgcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8VCo+KG9wZXJhdG9yIG5ldyhzaXplKSk7CiAgICAgICAgfQogICAgICAgIHZvaWQgZGVhbGxvY2F0ZSh2b2lkKiBwdHIsIHNpemVfdCkgewogICAgICAgICAgICBvcGVyYXRvciBkZWxldGUocHRyKTsKICAgICAgICB9CiAgICAgICAgZnJpZW5kIGJvb2wgb3BlcmF0b3I9PSAoQ291bnRpbmdBbGxvY2F0b3IgY29uc3QmIGMwLCBDb3VudGluZ0FsbG9jYXRvciBjb25zdCYgYzEpIHsKICAgICAgICAgICAgcmV0dXJuIGMwLmRfbWF4ID09IGMxLmRfbWF4OwogICAgICAgIH0gCgogICAgICAgIGZyaWVuZCBib29sIG9wZXJhdG9yIT0gKENvdW50aW5nQWxsb2NhdG9yIGNvbnN0JiBjMCwgQ291bnRpbmdBbGxvY2F0b3IgY29uc3QmIGMxKSB7CiAgICAgICAgICAgIHJldHVybiAhKGMwID09IGMxKTsKICAgICAgICB9CiAgICB9OwoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgogICAgdm9pZCBzaXplKGNoYXIgY29uc3QqIG5hbWUpIHsKICAgICAgICBDb3VudGluZ0FsbG9jYXRvcjx0eXBlbmFtZSBUOjp2YWx1ZV90eXBlPiBhbGxvY2F0b3I7CiAgICAgICAgVCBtKGFsbG9jYXRvcik7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgIT0gdG90YWxfc2l6ZTsgKytpKSB7CiAgICAgICAgICAgIG1baV0gPSBpOwogICAgICAgIH0KICAgICAgICBjb3V0IDw8IG5hbWUgPDwgIj0iICA8PCBhbGxvY2F0b3Iuc2l6ZSgpIDw8ICJcbiI7CiAgICB9CgogICAgaW50IG1haW4oKSB7CiAgICAgICAgc2l6ZTxtYXA8bG9uZywgbG9uZyBsb25nLCBsZXNzPGludD4sIENvdW50aW5nQWxsb2NhdG9yPHBhaXI8bG9uZyBjb25zdCwgbG9uZyBsb25nPj4+PigibWFwIik7CiAgICAgICAgc2l6ZTx1bm9yZGVyZWRfbWFwPGxvbmcsIGxvbmcgbG9uZywgaGFzaDxsb25nPiwgZXF1YWxfdG88bG9uZz4sIENvdW50aW5nQWxsb2NhdG9yPHBhaXI8bG9uZyBjb25zdCwgbG9uZyBsb25nPj4+PigidW5vcmRlcmVkX21hcCIpOwogICAgICAgIGNvdXQgPDwgImFycmF5PSIgPDwgc2l6ZW9mKGxvbmcgbG9uZ1t0b3RhbF9zaXplXSkgPDwgIlxuIjsKCSAgICByZXR1cm4gMDsKICAgIH0=