From 8ec471f8eb9281720aa75043cd65cb41f1959570 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 21 Mar 2019 16:36:15 +0100 Subject: [PATCH] redesign comparison of values of any type --- alib2common/src/common/createUnique.hpp | 3 +- alib2data/src/grammar/ContextFree/CFG.h | 4 +- alib2data/src/grammar/ContextFree/CNF.h | 4 +- .../src/grammar/ContextFree/EpsilonFreeCFG.h | 4 +- alib2data/src/grammar/ContextFree/GNF.h | 4 +- alib2data/src/grammar/ContextFree/LG.h | 4 +- alib2data/src/grammar/Regular/LeftLG.h | 4 +- alib2data/src/grammar/Regular/LeftRG.h | 4 +- alib2data/src/grammar/Regular/RightLG.h | 4 +- alib2data/src/grammar/Regular/RightRG.h | 4 +- alib2std/src/extensions/container/map.hpp | 3 +- alib2std/src/extensions/container/set.hpp | 3 +- alib2std/src/extensions/functional.hpp | 54 ++++++++++++------- .../test-src/extensions/FunctionalTest.cpp | 6 ++- 14 files changed, 62 insertions(+), 43 deletions(-) diff --git a/alib2common/src/common/createUnique.hpp b/alib2common/src/common/createUnique.hpp index 677ba46103..d73415828a 100644 --- a/alib2common/src/common/createUnique.hpp +++ b/alib2common/src/common/createUnique.hpp @@ -13,6 +13,7 @@ #include "exception/CommonException.h" #include <climits> #include <alib/algorithm> +#include <alib/functional> namespace common { @@ -46,7 +47,7 @@ T createUnique ( T object, const Alphabets & ... alphabets ) { unsigned i = 0; do { - if ( ( ... && ( alphabets.count ( object ) == 0 ) ) ) + if ( ( ... && ( alphabets.count ( ext::poly_comp < typename Alphabets::value_type > ( object ) ) == 0 ) ) ) return object; inc ( object ); diff --git a/alib2data/src/grammar/ContextFree/CFG.h b/alib2data/src/grammar/ContextFree/CFG.h index e4c1deaf03..15ade64a22 100644 --- a/alib2data/src/grammar/ContextFree/CFG.h +++ b/alib2data/src/grammar/ContextFree/CFG.h @@ -407,7 +407,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::CFG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -467,7 +467,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::CFG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2data/src/grammar/ContextFree/CNF.h b/alib2data/src/grammar/ContextFree/CNF.h index aeca45bf3e..2d6e5ddd9a 100644 --- a/alib2data/src/grammar/ContextFree/CNF.h +++ b/alib2data/src/grammar/ContextFree/CNF.h @@ -510,7 +510,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::CNF < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -574,7 +574,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::CNF < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h index c71cc43576..619348c11a 100644 --- a/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h +++ b/alib2data/src/grammar/ContextFree/EpsilonFreeCFG.h @@ -425,7 +425,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::EpsilonFreeCFG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -485,7 +485,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::EpsilonFreeCFG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2data/src/grammar/ContextFree/GNF.h b/alib2data/src/grammar/ContextFree/GNF.h index ece44382bc..7bd3b42843 100644 --- a/alib2data/src/grammar/ContextFree/GNF.h +++ b/alib2data/src/grammar/ContextFree/GNF.h @@ -424,7 +424,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::GNF < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -483,7 +483,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::GNF < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2data/src/grammar/ContextFree/LG.h b/alib2data/src/grammar/ContextFree/LG.h index 0e3d66c913..a0dc98309c 100644 --- a/alib2data/src/grammar/ContextFree/LG.h +++ b/alib2data/src/grammar/ContextFree/LG.h @@ -514,7 +514,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::LG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -578,7 +578,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::LG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2data/src/grammar/Regular/LeftLG.h b/alib2data/src/grammar/Regular/LeftLG.h index df00229cf7..1e2b27b2e6 100644 --- a/alib2data/src/grammar/Regular/LeftLG.h +++ b/alib2data/src/grammar/Regular/LeftLG.h @@ -497,7 +497,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::LeftLG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -561,7 +561,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::LeftLG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2data/src/grammar/Regular/LeftRG.h b/alib2data/src/grammar/Regular/LeftRG.h index 3c8772ea02..482af3342e 100644 --- a/alib2data/src/grammar/Regular/LeftRG.h +++ b/alib2data/src/grammar/Regular/LeftRG.h @@ -513,7 +513,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -573,7 +573,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::LeftRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2data/src/grammar/Regular/RightLG.h b/alib2data/src/grammar/Regular/RightLG.h index 09f7e1573a..dd0d3db4b7 100644 --- a/alib2data/src/grammar/Regular/RightLG.h +++ b/alib2data/src/grammar/Regular/RightLG.h @@ -494,7 +494,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::RightLG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -558,7 +558,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::RightLG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2data/src/grammar/Regular/RightRG.h b/alib2data/src/grammar/Regular/RightRG.h index 95d227bfb6..1ada868e41 100644 --- a/alib2data/src/grammar/Regular/RightRG.h +++ b/alib2data/src/grammar/Regular/RightRG.h @@ -512,7 +512,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::RightRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const TerminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::NonterminalAlphabet > ( ).get ( ).count ( ext::poly_comp < NonterminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the terminal alphabet since it is already in the nonterminal alphabet." ); } }; @@ -572,7 +572,7 @@ public: * \throws grammar::GrammarException of the tested symbol is in nonterminal alphabet */ static void valid ( const grammar::RightRG < TerminalSymbolType, NonterminalSymbolType > & grammar, const NonterminalSymbolType & symbol ) { - if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( symbol ) ) + if ( grammar.template accessComponent < grammar::TerminalAlphabet > ( ).get ( ).count ( ext::poly_comp < TerminalSymbolType > ( symbol ) ) ) throw grammar::GrammarException ( "Symbol " + ext::to_string ( symbol ) + " cannot be in the nonterminal alphabet since it is already in the terminal alphabet." ); } }; diff --git a/alib2std/src/extensions/container/map.hpp b/alib2std/src/extensions/container/map.hpp index b5b39124db..416458d173 100644 --- a/alib2std/src/extensions/container/map.hpp +++ b/alib2std/src/extensions/container/map.hpp @@ -35,7 +35,6 @@ #include <extensions/compare.hpp> #include <extensions/allocFix.hpp> #include <extensions/range.hpp> -#include <extensions/functional.hpp> namespace ext { @@ -50,7 +49,7 @@ namespace ext { * \tparam Cmp the comparator type used to order keys * \tparam Alloc the allocator of values of type T */ -template < typename T, typename R, typename Cmp = ext::less < >, 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 >, AllocFix < Alloc > { public: /** diff --git a/alib2std/src/extensions/container/set.hpp b/alib2std/src/extensions/container/set.hpp index 783b6f33c1..9cd582ffde 100644 --- a/alib2std/src/extensions/container/set.hpp +++ b/alib2std/src/extensions/container/set.hpp @@ -32,7 +32,6 @@ #include <extensions/compare.hpp> #include <extensions/allocFix.hpp> #include <extensions/range.hpp> -#include <extensions/functional.hpp> namespace ext { @@ -45,7 +44,7 @@ namespace ext { * \tparam Cmp the comparator type used to order keys * \tparam Alloc the allocator of values of type T */ -template < typename T, typename Cmp = ext::less < >, 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 >, AllocFix < Alloc > { public: /** diff --git a/alib2std/src/extensions/functional.hpp b/alib2std/src/extensions/functional.hpp index 1feb42aae7..091ec29066 100644 --- a/alib2std/src/extensions/functional.hpp +++ b/alib2std/src/extensions/functional.hpp @@ -31,30 +31,48 @@ namespace ext { -template < typename _Tp = void > -struct less; +template < class T, class R > +struct PolyComp { + const T & m_inst; -template < typename _Tp > -struct less : public std::binary_function < _Tp, _Tp, bool > { - bool operator ( ) ( const _Tp & __x, const _Tp & __y ) const { - return __x < __y; + explicit PolyComp ( const T & inst ) : m_inst ( inst ) { } }; -template < > -struct less < void > { - template < typename _Tp, typename _Up, typename std::enable_if < supports < std::less < > ( _Tp, _Up ) >::value >::type * = nullptr > - auto operator ( ) ( _Tp && __t, _Up && __u ) const noexcept ( noexcept ( std::forward < _Tp > ( __t ) < std::forward < _Up > ( __u ) ) ) -> decltype ( std::forward < _Tp > ( __t ) < std::forward < _Up > ( __u ) ) { - return std::forward < _Tp > ( __t ) < std::forward < _Up > ( __u ); - } +template < class R, class T > +PolyComp < T, R > poly_comp ( const T & inst ) { + return PolyComp < T, R > ( inst ); +} - template < typename _Tp, typename _Up, typename std::enable_if < ! supports < std::less < > ( _Tp, _Up ) >::value >::type * = nullptr > - bool operator ( ) ( _Tp &&, _Up && ) const noexcept { - return ext::type_index ( typeid ( _Tp ) ) < ext::type_index ( typeid ( _Up ) ); - } +template < class T > +bool operator < ( const PolyComp < T, T > & first, const T & second ) { + return first.m_inst < second; +} - typedef std::__is_transparent is_transparent; -}; +template < class T > +bool operator < ( const T & first, const PolyComp < T, T > & second ) { + return first < second.m_inst; +} + +template < class T, class R, typename std::enable_if < supports < std::less < > ( T, R ) >::value && ! std::is_same < T, R >::value >::type * = nullptr > +bool operator < ( const PolyComp < T, R > & first, const R & second ) { + return first.m_inst < second; +} + +template < class T, class R, typename std::enable_if < ! supports < std::less < > ( T, R ) >::value && ! std::is_same < T, R >::value >::type * = nullptr > +bool operator < ( const PolyComp < T, R > &, const R & ) { + return std::type_index ( typeid ( T ) ) < std::type_index ( typeid ( R ) ); +} + +template < class R, class T, typename std::enable_if < supports < std::less < > ( R, T ) >::value && ! std::is_same < T, R >::value >::type * = nullptr > +bool operator < ( const R & first, const PolyComp < T, R > & second ) { + return first < second.m_inst; +} + +template < class R, class T, typename std::enable_if < ! supports < std::less < > ( R, T ) >::value && ! std::is_same < T, R >::value >::type * = nullptr > +bool operator < ( const R &, const PolyComp < T, R > & ) { + return std::type_index ( typeid ( R ) ) < std::type_index ( typeid ( T ) ); +} /** * \brief diff --git a/alib2std/test-src/extensions/FunctionalTest.cpp b/alib2std/test-src/extensions/FunctionalTest.cpp index 3336fb68d9..9e8115d44e 100644 --- a/alib2std/test-src/extensions/FunctionalTest.cpp +++ b/alib2std/test-src/extensions/FunctionalTest.cpp @@ -4,10 +4,12 @@ TEST_CASE ( "Functional Test", "[unit][std][bits]" ) { SECTION ( "Less" ) { - ext::less < > test; + std::less < > test; CHECK ( test ( 1, 2 ) == true ); CHECK ( test ( 1, 2. ) == true ); - CHECK_EXCLUSIVE_OR( (test ( std::string ( "aa" ), 1 )), (test ( 1, std::string ( "aa" ) ) ) ); + CHECK_EXCLUSIVE_OR( ( test ( ext::poly_comp < int > ( std::string ( "aa" ) ), 1 ) ), ( test ( ext::poly_comp < std::string > ( 1 ), std::string ( "aa" ) ) ) ); + + CHECK ( test ( ext::poly_comp < int > ( 1 ), 2 ) == true ); } } -- GitLab