/*
 * ValuePrinterAbstraction.hpp
 *
 *  Created on: 11. 7. 2017
 *	  Author: Jan Travnicek
 */

#pragma once

#include <memory>

#include <abstraction/NaryOperationAbstraction.hpp>
#include <abstraction/ValueOperationAbstraction.hpp>

namespace abstraction {

template < class ParamType >
class ValuePrinterAbstraction : virtual public NaryOperationAbstraction < ParamType, std::ostream & >, virtual public ValueOperationAbstraction < void > {
public:
	ValuePrinterAbstraction ( ) = default;

	std::shared_ptr < abstraction::Value > run ( ) override {
		std::shared_ptr < abstraction::Value > & firstParam = std::get < 0 > ( this->getParams ( ) );
		std::shared_ptr < abstraction::Value > & secondParam = std::get < 1 > ( this->getParams ( ) );

		retrieveValue < std::ostream & > ( secondParam ) << retrieveValue < const ParamType & > ( firstParam ) << std::endl;
		return std::make_shared < abstraction::Void > ( );
	}
};

template < >
class ValuePrinterAbstraction < void > : virtual public NaryOperationAbstraction < >, virtual public ValueOperationAbstraction < void > {
public:
	ValuePrinterAbstraction ( ) = default;

	std::shared_ptr < abstraction::Value > run ( ) override {
		return std::make_shared < abstraction::Void > ( );
	}
};

} /* namespace abstraction */

