Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
OverloadResolution.hpp
Go to the documentation of this file.
1
6#pragma once
7
8#include <ext/list>
10
11namespace abstraction {
12
13template < class Entry >
14std::shared_ptr < abstraction::OperationAbstraction > getOverload ( const ext::list < std::unique_ptr < Entry > > & overloads, const ext::vector < std::string > & paramTypes, const ext::vector < abstraction::TypeQualifiers::TypeQualifierSet > &, AlgorithmCategories::AlgorithmCategory category ) {
15 enum class MatchType {
16 EXACT,
17 CAST,
18 INCOMPATIBLE
19 };
20
21 auto incompatibleLambda = [ ] ( MatchType compatibility ) {
22 return compatibility == MatchType::INCOMPATIBLE;
23 };
24
25 // determine how one can actually map what we have ( paramTypes ) as params to what is available as overloads ( overloads )
26 std::vector < std::pair < ext::vector < MatchType >, Entry * > > compatibilityData;
27 for ( const std::unique_ptr < Entry > & entry : overloads ) {
28 if ( entry->getEntryInfo ( ).getCategory ( ) != category && AlgorithmCategories::AlgorithmCategory::NONE != category )
29 continue;
30
31 if ( entry->getEntryInfo ( ).getParams ( ).size ( ) != paramTypes.size ( ) )
32 continue;
33
34 ext::vector < MatchType > compatibilityVector;
35 for ( size_t i = 0; i < paramTypes.size ( ); ++ i ) {
36 MatchType matchType;
37 if ( std::get < 0 > ( entry->getEntryInfo ( ).getParams ( ) [ i ] ) == paramTypes [ i ] || std::get < 0 > ( entry->getEntryInfo ( ).getParams ( ) [ i ] ) == "auto" ) {
38 matchType = MatchType::EXACT;
39 } else if ( abstraction::CastRegistry::castAvailable ( std::get < 0 > ( entry->getEntryInfo ( ).getParams ( ) [ i ] ), paramTypes [ i ], true ) ) {
40 matchType = MatchType::CAST;
41 } else {
42 matchType = MatchType::INCOMPATIBLE;
43 }
44
45 compatibilityVector.push_back ( matchType );
46 }
47
48 // clear incompatibilities are fitered out
49 if ( std::none_of ( compatibilityVector.begin ( ), compatibilityVector.end ( ), incompatibleLambda ) )
50 compatibilityData.emplace_back ( std::move ( compatibilityVector ), entry.get ( ) );
51 }
52
53 // remaining compatible overloads are examined per parameter and the best option is remembered as overload index that achieved it
55 for ( size_t i = 0; i < paramTypes.size ( ); ++ i ) {
57
58 unsigned overload = 0;
59 for ( const std::pair < ext::vector < MatchType >, Entry * > & data : compatibilityData ) {
60 if ( data.first [ i ] == MatchType::EXACT )
61 best.insert ( overload );
62
63 ++ overload;
64 }
65
66 if ( !best.empty ( ) ) {
67 winnerList.push_back ( std::move ( best ) );
68 continue;
69 }
70
71 overload = 0;
72 for ( const std::pair < ext::vector < MatchType >, Entry * > & data : compatibilityData ) {
73 if ( data.first [ i ] == MatchType::CAST )
74 best.insert ( overload );
75
76 ++ overload;
77 }
78
79 winnerList.push_back ( std::move ( best ) );
80 }
81
82 // intersection of everything together finds indexes which are better or of the same quality for all params over all overloads
83 ext::set < unsigned > winner { ext::sequence < unsigned > ( 0 ).begin ( ), ext::sequence < unsigned > ( compatibilityData.size ( ) ).end ( ) };
84 for ( const ext::set < unsigned > & best : winnerList ) {
85 ext::set < unsigned > filtered;
86 std::set_intersection ( winner.begin ( ), winner.end ( ), best.begin ( ), best.end ( ), std::inserter ( filtered, filtered.end ( ) ) );
87 winner = std::move ( filtered );
88 }
89
90 // if there is a sinle winner, return it
91 if ( winner.size ( ) == 1 ) {
92 return compatibilityData [ * winner.begin ( ) ].second->getAbstraction ( );
93 } else if ( winner.size ( ) > 1 ) {
94// throw std::invalid_argument ( "Entry overload " + ext::to_string ( paramTypes ) + " ambiguous." ); FIXME make better overload select algorithm
95 return compatibilityData [ * std::next ( winner.begin ( ) ) ].second->getAbstraction ( ); // FIXME terrible hack to get to const variant of get on datastructures...
96
97/* if(common::GlobalData::verbose)
98 common::Streams::err << "Entry overload " + ss.str ( ) + " ambiguous. First selected." << std::endl;*/
99 } else {
100 throw std::invalid_argument ( "Entry overload not found" );
101 }
102}
103
104} /* namespace abstraction */
105
AlgorithmCategory
Definition: AlgorithmCategories.hpp:14
static bool castAvailable(const std::string &target, const std::string &param, bool implicitOnly)
Definition: CastRegistry.cpp:49
Class extending the list class from the standard library. Original reason is to allow printing of the...
Definition: list.hpp:44
Representation of integer sequence usable in foreach form of for loop.
Definition: foreach.hpp:408
virtual_pointer_to_integer< IntegralType > begin()
Getter of the begin iterator into the sequence.
Definition: foreach.hpp:447
virtual_pointer_to_integer< IntegralType > end()
Getter of the end iterator into the sequence.
Definition: foreach.hpp:457
Definition: set.hpp:44
auto end() &
Inherited behavior of end for non-const instance.
Definition: set.hpp:129
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
auto begin() &
Inherited behavior of begin for non-const instance.
Definition: vector.hpp:125
auto end() &
Inherited behavior of end for non-const instance.
Definition: vector.hpp:155
Definition: AlgorithmAbstraction.hpp:11
std::shared_ptr< abstraction::OperationAbstraction > getOverload(const ext::list< std::unique_ptr< Entry > > &overloads, const ext::vector< std::string > &paramTypes, const ext::vector< abstraction::TypeQualifiers::TypeQualifierSet > &, AlgorithmCategories::AlgorithmCategory category)
Definition: OverloadResolution.hpp:14
int i
Definition: AllEpsilonClosure.h:118
none_of(T &&...) -> none_of< T... >