#pragma once

#include <typeinfo>
#include <typeindex>
#include <string>

namespace psemek::util
{

	std::string type_name(std::type_info const & type);
	std::string type_name(std::type_index const & type);

	template <typename T>
	std::string const & type_name()
	{
		static std::string const result = type_name(typeid(T));
		return result;
	}

	template <typename T>
	std::string type_name(T const & x)
	{
		return type_name(typeid(x));
	}

	template <typename T>
	struct dynamic_ptr
	{
		T * ptr;
	};

	template <typename OStream, typename T>
	auto & operator << (OStream & os, dynamic_ptr<T> const & d)
	{
		if (!d.ptr)
			return os << d.ptr;
		else
			return os << "<" << type_name(*d.ptr) << " " << d.ptr << ">";
	}

}
