#ifndef __LIB_TEST_DEBUG_STREAM_W_H__
#define __LIB_TEST_DEBUG_STREAM_W_H__


#include <windows.h>

#include <iostream>
#include <vector>

#include <tchar.h>


namespace LibTest
{


class DebugStreambufW : public std::wstreambuf
{
public:
	virtual int_type overflow( int_type i_char = EOF )
	{
		if( m_buf.empty() )
			m_buf.push_back( wchar_t(i_char) );
		else
			m_buf.back() = wchar_t(i_char);

		m_buf.push_back( wchar_t('\0') );

		return i_char;
	}

	virtual int sync(void)
	{
		if( !m_buf.empty() )
		{
			OutputDebugStringW( &m_buf[0] );
			m_buf.clear();
		}
		return 0;
	}

private:
	std::vector<wchar_t> m_buf;
};


class DebugStreamW : public std::wostream
{
public:
	DebugStreamW(void) : std::wostream( &m_buf )
	{}

private:
	DebugStreambufW m_buf;
};


class DebugStreamAdapterW
{
public:
	template<typename T>
	std::wostream& operator<<(T& t)
	{
		return ( GetDebugStream() << t ); 
	}

	template<typename T>
	std::wostream& operator<<(const T& t)
	{
		return ( GetDebugStream() << t );
	}

	operator std::wostream&()
	{
		return GetDebugStream(); 
	}

	std::wostream& operator<<( std::wostream& (__cdecl *_func_ptr)( std::wostream& ) )
	{
		return _func_ptr( GetDebugStream() );
	}

	DebugStreamW* operator&(void)
	{
		return &GetDebugStream(); 
	}

	void flush(void)
	{
		GetDebugStream().flush();
	}


private:
	static DebugStreamW& GetDebugStream(void)
	{
		static DebugStreamW debug_stream;
		return debug_stream;
	}
};


}


#endif
