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