I would like to take advantage of the following advertised feature of boost::fast_pool_allocator (see the Boost documentation for Boost Pool):
You pass the custom allocator into your std::map class. So, this allocator will be used for everything inside of std::map: for all Obj data and also for nodes of a binary tree of std::map. As the result, if you call purge_memory() in Foo's destructor then all this memory becomes invalid, and it crashes in std::map destructor.
Your assumption that a custom allocator is responsible for objects' de-allocation is not correct: it's a std::map's task to free all objects. So, ~Obj() will be called regardless if you pass the custom allocator or if you use a default one.
I don't see any elegant solution for your question. But this approach should work:
placement new to create Foo object from pool's memory,Foo object as usual,purge_memory() to release all memory from the pool. No destructors ~Obj or ~std::map will be called.