Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
AlgorithmRegistry.cpp 8.96 KiB
/*
 * AlgorithmRegistry.cpp
 *
 *  Created on: 19. 8. 2017
 *	  Author: Jan Travnicek
 */

#include <abstraction/AlgorithmRegistry.hpp>
#include <abstraction/CastRegistry.hpp>
#include <foreach>

namespace abstraction {

std::shared_ptr < abstraction::OperationAbstraction > AlgorithmRegistry::getAbstraction ( const std::string & name, const ext::vector < std::string > & paramTypes, AlgorithmCategories::AlgorithmCategory, bool & downcast, bool & normalize ) {
	auto group = getEntries ( ).find ( name );
	if ( group == getEntries ( ).end ( ) ) {
		ext::vector < std::string > explodedName = ext::explode ( name, "::" );

		for ( auto iter = getEntries ( ).begin ( ); iter != getEntries ( ).end ( ); ++ iter ) {
			ext::vector < std::string > explodedCandidate = ext::explode ( iter->first, "::" );

			if ( explodedName.size ( ) > explodedCandidate.size ( ) )
				continue;

			unsigned offset = explodedCandidate.size ( ) - explodedName.size ( );

			bool matches = true;
			for ( unsigned index = 0; index < explodedName.size ( ); ++ index ) {
				if ( explodedName [ index ] == "" )
					continue;

				if ( explodedName [ index ] != explodedCandidate [ index + offset ] ) {
					matches = false;
					break;
				}
			}

			if ( matches ) {
				if ( group == getEntries ( ).end ( ) )
					group = iter;
				else
					throw exception::CommonException ( "Name " + name + " is ambigous " );
			}
		}
	}
	if ( group == getEntries ( ).end ( ) )
		throw exception::CommonException ( "Entry " + name + " not available" );

	auto incompatibleLambda = [ ] ( const ext::tuple < MatchType, std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > & compatibility ) {
		return std::get < 0 > ( compatibility ) == MatchType::INCOMPATIBLE;
	};

	auto castLambda = [ ] ( const ext::tuple < MatchType, std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > & compatibility ) {
		return std::get < 0 > ( compatibility ) == MatchType::CAST;
	};

	auto exactLambda = [ ] ( const ext::tuple < MatchType, std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > & compatibility ) {
		return std::get < 0 > ( compatibility ) == MatchType::EXACT;
	};

	// determine how one can actually map what we have ( paramTypes ) as params to what is available as overloads ( group->second )
	std::vector < std::pair < ext::vector < ext::tuple < MatchType, std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > >, std::pair < std::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > >, std::shared_ptr < Entry > > > > compatibilityData;
	for ( const ext::tuple < AlgorithmCategories::AlgorithmCategory, ext::vector < ext::tuple < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier >, std::string > >, ext::pair < ext::pair < std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > >, std::shared_ptr < Entry > > > & entry : group->second ) {
		if ( std::get < 1 > ( entry ).size ( ) != paramTypes.size ( ) )
			continue;

		ext::vector < ext::tuple < MatchType, std::string, ext::set < abstraction::ParamQualifiers::ParamQualifier > > > compatibilityVector;
		for ( unsigned i = 0; i < paramTypes.size ( ); ++ i ) {
			MatchType matchType;
			if ( std::get < 0 > ( std::get < 1 > ( entry ) [ i ] ) == paramTypes [ i ] ) {