/** Trying this again. Simpler approach, maybe...
**/

#include <cstddef>
#include <limits>
#include <new>
#include <stdexcept>
#include <iostream>
#include <cstdlib>

template <typename T> class MemoryManager
{
    public:
    /** Typedefs **/
        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;

        T* allocate(size_t n) const;
        void deallocate(T* const buffer, size_t) const;
        void construct(T* const ptr, const T& value) const;
        size_t max_size() const;
        MemoryManager() {};

        template <typename U> struct rebind
        {
            typedef MemoryManager<U> other;
        };
};

template <typename T>
T* MemoryManager<T>::allocate(size_t n) const
{
    if(n == 0)
        return NULL;

    if(n > max_size())
    {
        throw std::length_error("Integer overflow at MemoryManager::allocate()");
    }

    T* buffer = static_cast<T*>(malloc(n * sizeof(T)));

    if(buffer == NULL)
    {
        throw std::bad_alloc();
    }

    std::cout << (n * sizeof(T)) << " bytes allocated.\n";
    return buffer;
}

template <typename T>
void MemoryManager<T>::deallocate(T* const buffer, size_t) const
{
    free(buffer);
    std::cout << "Buffer deallocated.\n";
}

template <typename T>
void MemoryManager<T>::construct(T* const ptr, const T& value) const
{
    void* const placement = static_cast<void*>(ptr);
    new (placement) T(value);
}

template <typename T>
size_t MemoryManager<T>::max_size() const
{
    return std::numeric_limits<size_t>::max();
}

#include <vector>
#include <iostream>
int main()
{
    auto f = [&](int i){std::cout<< i << "\t";};

	std::vector<int, MemoryManager<int> > v = {1,2,3,4,5};

	for(int i : v)
	{
		f(i);
	}
}