From 9f170721a85a56bc91aa64972e78c9c43eb3a5b1 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Thu, 2 Nov 2017 16:05:57 +0100
Subject: [PATCH] heterogeneous lookups

---
 alib2algo/src/automaton/run/Run.h             | 12 ++++-----
 .../grammar/parsing/CornerSubstitution.cpp    |  3 ++-
 .../grammar/parsing/ExtractRightContext.cpp   |  3 ++-
 .../src/grammar/parsing/First.h               |  9 ++++---
 .../src/grammar/parsing/Follow.h              |  6 ++---
 .../parsing/HandleFirstFirstConflict.cpp      |  3 ++-
 .../parsing/HandleFirstFollowConflict.cpp     |  5 ++--
 .../src/grammar/parsing/LL1ParseTable.h       |  2 +-
 alib2data/src/automaton/FSM/DFA.h             | 27 ++++++++-----------
 alib2std/src/extensions/map.hpp               |  2 +-
 alib2std/src/extensions/set.hpp               |  2 +-
 11 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/alib2algo/src/automaton/run/Run.h b/alib2algo/src/automaton/run/Run.h
index b01d7b903e..3b188422e1 100644
--- a/alib2algo/src/automaton/run/Run.h
+++ b/alib2algo/src/automaton/run/Run.h
@@ -396,13 +396,13 @@ ext::tuple < bool, StateType, ext::set < unsigned >, ext::deque < PushdownStoreS
 
 	for ( auto symbolIter = string.getContent ( ).begin ( ); symbolIter != string.getContent ( ).end ( ); ) {
 
-		auto callTransition = automaton.getCallTransitions ( ).find ( ext::make_pair ( state, * symbolIter ) );
+		auto callTransition = automaton.getCallTransitions ( ).find ( std::pair < StateType, ext::variant < EpsilonType, InputSymbolType > > ( state, * symbolIter ) );
 
 		if ( callTransition != automaton.getCallTransitions ( ).end ( ) ) {
 			symbolIter++;
 			i++;
 		} else {
-			callTransition = automaton.getCallTransitions ( ).find ( ext::make_pair ( state, EpsilonType ( ) ) );
+			callTransition = automaton.getCallTransitions ( ).find ( std::pair < StateType, ext::variant < EpsilonType, InputSymbolType > > ( state, EpsilonType ( ) ) );
 		}
 
 		if ( callTransition != automaton.getCallTransitions ( ).end ( ) ) {
@@ -413,13 +413,13 @@ ext::tuple < bool, StateType, ext::set < unsigned >, ext::deque < PushdownStoreS
 		}
 
 		if ( !res ) {
-			auto returnTransition = automaton.getReturnTransitions ( ).find ( ext::make_tuple ( state, * symbolIter, pushdownStore.back ( ) ) );
+			auto returnTransition = automaton.getReturnTransitions ( ).find ( std::tuple < StateType, ext::variant < EpsilonType, InputSymbolType >, PushdownStoreSymbolType > ( state, * symbolIter, pushdownStore.back ( ) ) );
 
 			if ( returnTransition != automaton.getReturnTransitions ( ).end ( ) ) {
 				symbolIter++;
 				i++;
 			} else {
-				returnTransition = automaton.getReturnTransitions ( ).find ( ext::make_tuple ( state, EpsilonType ( ), pushdownStore.back ( ) ) );
+				returnTransition = automaton.getReturnTransitions ( ).find ( std::tuple < StateType, ext::variant < EpsilonType, InputSymbolType >, PushdownStoreSymbolType > ( state, EpsilonType ( ), pushdownStore.back ( ) ) );
 			}
 
 			if ( returnTransition != automaton.getReturnTransitions ( ).end ( ) ) {
@@ -431,13 +431,13 @@ ext::tuple < bool, StateType, ext::set < unsigned >, ext::deque < PushdownStoreS
 		}
 
 		if ( !res ) {
-			auto localTransition = automaton.getLocalTransitions ( ).find ( ext::make_pair ( state, * symbolIter ) );
+			auto localTransition = automaton.getLocalTransitions ( ).find ( std::pair < StateType, ext::variant < EpsilonType, InputSymbolType > > ( state, * symbolIter ) );
 
 			if ( localTransition != automaton.getLocalTransitions ( ).end ( ) ) {
 				symbolIter++;
 				i++;
 			} else {
-				localTransition = automaton.getLocalTransitions ( ).find ( ext::make_pair ( state, EpsilonType ( ) ) );
+				localTransition = automaton.getLocalTransitions ( ).find ( std::pair < StateType, ext::variant < EpsilonType, InputSymbolType > > ( state, EpsilonType ( ) ) );
 			}
 
 			if ( localTransition != automaton.getLocalTransitions ( ).end ( ) )
diff --git a/alib2algo_experimental/src/grammar/parsing/CornerSubstitution.cpp b/alib2algo_experimental/src/grammar/parsing/CornerSubstitution.cpp
index 729a32e885..beb7bb338e 100644
--- a/alib2algo_experimental/src/grammar/parsing/CornerSubstitution.cpp
+++ b/alib2algo_experimental/src/grammar/parsing/CornerSubstitution.cpp
@@ -10,6 +10,7 @@
 #include "CornerSubstitution.h"
 
 #include <grammar/ContextFree/CFG.h>
+#include <common/DefaultEpsilonType.h>
 
 namespace grammar {
 
@@ -25,7 +26,7 @@ void CornerSubstitution::cornerSubstitution ( grammar::CFG < > & grammar, const
 		const DefaultSymbolType & lhs = rule.first;
 
 		for ( const ext::vector < DefaultSymbolType > & rhs : rule.second ) {
-			if ( ( lhs == nonterminal ) && ( rhs.size ( ) > 0 ) && ( grammar.getNonterminalAlphabet ( ).count ( rhs[0] ) ) && First::first ( grammar, rhs ).count ( terminal ) )
+			if ( ( lhs == nonterminal ) && ( rhs.size ( ) > 0 ) && ( grammar.getNonterminalAlphabet ( ).count ( rhs[0] ) ) && First::first ( grammar, rhs ).count ( ext::variant < DefaultSymbolType, DefaultEpsilonType > ( terminal ) ) )
 				Substitute::substitute ( grammar, res, lhs, rhs, rhs.begin ( ) );
 			else
 				res.addRule ( lhs, rhs );
diff --git a/alib2algo_experimental/src/grammar/parsing/ExtractRightContext.cpp b/alib2algo_experimental/src/grammar/parsing/ExtractRightContext.cpp
index b7d1c23883..5cfb2364b5 100644
--- a/alib2algo_experimental/src/grammar/parsing/ExtractRightContext.cpp
+++ b/alib2algo_experimental/src/grammar/parsing/ExtractRightContext.cpp
@@ -9,6 +9,7 @@
 #include "First.h"
 #include "common/Substitute.h"
 #include <grammar/ContextFree/CFG.h>
+#include <common/DefaultEpsilonType.h>
 
 namespace grammar {
 
@@ -27,7 +28,7 @@ void ExtractRightContext::extractRightContext ( grammar::CFG < > & grammar, cons
 			bool substitued = false;
 			if(rhs.size() > 0)
 				for ( ext::vector < DefaultSymbolType >::const_iterator iter = rhs.begin ( ); iter + 1 != rhs.end ( ); ++iter )
-					if ( nonterminals.count ( * iter ) && grammar.getNonterminalAlphabet ( ).count ( * ( iter + 1 ) ) && First::first ( grammar, ext::vector < DefaultSymbolType > ( iter + 1, rhs.end ( ) ) ).count ( terminal ) ) {
+					if ( nonterminals.count ( * iter ) && grammar.getNonterminalAlphabet ( ).count ( * ( iter + 1 ) ) && First::first ( grammar, ext::vector < DefaultSymbolType > ( iter + 1, rhs.end ( ) ) ).count ( ext::variant < DefaultSymbolType, DefaultEpsilonType > ( terminal ) ) ) {
 						Substitute::substitute ( grammar, res, lhs, rhs, iter + 1 );
 						substitued = true;
 						break;
diff --git a/alib2algo_experimental/src/grammar/parsing/First.h b/alib2algo_experimental/src/grammar/parsing/First.h
index ab544a6416..1cbb577d80 100644
--- a/alib2algo_experimental/src/grammar/parsing/First.h
+++ b/alib2algo_experimental/src/grammar/parsing/First.h
@@ -8,12 +8,13 @@
 #ifndef FIRST_H_
 #define FIRST_H_
 
-#include <string/Epsilon.h>
-#include <grammar/Grammar.h>
 #include <vector>
 #include <set>
 #include <variant>
 
+#include <string/Epsilon.h>
+#include <grammar/Grammar.h>
+
 namespace grammar {
 
 namespace parsing {
@@ -46,12 +47,12 @@ ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > First::
 	}
 
 	 // 4. FIRST(A \alpha) = first(A) if A \in N and \varepsilon \notin first(A)
-	else if ( nonterminals.count ( rhs[0] ) && !firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < SymbolType >::EPSILON ) ) {
+	else if ( nonterminals.count ( rhs[0] ) && !firstOfNonterminal.find ( rhs[0] )->second.count ( ext::variant < SymbolType, string::Epsilon < SymbolType > >::template from < string::Epsilon < SymbolType > > ( ) ) ) {
 		return firstOfNonterminal.find ( rhs[0] )->second;
 	}
 
 	 // 5. FIRST(A \alpha) = (first(A) - \varepsilon) \cup FIRST(\alpha) if A \in N and \varepsilon \in first(A)
-	else if ( nonterminals.count ( rhs[0] ) && firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < SymbolType >::EPSILON ) ) {
+	else if ( nonterminals.count ( rhs[0] ) && firstOfNonterminal.find ( rhs[0] )->second.count ( ext::variant < SymbolType, string::Epsilon < SymbolType > >::template from < string::Epsilon < SymbolType > > ( ) ) ) {
 		ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > res = firstOfNonterminal.find ( rhs[0] )->second;
 		res.erase ( string::Epsilon < SymbolType >::EPSILON );
 
diff --git a/alib2algo_experimental/src/grammar/parsing/Follow.h b/alib2algo_experimental/src/grammar/parsing/Follow.h
index 955481bcb0..10f9d9a79f 100644
--- a/alib2algo_experimental/src/grammar/parsing/Follow.h
+++ b/alib2algo_experimental/src/grammar/parsing/Follow.h
@@ -52,8 +52,8 @@ void Follow::follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::
 
 				ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > firstBeta = First::first ( grammar, ext::vector < SymbolType > ( std::next ( it ), rhs.end ( ) ) );
 
-				if ( firstBeta.count ( string::Epsilon < SymbolType >::EPSILON ) ) {
-					firstBeta.erase ( string::Epsilon < SymbolType >::EPSILON );
+				if ( firstBeta.count ( ext::variant < SymbolType, string::Epsilon < SymbolType > >::template from < string::Epsilon < SymbolType > > ( ) ) ) {
+					firstBeta.erase ( ext::variant < SymbolType, string::Epsilon < SymbolType > >::template from < string::Epsilon < SymbolType > > ( ) );
 					followSet[Y].insert ( followSet[X].begin ( ), followSet[X].end ( ) );
 				}
 
@@ -81,7 +81,7 @@ ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < S
 	for ( const SymbolType & symb : grammar.getNonterminalAlphabet ( ) )
 		followSet1[symb];
 
-	followSet1[grammar.getInitialSymbol ( )] = { string::Epsilon < SymbolType >::EPSILON };
+	followSet1[grammar.getInitialSymbol ( )] = { ext::variant < SymbolType, string::Epsilon < SymbolType > >::template from < string::Epsilon < SymbolType > > ( ) };
 
 	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < SymbolType > > > > followSet2 = followSet1;
 
diff --git a/alib2algo_experimental/src/grammar/parsing/HandleFirstFirstConflict.cpp b/alib2algo_experimental/src/grammar/parsing/HandleFirstFirstConflict.cpp
index 57ff9f488c..a40b4d2b25 100644
--- a/alib2algo_experimental/src/grammar/parsing/HandleFirstFirstConflict.cpp
+++ b/alib2algo_experimental/src/grammar/parsing/HandleFirstFirstConflict.cpp
@@ -11,6 +11,7 @@
 #include "CornerSubstitution.h"
 
 #include <grammar/ContextFree/CFG.h>
+#include <common/DefaultEpsilonType.h>
 
 namespace grammar {
 
@@ -18,7 +19,7 @@ namespace parsing {
 
 void HandleFirstFirstConflict::handleFirstFirstConflict ( grammar::CFG < > & grammar, const DefaultSymbolType & terminal, const DefaultSymbolType & nonterminal, const ext::set < ext::vector < DefaultSymbolType > > & rhsds ) {
 	for ( const ext::vector < DefaultSymbolType > & rhs : rhsds )
-		if ( ( rhs.size ( ) > 0 ) && grammar.getNonterminalAlphabet ( ).count ( rhs[0] ) && First::first ( grammar, rhs ).count ( terminal ) ) {
+		if ( ( rhs.size ( ) > 0 ) && grammar.getNonterminalAlphabet ( ).count ( rhs[0] ) && First::first ( grammar, rhs ).count ( ext::variant < DefaultSymbolType, DefaultEpsilonType > ( terminal ) ) ) {
 			CornerSubstitution::cornerSubstitution ( grammar, terminal, nonterminal );
 			return;
 		}
diff --git a/alib2algo_experimental/src/grammar/parsing/HandleFirstFollowConflict.cpp b/alib2algo_experimental/src/grammar/parsing/HandleFirstFollowConflict.cpp
index 53d824e0eb..30e0d5d64d 100644
--- a/alib2algo_experimental/src/grammar/parsing/HandleFirstFollowConflict.cpp
+++ b/alib2algo_experimental/src/grammar/parsing/HandleFirstFollowConflict.cpp
@@ -13,6 +13,7 @@
 #include "ExtractRightContext.h"
 
 #include <grammar/ContextFree/CFG.h>
+#include <common/DefaultEpsilonType.h>
 
 namespace grammar {
 
@@ -32,7 +33,7 @@ void HandleFirstFollowConflict::handleFirstFollowConflict ( grammar::CFG < > & g
 		for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rule : grammar.getRules ( ) ) {
 			const DefaultSymbolType & lhs = rule.first;
 
-			if ( Follow::follow ( grammar, lhs ).count ( terminal ) )
+			if ( Follow::follow ( grammar, lhs ).count ( ext::variant < DefaultSymbolType, DefaultEpsilonType > ( terminal ) ) )
 				for ( const ext::vector < DefaultSymbolType > & rhs : rule.second )
 					for ( unsigned i = rhs.size ( ); i > 0; i-- ) {
 						if ( symbolsEndingWithNonterminal.count ( rhs[i - 1] ) )
@@ -51,7 +52,7 @@ void HandleFirstFollowConflict::handleFirstFollowConflict ( grammar::CFG < > & g
 		for ( const ext::vector < DefaultSymbolType > & rhs : rule.second ) {
 			if ( rhs.size ( ) > 0 )
 				for ( ext::vector < DefaultSymbolType >::const_iterator iter = rhs.begin ( ); iter + 1 != rhs.end ( ); ++iter )
-					if ( symbolsEndingWithNonterminal.count ( * iter ) && grammar.getNonterminalAlphabet ( ).count ( * ( iter + 1 ) ) && First::first ( grammar, ext::vector < DefaultSymbolType > ( iter + 1, rhs.end ( ) ) ).count ( terminal ) ) {
+					if ( symbolsEndingWithNonterminal.count ( * iter ) && grammar.getNonterminalAlphabet ( ).count ( * ( iter + 1 ) ) && First::first ( grammar, ext::vector < DefaultSymbolType > ( iter + 1, rhs.end ( ) ) ).count ( ext::variant < DefaultSymbolType, DefaultEpsilonType > ( terminal ) ) ) {
 						ExtractRightContext::extractRightContext ( grammar, terminal, symbolsEndingWithNonterminal );
 						return;
 					}
diff --git a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h
index d7c0a9da19..56601ef507 100644
--- a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h
+++ b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h
@@ -48,7 +48,7 @@ ext::map < ext::pair < ext::variant < SymbolType, string::Epsilon < > >, SymbolT
 				res [ ext::make_pair ( firstElem, lhs ) ].insert ( rhs );
 			}
 
-			if ( first[rhs].count ( string::Epsilon < >::EPSILON ) )
+			if ( first[rhs].count ( ext::variant < SymbolType, string::Epsilon < SymbolType > >::template from < string::Epsilon < SymbolType > > ( ) ) )
 				for ( const ext::variant < SymbolType, string::Epsilon < > > & followElem : follow[lhs] )
 					res [ ext::make_pair ( followElem, lhs ) ].insert ( rhs );
 
diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h
index 7296f8b809..dbe5c056bb 100644
--- a/alib2data/src/automaton/FSM/DFA.h
+++ b/alib2data/src/automaton/FSM/DFA.h
@@ -512,21 +512,21 @@ ext::map < ext::pair < StateType, SymbolType >, StateType > && DFA<SymbolType, S
 	return std::move ( transitions );
 }
 
-template < class Type, class From >
-class PartialComparator {
-	const Type & m_data;
-	std::function < const Type & ( const From & ) > retrieveFunction;
+template < class SymbolType, class StateType >
+class Compar {
+	const StateType & m_data;
 
 public:
-	PartialComparator ( const Type & data, const Type & ( * function ) ( const From & ) ) : m_data ( data ), retrieveFunction ( function ) {
+	Compar ( const StateType & data ) : m_data ( data ) {
+
 	}
 
-	friend bool operator < ( const PartialComparator & first, const Type & second ) {
-		return first.m_data < first.retrieveFunction ( second );
+	friend bool operator < ( const Compar & first, const std::pair < StateType, SymbolType > & second ) {
+		return first.m_data < second.first;
 	}
 
-	friend bool operator < ( const Type & first, const PartialComparator & second ) {
-		return second.retrieveFunction ( first ) < second.m_data;
+	friend bool operator < ( const std::pair < StateType, SymbolType > & first, const Compar & second ) {
+		return first.first < second.m_data;
 	}
 };
 
@@ -535,13 +535,8 @@ ext::range < typename ext::map < ext::pair < StateType, SymbolType >, StateType
 	if ( !getStates ( ).count ( from ) )
 		throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" );
 
-	typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator lower = transitions.begin ( );
-	while ( lower != transitions.end ( ) && lower->first.first < from )
-		++ lower;
-
-	typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator upper = lower;
-	while ( upper != transitions.end ( ) && upper->first.first <= from )
-		++ upper;
+	auto lower = transitions.lower_bound ( Compar < SymbolType, StateType > ( from ) );
+	auto upper = transitions.upper_bound ( Compar < SymbolType, StateType > ( from ) );
 
 	return ext::make_range ( lower, upper );
 }
diff --git a/alib2std/src/extensions/map.hpp b/alib2std/src/extensions/map.hpp
index 927b9132bd..3f174aee9a 100644
--- a/alib2std/src/extensions/map.hpp
+++ b/alib2std/src/extensions/map.hpp
@@ -19,7 +19,7 @@
 
 namespace ext {
 
-template < typename T, typename R, typename Cmp = std::less < T >, typename Alloc = std::allocator < std::pair < const T, R > > >
+template < typename T, typename R, typename Cmp = std::less < >, typename Alloc = std::allocator < std::pair < const T, R > > >
 class map : public std::map < T, R, Cmp, Alloc > {
 public:
 #ifdef __clang__
diff --git a/alib2std/src/extensions/set.hpp b/alib2std/src/extensions/set.hpp
index 5040f8210d..b08dd3e648 100644
--- a/alib2std/src/extensions/set.hpp
+++ b/alib2std/src/extensions/set.hpp
@@ -17,7 +17,7 @@
 
 namespace ext {
 
-template < typename T, typename Cmp = std::less < T >, typename Alloc = std::allocator < T > >
+template < typename T, typename Cmp = std::less < >, typename Alloc = std::allocator < T > >
 class set : public std::set < T, Cmp, Alloc > {
 public:
 #ifdef __clang__
-- 
GitLab