#include <memory>
#include <new>
#include <cstdlib>
template<typename T, typename... Args>
T*
allocate(Args&&... args)
{
std::unique_ptr<T, void(*)(void*)> hold(static_cast<T*>(std::malloc(sizeof(T))),
std::free);
::new (hold.get()) T(std::forward<Args>(args)...);
return static_cast<T*>(hold.release());
}
template<typename T>
void
deallocate(void* p)
{
static_cast<T*>(p)->~T();
std::free(p);
}
#include <iostream>
struct Base
{
int i;
Base(int i) : i(i) {std::cout << "Base() " << i << std::endl ;}
Base(const Base&) = delete;
Base& operator=(const Base&) = delete;
~Base() {std::cout << "~Base() " << i << std::endl;}
virtual void bark() const {std::cout << "Hi Base! " << i << std::endl;}
};
struct Derived
: public Base
{
double d;
Derived(int i, double d) : Base(i), d(d) {std::cout << "Derived() " << i << " " << d << std::endl;}
Derived(const Base&) = delete;
Derived& operator=(const Derived&) = delete;
~Derived() {std::cout << "~Derived() " << i << " " << d << std::endl;}
void bark() const {std::cout << "Hi Derived! " << i << " " << d << std::endl;}
};
int
main()
{
std::unique_ptr<Base, void(*)(void*)> p(allocate<Derived>(42, 10.42), deallocate<Derived>);
p->bark();
std::unique_ptr<Base, void(*)(void*)> p2 = std::move(p);
p2->bark();
}
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPG5ldz4KI2luY2x1ZGUgPGNzdGRsaWI+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBBcmdzPgpUKgphbGxvY2F0ZShBcmdzJiYuLi4gYXJncykKewogICAgc3RkOjp1bmlxdWVfcHRyPFQsIHZvaWQoKikodm9pZCopPiBob2xkKHN0YXRpY19jYXN0PFQqPihzdGQ6Om1hbGxvYyhzaXplb2YoVCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjpmcmVlKTsKICAgIDo6bmV3IChob2xkLmdldCgpKSBUKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7CiAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VCo+KGhvbGQucmVsZWFzZSgpKTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kdm9pZApkZWFsbG9jYXRlKHZvaWQqIHApCnsKICAgIHN0YXRpY19jYXN0PFQqPihwKS0+flQoKTsKICAgIHN0ZDo6ZnJlZShwKTsKfQoKI2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IEJhc2UKewogICAgaW50IGk7CiAgICBCYXNlKGludCBpKSA6IGkoaSkge3N0ZDo6Y291dCA8PCAiQmFzZSgpICIgPDwgaSA8PCBzdGQ6OmVuZGwgO30KICAgIEJhc2UoY29uc3QgQmFzZSYpID0gZGVsZXRlOwogICAgQmFzZSYgb3BlcmF0b3I9KGNvbnN0IEJhc2UmKSA9IGRlbGV0ZTsKICAgIH5CYXNlKCkge3N0ZDo6Y291dCA8PCAifkJhc2UoKSAiIDw8IGkgPDwgc3RkOjplbmRsO30KCiAgICB2aXJ0dWFsIHZvaWQgYmFyaygpIGNvbnN0IHtzdGQ6OmNvdXQgPDwgIkhpIEJhc2UhICIgPDwgaSA8PCBzdGQ6OmVuZGw7fQp9OwoKc3RydWN0IERlcml2ZWQKICAgIDogcHVibGljIEJhc2UKewogICAgZG91YmxlIGQ7CiAgICBEZXJpdmVkKGludCBpLCBkb3VibGUgZCkgOiBCYXNlKGkpLCBkKGQpIHtzdGQ6OmNvdXQgPDwgIkRlcml2ZWQoKSAiIDw8IGkgPDwgIiAiIDw8IGQgPDwgc3RkOjplbmRsO30KICAgIERlcml2ZWQoY29uc3QgQmFzZSYpID0gZGVsZXRlOwogICAgRGVyaXZlZCYgb3BlcmF0b3I9KGNvbnN0IERlcml2ZWQmKSA9IGRlbGV0ZTsKICAgIH5EZXJpdmVkKCkge3N0ZDo6Y291dCA8PCAifkRlcml2ZWQoKSAiIDw8IGkgPDwgIiAiIDw8IGQgPDwgc3RkOjplbmRsO30KCiAgICB2b2lkIGJhcmsoKSBjb25zdCB7c3RkOjpjb3V0IDw8ICJIaSBEZXJpdmVkISAiIDw8IGkgPDwgIiAiIDw8IGQgPDwgc3RkOjplbmRsO30KfTsKCmludAptYWluKCkKewogICAgc3RkOjp1bmlxdWVfcHRyPEJhc2UsIHZvaWQoKikodm9pZCopPiBwKGFsbG9jYXRlPERlcml2ZWQ+KDQyLCAxMC40MiksIGRlYWxsb2NhdGU8RGVyaXZlZD4pOwogICAgcC0+YmFyaygpOwogICAgc3RkOjp1bmlxdWVfcHRyPEJhc2UsIHZvaWQoKikodm9pZCopPiBwMiA9IHN0ZDo6bW92ZShwKTsKICAgIHAyLT5iYXJrKCk7Cn0K