// step1/memory_pool.h

#include <new>
#include <stddef.h>
#include <assert.h>

template <size_t Sz>
class MemoryPool
{
public:
    static void* allocate()
    {
        void* pvResult = s_pMemoryPool;
        if (pvResult == 0)
        {
            return ::operator new(Sz >= sizeof(BlockList)
                                  ? Sz : sizeof(BlockList),
                                  std::nothrow);
        }
        s_pMemoryPool = s_pMemoryPool->m_pNext;
        return pvResult;
    }
    static void deallocate(void* pvReturn)
    {
        assert(pvReturn != NULL);
        BlockList* pBlockList = reinterpret_cast<BlockList*>(pvReturn);
        pBlockList->m_pNext = s_pMemoryPool;
        s_pMemoryPool = pBlockList;
    }
private:
    static struct BlockList { BlockList* m_pNext; }* s_pMemoryPool;
};

template <size_t Sz>
    typename MemoryPool<Sz>::BlockList*
        MemoryPool<Sz>::s_pMemoryPool = NULL;