#include <iostream>
#include <map>

class TypeRegistry {
	public:
		TypeRegistry() {
			counter = 0;
		}

		template <typename T>
		int getTypeId() {
			static int id = -1;

			if (id < 0) {
				id = counter++;
			}

			return id;
		}

		static TypeRegistry & getInstance() {
			static TypeRegistry t;

			return t;
		}

	private:
		int counter;
};

class Foo {
	public:
		template <typename T>
		T & get() {
			std::map<int, void*>::iterator i;
			int id;

			id = TypeRegistry::getInstance().getTypeId<T>();
			i = this->values.find(id);

			if (i != this->values.end())
				return *(T*)i->second;

			T *value = new T();
			this->values[id] = value;
			return *value;
		}

		size_t size() const {
			return this->values.size();
		}

	private:
		std::map<int, void*> values;
};



int main()
{
	Foo a, b;

	a.get<int>() = 1;
	a.get<float>() = 3.14;
	b.get<int>() = 2;
	b.get<double>() = 3.14159;
	b.get<float>() = 1.23;

	std::cout << "a<int> = " << a.get<int>() << std::endl; 
	std::cout << "a<float> = " << a.get<float>() << std::endl; 
	std::cout << "size of a = " << a.size() << std::endl; 
	std::cout << "b<int> = " << b.get<int>() << std::endl; 
	std::cout << "b<double> = " << b.get<double>() << std::endl; 
	std::cout << "b<float> = " << b.get<float>() << std::endl; 
	std::cout << "size of b = " << b.size() << std::endl;

	a.get<int>()++;
	a.get<float>() += 3.14;
	b.get<int>() -= 2;
	b.get<double>() *= 3.14159;
	b.get<float>() /= 1.23;

	std::cout << "a<int> = " << a.get<int>() << std::endl; 
	std::cout << "a<float> = " << a.get<float>() << std::endl; 
	std::cout << "size of a = " << a.size() << std::endl; 
	std::cout << "b<int> = " << b.get<int>() << std::endl; 
	std::cout << "b<double> = " << b.get<double>() << std::endl; 
	std::cout << "b<float> = " << b.get<float>() << std::endl; 
	std::cout << "size of b = " << b.size() << std::endl;

	return 0;
}


