//
// Copyright (c) 2009-2010 Ronald Kluth
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

/**
 * @file Example_Record.cpp
 * @author Ronald Kluth
 * @date 2009/11/23
 * @brief Example introducing basic default record usage
 * @since 0.1
 */

/**
 * @example Example_Record.cpp
 *
 * This example illustrates the basic usage of the library's default record
 * type. Class @c Record always holds a text message, but it can also be used
 * to transport arbitrary data. All that is necessary is a declaration of a
 * so-called info type with the macro CPPLOG_DECLARE_INFO_TYPE. The library
 * already provides three common info types: @c FileInfo, @c LineInfo, and
 * @c ScopeInfo, all of which are used in this example. Additionally, a list
 * of info types can be declared to provide automatic iteration over the
 * contained information. This is done via the macro CPPLOG_DECLARE_INFO_TYPE_LIST.
 *
 * After declaring the list @c Infos of info types, we add the functor
 * @c InfoWriter for printing info type values on the console. In the main
 * function, we first create a record object with a text message and then
 * add the info types with the class's methods @c file, @c line, and @c scope
 * which all support chaining.
 *
 * The next part shows two different ways to extract information from @c Record
 * objects. The text can be retrieved via @c getText, but the info types need a
 * little more work as they are stored in a map with their type info as key.
 * Hence they must be requested via the method template @c get, which returns
 * a pointer to the data, or zero if the given info type was not found in the
 * record. The other method is automatic iteration over info types via the
 * method template @c iterateInfo, which requires an info type list and a
 * functor to call for each value.
 */
#include <CppLog.h>
#include <iostream>
using namespace Log;

CPPLOG_DECLARE_INFO_TYPE_LIST( Infos, FileInfo, LineInfo, ScopeInfo );

struct InfoWriter {
	template < typename ValT >
	void operator()( const StringLiteral& name, const ValT& value, bool found ) {
		if( found ) { std::cout << ", " << name << ": " << value; }
	}
} writer;

int main() {
	Record rec( "Logging class Record example" );
	rec.file( __FILE__ ).line( __LINE__ ).scope( "main()" );

	std::cout << rec.getText();
	if( FileInfo::Type const* fi = rec.get< FileInfo >() )
		std::cout << ", " << FileInfo::getName() << ": " << *fi;
	if( LineInfo::Type const* li = rec.get< LineInfo >() )
		std::cout << ", " << LineInfo::getName() << ": " << *li;
	if( ScopeInfo::Type const* si = rec.get< ScopeInfo >() )
		std::cout << ", " << ScopeInfo::getName() << ": " << *si;
	std::cout << std::endl;

	std::cout << rec.getText();
	rec.iterateInfo< Infos >( writer );
	std::cout << std::endl;
}
