#define LTT_LOG_LEVEL LTT_LOG_DEBUG_LEVEL
#define LTT_LOG_BREAK LTT_LOG_CRITICAL_LEVEL

#include <cstdlib>
#include <iostream>

namespace LTT
{
	class IgnoreStreamT
	{
		IgnoreStreamT(IgnoreStreamT const& Rhs);
		IgnoreStreamT& operator= (IgnoreStreamT const& Rhs);
		
	public:
		IgnoreStreamT()
		{
		}
	};
	
	IgnoreStreamT IgnoreStream;
	
	template<typename T>
	IgnoreStreamT& operator<< (IgnoreStreamT& Stream, T const& Object)
	{
		return Stream;
	};
	
	class AbortStreamT
	{
		AbortStreamT(AbortStreamT const& Rhs);
		AbortStreamT& operator= (AbortStreamT const& Rhs);
		
	public:
		AbortStreamT()
		{
		}
	};
	
	AbortStreamT AbortStream;
	
	template<typename T>
	AbortStreamT& operator<< (AbortStreamT& Stream, T const& Object)
	{
		std::abort();
		return Stream;
	};
}

#define LTT_LOG_DEBUG_LEVEL 1
#define LTT_LOG_INFO_LEVEL 2
#define LTT_LOG_WARNING_LEVEL 3
#define LTT_LOG_ERROR_LEVEL 4
#define LTT_LOG_CRITICAL_LEVEL 5

#ifndef LTT_LOG_LEVEL
#define LTT_LOG_LEVEL LTT_LOG_INFO_LEVEL
#endif // LTT_LOG_LEVEL

#ifndef LTT_LOG_BREAK
#define LTT_LOG_BREAK LTT_LOG_CRITICAL_LEVEL
#endif // LTT_LOG_BREAK

#if LTT_LOG_DEBUG_LEVEL >= LTT_LOG_BREAK
#define LTT_LOG_DEBUG (LTT::AbortStream)
#elif LTT_LOG_DEBUG_LEVEL >= LTT_LOG_LEVEL
#define LTT_LOG_DEBUG (std::clog)
#else
#define LTT_LOG_DEBUG (LTT::IgnoreStream)
#endif

#if LTT_LOG_INFO_LEVEL >= LTT_LOG_BREAK
#define LTT_LOG_INFO (LTT::AbortStream)
#elif LTT_LOG_INFO_LEVEL >= LTT_LOG_LEVEL
#define LTT_LOG_INFO (std::clog)
#else
#define LTT_LOG_INFO (LTT::IgnoreStream)
#endif

#if LTT_LOG_WARNING_LEVEL >= LTT_LOG_BREAK
#define LTT_LOG_WARNING (LTT::AbortStream)
#elif LTT_LOG_WARNING_LEVEL >= LTT_LOG_LEVEL
#define LTT_LOG_WARNING (std::clog)
#else
#define LTT_LOG_WARNING (LTT::IgnoreStream)
#endif

#if LTT_LOG_ERROR_LEVEL >= LTT_LOG_BREAK
#define LTT_LOG_ERROR (LTT::AbortStream)
#elif LTT_LOG_ERROR_LEVEL >= LTT_LOG_LEVEL
#define LTT_LOG_ERROR (std::clog)
#else
#define LTT_LOG_ERROR (LTT::IgnoreStream)
#endif

#if LTT_LOG_CRITICAL_LEVEL >= LTT_LOG_BREAK
#define LTT_LOG_CRITICAL (LTT::AbortStream)
#elif LTT_LOG_CRITICAL_LEVEL >= LTT_LOG_LEVEL
#define LTT_LOG_CRITICAL (std::clog)
#else
#define LTT_LOG_CRITICAL (LTT::IgnoreStream)
#endif

int main()
{
	std::clog.rdbuf(std::cout.rdbuf());
	
	LTT_LOG_DEBUG << "Hello Debug!\n";
	LTT_LOG_INFO << "Hello Info!\n";
	LTT_LOG_WARNING << "Hello Warning!\n";
	LTT_LOG_ERROR << "Hello Error!\n";
	// LTT_LOG_CRITICAL << "Hello Critical!\n";
}