#include <deque>
#include <memory>
#include <iostream>
template<class T> class manager {
static void construct(T* p, const T& val) {
new((void*)p) T(val); }
template<class U, class... Args>
static void construct(U* p, Args&&... args) {
new((void*)p) T(std::forward<Args>(args)...); }
class allocator: public std::allocator<T> {
public:
void construct(T* p, const T& val) {
manager::construct(p, val); }
template<class U, class... Args>
void construct(U* p, Args&&... args) {
manager::construct(p, std::forward<Args>(args)...); }
//needed for deque ...dunno why it is using rebind for T
template<class U> struct rebind {
typedef typename std::conditional<
std::is_same<T,U>::value, allocator,
std::allocator<U>>::type other; };
};
std::deque<T, allocator> storage; //deque preserves pointers
public:
template<class... Args>
T* create(Args&&... args) {
storage.emplace_back(std::forward<Args>(args)...);
return &storage.back();
}
};
class special {
friend class manager<special>;
int i;
special(int i): i(i) {}
public:
int get() const { return i; }
};
int main() {
manager<special> m;
special* p = m.create(123);
std::cout << p->get() << std::endl;
}
I2luY2x1ZGUgPGRlcXVlPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8aW9zdHJlYW0+Cgp0ZW1wbGF0ZTxjbGFzcyBUPiBjbGFzcyBtYW5hZ2VyIHsKCXN0YXRpYyB2b2lkIGNvbnN0cnVjdChUKiBwLCBjb25zdCBUJiB2YWwpIHsKCQluZXcoKHZvaWQqKXApIFQodmFsKTsgfQoJdGVtcGxhdGU8Y2xhc3MgVSwgY2xhc3MuLi4gQXJncz4KCSAgc3RhdGljIHZvaWQgY29uc3RydWN0KFUqIHAsIEFyZ3MmJi4uLiBhcmdzKSB7CgkJbmV3KCh2b2lkKilwKSBUKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7IH0KCWNsYXNzIGFsbG9jYXRvcjogcHVibGljIHN0ZDo6YWxsb2NhdG9yPFQ+IHsKCXB1YmxpYzoKCQl2b2lkIGNvbnN0cnVjdChUKiBwLCBjb25zdCBUJiB2YWwpIHsKCQkJbWFuYWdlcjo6Y29uc3RydWN0KHAsIHZhbCk7IH0KCQl0ZW1wbGF0ZTxjbGFzcyBVLCBjbGFzcy4uLiBBcmdzPgoJCSAgdm9pZCBjb25zdHJ1Y3QoVSogcCwgQXJncyYmLi4uIGFyZ3MpIHsKCQkJICBtYW5hZ2VyOjpjb25zdHJ1Y3QocCwgc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsgfQoJLy9uZWVkZWQgZm9yIGRlcXVlIC4uLmR1bm5vIHdoeSBpdCBpcyB1c2luZyByZWJpbmQgZm9yIFQKCQl0ZW1wbGF0ZTxjbGFzcyBVPiBzdHJ1Y3QgcmViaW5kIHsKCQkJdHlwZWRlZiB0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPAoJCQkgIHN0ZDo6aXNfc2FtZTxULFU+Ojp2YWx1ZSwgYWxsb2NhdG9yLAoJCQkgIHN0ZDo6YWxsb2NhdG9yPFU+Pjo6dHlwZSBvdGhlcjsgfTsKCX07CglzdGQ6OmRlcXVlPFQsIGFsbG9jYXRvcj4gc3RvcmFnZTsgLy9kZXF1ZSBwcmVzZXJ2ZXMgcG9pbnRlcnMKcHVibGljOgoJdGVtcGxhdGU8Y2xhc3MuLi4gQXJncz4KCSAgVCogY3JlYXRlKEFyZ3MmJi4uLiBhcmdzKSB7CgkJc3RvcmFnZS5lbXBsYWNlX2JhY2soc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsKCQlyZXR1cm4gJnN0b3JhZ2UuYmFjaygpOwoJfQp9OwoKY2xhc3Mgc3BlY2lhbCB7CglmcmllbmQgY2xhc3MgbWFuYWdlcjxzcGVjaWFsPjsKCWludCBpOwoJc3BlY2lhbChpbnQgaSk6IGkoaSkge30KcHVibGljOgoJaW50IGdldCgpIGNvbnN0IHsgcmV0dXJuIGk7IH0KfTsKCmludCBtYWluKCkgewoJbWFuYWdlcjxzcGVjaWFsPiBtOwoJc3BlY2lhbCogcCA9IG0uY3JlYXRlKDEyMyk7CglzdGQ6OmNvdXQgPDwgcC0+Z2V0KCkgPDwgc3RkOjplbmRsOwp9Cg==