From 91cd7b44062205359e2b1859eadb55f87806dfe6 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <jan.travnicek@.fit.cvut.cz> Date: Tue, 19 Mar 2019 15:56:14 +0100 Subject: [PATCH] simplify comparator in DFA --- alib2data/src/automaton/FSM/DFA.h | 22 ++---------- alib2std/src/extensions/functional.hpp | 34 +++++++++++++++++++ .../test-src/extensions/FunctionalTest.cpp | 5 +++ 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h index 42b4869012..df3dda5ad8 100644 --- a/alib2data/src/automaton/FSM/DFA.h +++ b/alib2data/src/automaton/FSM/DFA.h @@ -443,31 +443,13 @@ ext::map < ext::pair < StateType, SymbolType >, StateType > && DFA<SymbolType, S return std::move ( transitions ); } -template < class SymbolType, class StateType > -class Compar { - const StateType & m_data; - -public: - Compar ( const StateType & data ) : m_data ( data ) { - - } - - friend bool operator < ( const Compar & first, const std::pair < StateType, SymbolType > & second ) { - return first.m_data < second.first; - } - - friend bool operator < ( const std::pair < StateType, SymbolType > & first, const Compar & second ) { - return first.first < second.m_data; - } -}; - template<class SymbolType, class StateType > ext::iterator_range < typename ext::map < ext::pair < StateType, SymbolType >, StateType >::const_iterator > DFA<SymbolType, StateType>::getTransitionsFromState ( const StateType & from ) const { if ( !getStates ( ).count ( from ) ) throw AutomatonException ( "State \"" + ext::to_string ( from ) + "\" doesn't exist" ); - auto lower = transitions.lower_bound ( Compar < SymbolType, StateType > ( from ) ); - auto upper = transitions.upper_bound ( Compar < SymbolType, StateType > ( from ) ); + auto lower = transitions.lower_bound ( ext::slice_comp ( from ) ); + auto upper = transitions.upper_bound ( ext::slice_comp ( from ) ); return ext::make_iterator_range ( lower, upper ); } diff --git a/alib2std/src/extensions/functional.hpp b/alib2std/src/extensions/functional.hpp index 84d5283fb2..4992b050e2 100644 --- a/alib2std/src/extensions/functional.hpp +++ b/alib2std/src/extensions/functional.hpp @@ -74,6 +74,40 @@ bool operator < ( const R &, const PolyComp < T > & ) { return std::type_index ( typeid ( R ) ) < std::type_index ( typeid ( T ) ); } +template < class ... Ts > +struct SliceComp { + std::tuple < const Ts & ... > m_data; + + SliceComp ( const Ts & ... data ) : m_data ( data ... ) { + } + + template < class T, size_t ... I > + static bool compare ( const SliceComp < Ts ... > & first, const T & second, std::index_sequence < I ... > ) { + return first.m_data < std::tie ( std::get < I > ( second ) ... ); + } + + template < class T > + friend bool operator < ( const SliceComp < Ts ... > & first, const T & second ) { + return compare < T > ( first, second, std::make_index_sequence < sizeof ... ( Ts ) > { } ); + } + + template < class T, size_t ... I > + static bool compare ( const T & first, const SliceComp < Ts ... > & second, std::index_sequence < I ... > ) { + return std::tie ( std::get < I > ( first ) ... ) < second.m_data; + } + + template < class T > + friend bool operator < ( const T & first, const SliceComp < Ts ... > & second ) { + return compare < T > ( first, second, std::make_index_sequence < sizeof ... ( Ts ) > { } ); + } + +}; + +template < class ... Ts > +SliceComp < Ts ... > slice_comp ( const Ts & ... inst ) { + return SliceComp < Ts ... > ( inst ... ); +} + /** * \brief * Class extending the reference wrapper class from the standard library. Original reason is to allow its use with standard stream aggregation class. diff --git a/alib2std/test-src/extensions/FunctionalTest.cpp b/alib2std/test-src/extensions/FunctionalTest.cpp index f61eed5044..595c4a5ce8 100644 --- a/alib2std/test-src/extensions/FunctionalTest.cpp +++ b/alib2std/test-src/extensions/FunctionalTest.cpp @@ -11,5 +11,10 @@ TEST_CASE ( "Functional Test", "[unit][std][bits]" ) { CHECK_EXCLUSIVE_OR( ( test ( ext::poly_comp ( std::string ( "aa" ) ), 1 ) ), ( test ( ext::poly_comp ( 1 ), std::string ( "aa" ) ) ) ); CHECK ( test ( ext::poly_comp ( 1 ), 2 ) == true ); + + std::pair < int, std::string > value ( 1, "aa" ); + + CHECK ( test ( ext::slice_comp ( 0 ), value ) == true ); + CHECK ( test ( ext::slice_comp ( 1 ), value ) == false ); } } -- GitLab