Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Concepts
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... >