#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;
}
