#include <iostream>
#include <iomanip>
#include <memory>
#include <map>

using namespace std;

template < typename T >
struct MyAllocator : std::allocator< T > {

    // ctors
    MyAllocator() = default;
    MyAllocator( MyAllocator const & ) = default;
    template < typename U >
    MyAllocator( MyAllocator<U> const & ) { }

    // member function
    typename std::allocator< T >::pointer
    allocate( typename std::allocator< T >::size_type n,
              std::allocator<void>::const_pointer hint = 0 ) {

        typename std::allocator< T >::pointer result = std::allocator< T >::allocate( n, hint );

        cout << "allocate(" << n << ", " << hint << ") -> " << result << " "
             << "size = " << sizeof( T ) * n << endl;;

        return result;
    }

    // member type
    template < typename U >
    struct rebind {
        typedef MyAllocator<U> other;
    };

};

int main() {

    typedef int iIndex;
    typedef std::string Data;

    typedef map<
                iIndex,
                Data,
                std::less< iIndex >,
                MyAllocator< std::pair<const iIndex, Data> >
               > mapData;

    typedef int iType;
    typedef map<
                iType,
                mapData,
                std::less< iType >,
                MyAllocator< std::pair<const iType, mapData> >
               > Foo;
    Foo foo;

    foo[ 1 ].insert( make_pair(1, "aaa") );

}
