//
// 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 SetInserter.h
 * @author Ronald Kluth
 * @date created at 2009/03/29
 * @brief Declaration and implementation of class template SetInserter
 * @since 0.1
 */

#ifndef LOG_DETAIL_SETINSERTER_INCLUDED
#define LOG_DETAIL_SETINSERTER_INCLUDED

#include <set>

namespace Log {
namespace Detail {

// forward declaration
template < typename SetInserterT >
const SetInserterT&
operator<<( const SetInserterT& ins, const typename SetInserterT::ValueType& value );

/**
 * @brief Helper class to enable @c std::set value insertion with @c operator<<
 */
template< typename ValueT >
struct SetInserter
{
	/// Type of the values the inserter can add to a set
	typedef ValueT ValueType;
	/// Set type to be modified by the inserter object
	typedef std::set< ValueType > SetType;

	/// Reference to the set which is to be modified
	SetType& set_;

	/// Construction with non-const reference to a set
	SetInserter( SetType& set ): set_( set ) {}

	/// Add a value to the referenced @c set_
	const SetInserter& add( const ValueType& value ) const
	{
		set_.insert( value );
		return *this;
	}

	template < typename SetInserterT >
	friend
	const SetInserterT&
	operator<<( const SetInserterT& ins, const typename SetInserterT::ValueType& value );
};

/// Insertion operator to add values to a set in a stream-like manner
template < typename SetInserterT >
inline
const SetInserterT&
operator<<( const SetInserterT& ins, const typename SetInserterT::ValueType& value )
{
	ins.add( value );
	return ins;
}

} } // namespace Log::Detail

#endif /* LOG_DETAIL_SETINSERTER_INCLUDED */
