diff --git a/alib2data/src/automaton/FSM/DFA.cpp b/alib2data/src/automaton/FSM/DFA.cpp index ec5169eedaccea3d45258bdc3f1652448d8124e9..41a93b6dcbfbd6548c9dda5651fa037f76a22bd7 100644 --- a/alib2data/src/automaton/FSM/DFA.cpp +++ b/alib2data/src/automaton/FSM/DFA.cpp @@ -133,16 +133,25 @@ bool DFA::isTotal() const { } int DFA::compare(const DFA& other) const { - auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); } + if(res == 0) { + std::compare<decltype(initialState)> comp; + res = comp(initialState, other.initialState); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(transitions)> comp; + res = comp(transitions, other.transitions); + } + return res; } void DFA::operator>>(std::ostream& out) const { diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.cpp b/alib2data/src/automaton/FSM/EpsilonNFA.cpp index c053207f2272d7a16ed01759d7f3347de36c6fea..1dc580bef8d5e940ced2269775aa8a49d69a4e5b 100644 --- a/alib2data/src/automaton/FSM/EpsilonNFA.cpp +++ b/alib2data/src/automaton/FSM/EpsilonNFA.cpp @@ -266,16 +266,25 @@ bool EpsilonNFA::isTotal() const { } int EpsilonNFA::compare(const EpsilonNFA& other) const { - auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); } + if(res == 0) { + std::compare<decltype(initialState)> comp; + res = comp(initialState, other.initialState); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(transitions)> comp; + res = comp(transitions, other.transitions); + } + return res; } void EpsilonNFA::operator>>(std::ostream& out) const { diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.cpp b/alib2data/src/automaton/FSM/ExtendedNFA.cpp index 663920663a37efd73da99f2c3df1f5cd5fecf2a2..3d7d13dfaf582d60663c3f322cb8fdb9192c289a 100644 --- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp +++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp @@ -177,16 +177,25 @@ std::map<std::pair<State, regexp::RegExp>, std::set<State> > ExtendedNFA::getTra } int ExtendedNFA::compare(const ExtendedNFA& other) const { - auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); } + if(res == 0) { + std::compare<decltype(initialState)> comp; + res = comp(initialState, other.initialState); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(transitions)> comp; + res = comp(transitions, other.transitions); + } + return res; } void ExtendedNFA::operator>>(std::ostream& out) const { diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp index fbe13322e8cb40d3f0cf3b59f356a1452ff5f275..4b505cb25ab503eba25cd061566955f905eb5a82 100644 --- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp +++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp @@ -156,16 +156,25 @@ unsigned MultiInitialStateNFA::transitionsSize() const { } int MultiInitialStateNFA::compare(const MultiInitialStateNFA& other) const { - auto first = std::tie(states, inputAlphabet, initialStates, finalStates, transitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); } + if(res == 0) { + std::compare<decltype(initialStates)> comp; + res = comp(initialStates, other.initialStates); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(transitions)> comp; + res = comp(transitions, other.transitions); + } + return res; } void MultiInitialStateNFA::operator>>(std::ostream& out) const { diff --git a/alib2data/src/automaton/FSM/NFA.cpp b/alib2data/src/automaton/FSM/NFA.cpp index 72ee67a7facba93aafdec6ef2e3dd4a869984a21..f9df9181e96c03565d551be8e069206773dc8fbd 100644 --- a/alib2data/src/automaton/FSM/NFA.cpp +++ b/alib2data/src/automaton/FSM/NFA.cpp @@ -139,16 +139,25 @@ unsigned NFA::transitionsSize() const { } int NFA::compare(const NFA& other) const { - auto first = std::tie(states, inputAlphabet, initialState, finalStates, transitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.transitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); } + if(res == 0) { + std::compare<decltype(initialState)> comp; + res = comp(initialState, other.initialState); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(transitions)> comp; + res = comp(transitions, other.transitions); + } + return res; } void NFA::operator>>(std::ostream& out) const { diff --git a/alib2data/src/automaton/PDA/DPDA.cpp b/alib2data/src/automaton/PDA/DPDA.cpp index 85bd138fe4e22d020d7911c0fa93854215ff31b7..2b16f016c8519f52cfd750017b04fd21562adb00 100644 --- a/alib2data/src/automaton/PDA/DPDA.cpp +++ b/alib2data/src/automaton/PDA/DPDA.cpp @@ -223,16 +223,33 @@ std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std: } int DPDA::compare(const DPDA& other) const { - auto first = std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, initialSymbol, transitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.initialSymbol, other.transitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); + } + if(res == 0) { + std::compare<decltype(initialState)> comp; + res = comp(initialState, other.initialState); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(stackAlphabet)> comp; + res = comp(stackAlphabet, other.stackAlphabet); + } + if(res == 0) { + std::compare<decltype(initialSymbol)> comp; + res = comp(initialSymbol, other.initialSymbol); + } + if(res == 0) { + std::compare<decltype(transitions)> comp; + res = comp(transitions, other.transitions); } + return res; } void DPDA::operator>>(std::ostream& out) const { diff --git a/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp b/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp index c6fa402b502d1155e6fa5b4e76a0856622369644..8f263d6f7d008b50aeaeaafed9d345cbef9b786c 100644 --- a/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp +++ b/alib2data/src/automaton/PDA/InputDrivenNPDA.cpp @@ -175,16 +175,37 @@ bool InputDrivenNPDA::isDeterministic() const { } int InputDrivenNPDA::compare(const InputDrivenNPDA& other) const { - auto first = std::tie(states, inputAlphabet, initialStates, finalStates, transitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.transitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); + } + if(res == 0) { + std::compare<decltype(initialStates)> comp; + res = comp(initialStates, other.initialStates); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(stackAlphabet)> comp; + res = comp(stackAlphabet, other.stackAlphabet); + } + if(res == 0) { + std::compare<decltype(initialSymbol)> comp; + res = comp(initialSymbol, other.initialSymbol); + } + if(res == 0) { + std::compare<decltype(inputSymbolToPushdownStoreOperation)> comp; + res = comp(inputSymbolToPushdownStoreOperation, other.inputSymbolToPushdownStoreOperation); + } + if(res == 0) { + std::compare<decltype(transitions)> comp; + res = comp(transitions, other.transitions); } + return res; } void InputDrivenNPDA::operator>>(std::ostream& out) const { @@ -193,7 +214,10 @@ void InputDrivenNPDA::operator>>(std::ostream& out) const { << " inputAlphabet = " << inputAlphabet << " initialStates = " << initialStates << " finalStates = " << finalStates + << " stackAlphabet = " << stackAlphabet + << " initialSymbol = " << initialSymbol << " transitions = " << transitions + << " inputSymbolToPushdownStoreOperation = " << inputSymbolToPushdownStoreOperation << ")"; } diff --git a/alib2data/src/automaton/PDA/NPDA.cpp b/alib2data/src/automaton/PDA/NPDA.cpp index 5407aaaed8f383459325dfe14df9fa5c54b356ae..a95026b83b318de8dc2d2317c02731c5bc65b900 100644 --- a/alib2data/src/automaton/PDA/NPDA.cpp +++ b/alib2data/src/automaton/PDA/NPDA.cpp @@ -134,16 +134,33 @@ const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol> } int NPDA::compare(const NPDA& other) const { - auto first = std::tie(states, inputAlphabet, initialStates, finalStates, stackAlphabet, initialSymbols, transitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialStates, other.finalStates, other.stackAlphabet, other.initialSymbols, other.transitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); + } + if(res == 0) { + std::compare<decltype(initialStates)> comp; + res = comp(initialStates, other.initialStates); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(stackAlphabet)> comp; + res = comp(stackAlphabet, other.stackAlphabet); + } + if(res == 0) { + std::compare<decltype(initialSymbols)> comp; + res = comp(initialSymbols, other.initialSymbols); + } + if(res == 0) { + std::compare<decltype(transitions)> comp; + res = comp(transitions, other.transitions); } + return res; } void NPDA::operator>>(std::ostream& out) const { diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.cpp b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.cpp index 0b44a8fafba36597dd97bd62d9eebb74b9764ab7..453c9b3a34251d473c20c0bbdd29aa155f6bebf8 100644 --- a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.cpp +++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicDPDA.cpp @@ -367,16 +367,41 @@ const std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol>> } int RealTimeHeightDeterministicDPDA::compare(const RealTimeHeightDeterministicDPDA& other) const { - auto first = std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, bottomOfTheStackSymbol, callTransitions, returnTransitions, localTransitions); - auto second = std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.bottomOfTheStackSymbol, other.callTransitions, other.returnTransitions, other.localTransitions); - - if(first == second) { - return 0; - } else if(first < second) { - return -1; - } else { - return 1; + std::compare<decltype(states)> comp; + int res = comp(states, other.states); + if(res == 0) { + std::compare<decltype(inputAlphabet)> comp; + res = comp(inputAlphabet, other.inputAlphabet); + } + if(res == 0) { + std::compare<decltype(initialState)> comp; + res = comp(initialState, other.initialState); + } + if(res == 0) { + std::compare<decltype(finalStates)> comp; + res = comp(finalStates, other.finalStates); + } + if(res == 0) { + std::compare<decltype(stackAlphabet)> comp; + res = comp(stackAlphabet, other.stackAlphabet); + } + if(res == 0) { + std::compare<decltype(bottomOfTheStackSymbol)> comp; + res = comp(bottomOfTheStackSymbol, other.bottomOfTheStackSymbol); + } + if(res == 0) { + std::compare<decltype(callTransitions)> comp; + res = comp(callTransitions, other.callTransitions); + } + if(res == 0) { + std::compare<decltype(returnTransitions)> comp; + res = comp(returnTransitions, other.returnTransitions); + } + if(res == 0) { + std::compare<decltype(localTransitions)> comp; + res = comp(localTransitions, other.localTransitions); } + return res; } void RealTimeHeightDeterministicDPDA::operator>>(std::ostream& out) const { diff --git a/alib2data/src/std/compare.hpp b/alib2data/src/std/compare.hpp index fbb2a3dbe46f53336edf1b9be25a8910b543e6cb..8d8741a658373b6e3f7d6031f786c73fac355532 100644 --- a/alib2data/src/std/compare.hpp +++ b/alib2data/src/std/compare.hpp @@ -12,6 +12,7 @@ #include <vector> #include <string> #include <map> +#include <tuple> namespace std { @@ -91,6 +92,35 @@ struct compare<map<T, R>> { } }; +template<int I, typename Tuple> +struct compareTupleHelper; + +template<int I, typename Tuple> +struct compareTupleHelper { + static int compHelp(const Tuple& t1, const Tuple& t2) { + compare<typename tuple_element<I, Tuple>::type> comp; + int res = comp(std::get<I>(t1), std::get<I>(t2)); + if(res != 0) return res; + return compareTupleHelper<I - 1, Tuple>::compHelp(t1, t2); + } +}; + +template<class Tuple> +struct compareTupleHelper<0, Tuple> { + static int compHelp(const Tuple& t1, const Tuple& t2) { + compare<typename tuple_element<0, Tuple>::type> comp; + return comp(std::get<0>(t1), std::get<0>(t2)); + } +}; + + +template<typename ... Ts> +struct compare<tuple<Ts...>> { + int operator()(const tuple<Ts...>& first, const tuple<Ts...>& second) const { + return compareTupleHelper<tuple_size<std::tuple<Ts...>>::value - 1, std::tuple<Ts...>>::compHelp(first, second); + } +}; + template<> struct compare<string> { int operator()(const string& first, const string& second) const { diff --git a/alib2data/src/std/variant.hpp b/alib2data/src/std/variant.hpp index fc19fc4e4e1b82d3cff460b40323c5079f5fcee0..182f7260b6dd17a9029391ed8b5272ddbb8ab17b 100644 --- a/alib2data/src/std/variant.hpp +++ b/alib2data/src/std/variant.hpp @@ -13,6 +13,7 @@ #include <typeinfo> #include "type_traits.hpp" #include <string> +#include "compare.hpp" namespace std { @@ -94,6 +95,17 @@ struct variant_helper<F, Ts...> { return variant_helper<Ts...>::compareLess(this_t, this_v, other_t, other_v); } + inline static int compareHelper(size_t this_t, const void * this_v, size_t other_t, const void * other_v) + { + if (this_t == typeid(F).hash_code() && other_t != typeid(F).hash_code()) return -1; + if (this_t != typeid(F).hash_code() && other_t == typeid(F).hash_code()) return 1; + + if (this_t == typeid(F).hash_code() && other_t == typeid(F).hash_code()) { + compare<F> comp; + return comp( *(reinterpret_cast<const F*>(this_v)), *(reinterpret_cast<const F*>(other_v))); + } else + return variant_helper<Ts...>::compareHelper(this_t, this_v, other_t, other_v); + } }; template<> struct variant_helper<> { @@ -104,6 +116,7 @@ inline static bool compareEq(size_t, const void *, size_t, const void *) { retur inline static void print(ostream&, const size_t, const void *) {} inline static std::string string(const size_t, const void *) { return ""; } inline static bool compareLess(size_t, const void *, size_t, const void *) { return false; } +inline static int compareHelper(size_t, const void *, size_t, const void *) { return 0; } }; template<typename ST, typename AT, typename... Ts> @@ -195,6 +208,11 @@ public: return !(*this < other); } + int compare(const variant<F, Ts...>& other) const + { + return helper_t::compareHelper(this->type_id, &this->data, other.type_id, &other.data); + } + template<typename T> bool is() const { return (this->type_id == typeid(T).hash_code()); @@ -256,6 +274,13 @@ public: } }; +template<typename ... Ts> +struct compare<variant<Ts...>> { + int operator()(const variant<Ts...>& first, const variant<Ts...>& second) { + return first.compare(second); + } +}; + } /* namespace std */ #endif