/*
 * OperationAbstraction.hpp
 *
 *  Created on: 10. 7. 2017
 *	  Author: Jan Travnicek
 */

#ifndef _OPERATION_ABSTRACTION_HPP_
#define _OPERATION_ABSTRACTION_HPP_

#include <alib/memory>
#include <alib/string>
#include <alib/typeindex>
#include <alib/set>

#include <common/TypeQualifiers.hpp>

namespace abstraction {

class Value;

class OperationAbstraction : public std::enable_shared_from_this < OperationAbstraction > {
public:
	virtual void attachInput ( const std::shared_ptr < abstraction::Value > & input, size_t index ) = 0;
	virtual void detachInput ( size_t index ) = 0;

	virtual ~OperationAbstraction ( ) noexcept = default;

	virtual bool inputsAttached ( ) const = 0;
	virtual std::shared_ptr < abstraction::Value > eval ( ) = 0;
	virtual size_t numberOfParams ( ) const = 0;

	virtual bool isParamTypeUniversal ( size_t ) const {
		return false;
	}

	virtual bool isReturnTypeUniversal ( ) const {
		return false;
	}

	virtual ext::type_index getParamTypeIndex ( size_t index ) const = 0;
	virtual ext::type_index getReturnTypeIndex ( ) const = 0;

	std::string getParamType ( size_t index ) const;

	virtual abstraction::TypeQualifiers::TypeQualifierSet getParamTypeQualifiers ( size_t index ) const = 0;

	std::string getReturnType ( ) const;

	virtual abstraction::TypeQualifiers::TypeQualifierSet getReturnTypeQualifiers ( ) const = 0;

	virtual std::shared_ptr < abstraction::OperationAbstraction > getProxyAbstraction ( );
};

} /* namespace abstraction */

#endif /* _OPERATION_ABSTRACTION_HPP_ */
