template<typename T> class unique_ptr {
	T * p;
public:
	unique_ptr() : p(nullptr) {}
	~unique_ptr() {
		if (p) delete p;
	}
	unique_ptr(T *p ) : p(p) {}  
	unique_ptr(const unique_ptr& p) = delete;
	unique_ptr(unique_ptr&& other){
		p = other.p;
		other.p = nullptr;
	}
	unique_ptr& operator=(const unique_ptr& p) = delete;
	unique_ptr& operator=(unique_ptr&& other){
		auto tmp = p;
		p = other.p;
		other.p = tmp;
		return *this;
	}

	T& operator*() {
		return *p;
	}

	const T& operator*() const {
		return *p;
	}

	T* operator->() {
		return p;
	}


};
#include <utility>
template<typename T, typename... Args>
unique_ptr<T> make_unique(Args&&... args) {
	return unique_ptr<T>(new T(std::forward<Args>(args)...));
}

#include <iostream>
using namespace std;

struct test {
	test(int x, int y) {}
	void kvakni() { cout << "qaq" << endl; }
	~test() { cout << "delete" << endl; }
};

int main() {
	auto p = make_unique<test>(3,4);
	//unique_ptr<test> p(new test);

	p->kvakni();
	(*p).kvakni();
	return 0;
}
