/*
Accessing the object within this class using the -> opterator will be locked.

	locking_pointer<my_class> X(new my_class);
	X->func();

Using the * dereference operator but due to a language restriction an extra *
will be needed.

	locking_ptr<int> X(new int);
	**x = 0;

*/

//std
#include <iostream>
#include <vector>

template <class T>
class locking_pointer
{
public:
	locking_pointer(T * t): pointee(t){}
 
	class proxy
	{
	public:
		proxy(T * t): pointee(t){ std::cout << "lock\n"; }
		~proxy(){ std::cout << "unlock\n"; }
		T * operator -> (){ return pointee; }
		T & operator * (){ return *pointee; }
	private:
		T * pointee;
	};

	proxy operator -> (){ return proxy(pointee); }
	proxy operator * (){ return proxy(pointee); }

private:
	T * pointee;
};

int main(int argc, char ** argv)
{
	locking_pointer<std::vector<int> > test_1(new std::vector<int>);
	test_1->push_back(1);

	locking_pointer<int> test_2(new int(1));
	std::cout << **test_2 << "\n";

	return 0;
}
