#include <iostream>
#include <cstdint>
#include <utility>
template <typename T>
struct noop_destructor {
public:
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
template<typename... Args>
noop_destructor(Args&&... args) {
new (reinterpret_cast<void*>(wrapped_data)) T(std::forward<Args>(args)...);
}
explicit noop_destructor(const noop_destructor& rhs) {
std::copy(rhs.wrapped_data,rhs.wrapped_data+sizeof(T),wrapped_data);
}
noop_destructor& operator=(const noop_destructor& rhs) {
std::copy(rhs.wrapped_data,rhs.wrapped_data+sizeof(T),wrapped_data);
return *this;
}
pointer operator->() {
return reinterpret_cast<pointer>(wrapped_data);
}
const_pointer operator->() const {
return reinterpret_cast<const_pointer>(wrapped_data);
}
reference operator*() {
return *reinterpret_cast<pointer>(wrapped_data);
}
const_reference operator*() const {
return *reinterpret_cast<const_pointer>(wrapped_data);
}
private:
uint8_t wrapped_data[sizeof(T)] __attribute__ ((aligned (__BIGGEST_ALIGNMENT__)));
};
class A {
public:
A() : x_() {}
A(int x) : x_(x) {}
~A() {
std::cout << "noop destructor call of class A" << std::endl;
}
void foo() {
std::cout << "x_ = " << x_ << std::endl;
}
private:
int x_;
};
int main() {
A a1(5);
noop_destructor<A> a2;
a1.foo();
(*a2).foo();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGludD4KI2luY2x1ZGUgPHV0aWxpdHk+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IG5vb3BfZGVzdHJ1Y3RvciB7CnB1YmxpYzoKCXR5cGVkZWYgVCogcG9pbnRlcjsKCXR5cGVkZWYgY29uc3QgVCogY29uc3RfcG9pbnRlcjsKCXR5cGVkZWYgVCYgcmVmZXJlbmNlOwoJdHlwZWRlZiBjb25zdCBUJiBjb25zdF9yZWZlcmVuY2U7CgogICAgdGVtcGxhdGU8dHlwZW5hbWUuLi4gQXJncz4KCW5vb3BfZGVzdHJ1Y3RvcihBcmdzJiYuLi4gYXJncykgewoJCW5ldyAocmVpbnRlcnByZXRfY2FzdDx2b2lkKj4od3JhcHBlZF9kYXRhKSkgVChzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwoJfQoKICAgIGV4cGxpY2l0IG5vb3BfZGVzdHJ1Y3Rvcihjb25zdCBub29wX2Rlc3RydWN0b3ImIHJocykgewogICAgCXN0ZDo6Y29weShyaHMud3JhcHBlZF9kYXRhLHJocy53cmFwcGVkX2RhdGErc2l6ZW9mKFQpLHdyYXBwZWRfZGF0YSk7CiAgICB9CgogICAgbm9vcF9kZXN0cnVjdG9yJiBvcGVyYXRvcj0oY29uc3Qgbm9vcF9kZXN0cnVjdG9yJiByaHMpIHsKICAgIAlzdGQ6OmNvcHkocmhzLndyYXBwZWRfZGF0YSxyaHMud3JhcHBlZF9kYXRhK3NpemVvZihUKSx3cmFwcGVkX2RhdGEpOwogICAgCXJldHVybiAqdGhpczsKICAgIH0KCiAgICBwb2ludGVyIG9wZXJhdG9yLT4oKSB7CiAgICAJcmV0dXJuIHJlaW50ZXJwcmV0X2Nhc3Q8cG9pbnRlcj4od3JhcHBlZF9kYXRhKTsKICAgIH0KICAgIGNvbnN0X3BvaW50ZXIgb3BlcmF0b3ItPigpIGNvbnN0IHsKICAgIAlyZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdF9wb2ludGVyPih3cmFwcGVkX2RhdGEpOwogICAgfQogICAgcmVmZXJlbmNlIG9wZXJhdG9yKigpIHsKICAgIAlyZXR1cm4gKnJlaW50ZXJwcmV0X2Nhc3Q8cG9pbnRlcj4od3JhcHBlZF9kYXRhKTsKICAgIH0KICAgIGNvbnN0X3JlZmVyZW5jZSBvcGVyYXRvciooKSBjb25zdCB7CiAgICAJcmV0dXJuICpyZWludGVycHJldF9jYXN0PGNvbnN0X3BvaW50ZXI+KHdyYXBwZWRfZGF0YSk7CiAgICB9CnByaXZhdGU6Cgl1aW50OF90IHdyYXBwZWRfZGF0YVtzaXplb2YoVCldIF9fYXR0cmlidXRlX18gKChhbGlnbmVkIChfX0JJR0dFU1RfQUxJR05NRU5UX18pKSk7Cn07CgoKY2xhc3MgQSB7CnB1YmxpYzoKCUEoKSA6IHhfKCkge30KCUEoaW50IHgpIDogeF8oeCkge30KCX5BKCkgewoJCXN0ZDo6Y291dCA8PCAibm9vcCBkZXN0cnVjdG9yIGNhbGwgb2YgY2xhc3MgQSIgPDwgc3RkOjplbmRsOwoJfQoJdm9pZCBmb28oKSB7CgkJc3RkOjpjb3V0IDw8ICJ4XyA9ICIgPDwgeF8gPDwgc3RkOjplbmRsOwoJfQoKcHJpdmF0ZToKCWludCB4XzsKfTsKCmludCBtYWluKCkgewogICAgQSBhMSg1KTsKICAgIG5vb3BfZGVzdHJ1Y3RvcjxBPiBhMjsKCiAgICBhMS5mb28oKTsKICAgICgqYTIpLmZvbygpOwoJcmV0dXJuIDA7Cn0K