diff --git a/alib2common/src/common/createUnique.hpp b/alib2common/src/common/createUnique.hpp index 677ba46103e1adae2c2fb321aae4e2f7509c2236..d73415828acb6d8a680509aa7fdac5aa59142ec1 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 e4c1deaf0340270a43dadd6321e9ec28028346f2..15ade64a22d8d61f05eb7fa11fda9335918da6e9 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 aeca45bf3e1980e1efa90d0eafa733be0fbfcd4a..2d6e5ddd9a04b1ad59637ac4ede0ad3e6ce0b393 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 c71cc435764e6633cdecf89e19e95d17ffb76d34..619348c11ab5b17f553017da4b3afd2098e81599 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 ece44382bca2d257a1538a6052fa291a540faaba..7bd3b42843c3d64682e5af8633866a0fc929e1f1 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 0e3d66c913ae178b8500ac8ada3230a6e28a2547..a0dc98309c4fc4feb0fe379985d60b357b72972e 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 df00229cf758f0836176c34b23d7a32996fa228c..1e2b27b2e6e00d3273d2fbc6976cc60ab94da139 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 3c8772ea0239851dc13bb571ec5ef9f17ed101e5..482af3342e646da6522e7f916445f729b12a095d 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 09f7e1573a23072121d7296b9671f2827ea52a8e..dd0d3db4b7d887a58eac09076e2e4df73dac57ca 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 95d227bfb6ad52f02232114c326b976d66e086ed..1ada868e413ee6cd3cb985bc35363cbc599b7f3e 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 b5b39124dbf3bcb0d46b540f94ed6e42c303fe4b..416458d1737039e0456e92219c93ecde672da302 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 783b6f33c190376bc5731c1e52c597f53c02becf..9cd582ffde177dd67ce995ffe76b65975c9d4327 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 1feb42aae7cd9aace743f2514d21b48b365da6be..091ec29066f68629eb35210371e4bab643318de8 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 3336fb68d9b4ede876b56e1355baf6dea3f68706..9e8115d44e23a8751acab9065c81a508c1a789ca 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 ); } }