#include <iostream>
#include <sstream>
#include <functional>
struct singleton_impl
{
static singleton_impl& instance()
{
static singleton_impl impl;
return impl;
}
void log( const std::string& l )
{
std::cout << l << std::endl;
}
};
template<typename Fn>
class message
{
public:
message( Fn&& fn ) : m_f { std::forward<Fn>( fn ) }
{ }
~message() {
// Push to message queue
m_f( m_ss.str() );
}
template<typename T>
message& operator<<( const T& msg )
{
m_ss << msg;
return *this;
}
private:
std::stringstream m_ss;
Fn m_f;
};
struct logger
{
auto operator()() {
return message { std::bind( static_cast< void(logger::*)( const std::string& )>( &logger::log ) , this , std::placeholders::_1 ) };
}
void log( const std::string& l )
{
// std::cout << l << std::endl;
singleton_impl::instance().log( l );
}
};
int main()
{
logger logger;
logger() << "Hello, world ! a number : " << 15 << ". Supports 'operator <<'";
logger.log( "another way" );
{
logger() << "Use of RAII";
}
auto output = logger();
output << "Output over object.";
output << "Appended to the previous text.";
return 0;
}