//////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Exception handling utilities.

#pragma once

// Standard includes
#include <exception>
#include <string>

namespace MTL
{
	/// \brief Exception to be thrown.
	/// \tparam A	Specialization of exception.
	template<class A>
	class CException : public std::exception
	{
	protected:
		std::string			m_Message;			///< Message describing the exception.
		std::string			m_ThrownLocation;	///< Context in which exception was thrown.
		std::string			m_What;				///< Debugging output, with message and location

	public:
		/// \brief Constructor.
		/// \param[in]	rMessage			Message describing the exception.
		/// \param[in]	rThrownLocation		Context in which exception was thrown
		CException(std::string const & rMessage, std::string const & rThrownLocation)
			: m_Message(rMessage), m_ThrownLocation(rThrownLocation)
		{
            m_What = m_ThrownLocation + " : " + m_Message + "\n";
		}

		/// \brief Return string describing what happened.
		virtual const char * what() const noexcept
		{
			return m_What.c_str();
		}

		/// \brief Return the message.
		const char * message() const noexcept
		{
			return m_Message.c_str();
		}

		/// \brief Return the context.
		const char * context() const noexcept
		{
			return m_ThrownLocation.c_str();
		}
	};
} // namespace MTL
