-
Jan Trávníček authoredJan Trávníček authored
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 ] ) {