diff --git a/alib2std/src/extensions/heaps/BinomialHeap.h b/alib2std/src/extensions/heaps/BinomialHeap.h
index 9cb97d3b1aceac621c87cdf03aba50efb29b50dc..3e5293d76ed1c404bbcd2f82d749ecd79e60d6db 100644
--- a/alib2std/src/extensions/heaps/BinomialHeap.h
+++ b/alib2std/src/extensions/heaps/BinomialHeap.h
@@ -1,8 +1,8 @@
 /*
  * BinomialHeap.h
  *
- *   Created on: Apr 7, 2016
- *       Author: Jan Broz
+ * Created on: Apr 7, 2016
+ * Author: Jan Broz
  */
 
 #ifndef BINOMIAL_HEAP_INCLUDED
@@ -12,82 +12,89 @@
 
 namespace alib {
 
-/// binomial heap used as mergeable priority queue
-template< typename elem_t >
+// binomial heap used as mergeable priority queue
+template < typename T, typename Comparator >
 class BinomialHeap {
+	int threeWay ( const T & a, const T & b ) const {
+		bool less = _compare ( a, b );
+		bool more = _compare ( b, a );
+		if ( ! less && ! more )
+			return 0;
+		else if ( less )
+			return -1;
+		else
+			return 1;
+	}
+
 public:
 
-	BinomialHeap( int (* compare)( const elem_t &, const elem_t & ) );
+	BinomialHeap ( Comparator comparator = Comparator ( ) ) : _head( nullptr ), _size( 0 ), _compare ( comparator ) {
+	}
 
-	~BinomialHeap();
+	~BinomialHeap ( );
 
-	/// inserts a node with new value into the heap
-	void insert( const elem_t & value );
+	// inserts a node with new value into the heap
+	void insert ( const T & value );
 
-	/// finds the maximum value in the heap
-	const elem_t & getMax() const {
-		return (*searchMax( const_cast<Node**>(&_head) ))->value;
+	// finds the maximum value in the heap
+	const T & getMax ( ) const {
+		return ( * searchMax ( const_cast < Node * * > ( & _head ) ) )->value;
 	}
 
-	/// finds and removes the maximum value from the heap
-	elem_t extractMax();
+	// finds and removes the maximum value from the heap
+	T extractMax ( );
 
-	/// merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!)
-	void mergeWith( BinomialHeap<elem_t> && that );
+	// merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!)
+	void mergeWith ( BinomialHeap< T, Comparator > && that );
 
-	size_t size() const {
+	size_t size ( ) const {
 		return _size;
 	}
 
 protected:
 
 	struct Node {
-		elem_t value;
-		unsigned   degree;
+		T value;
+		unsigned degree;
 		Node * parent;
 		Node * child;
 		Node * sibling;
-		Node( const elem_t & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * sib = nullptr )
-		 : value(val), degree(deg), parent(par), child(chld), sibling(sib) {}
+		Node( const T & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * sib = nullptr )
+		 : value ( val ), degree ( deg ), parent ( par ), child ( chld ), sibling ( sib ) { }
 	};
 
-	Node *  _head;    ///< head of a singly linked list of binomial trees
-	size_t    _size;    ///< count of elements stored in the heap
-	int (*  _compare)( const elem_t &, const elem_t & ); ///< user-defined comparator function
+	Node * _head; //< head of a singly linked list of binomial trees
+	size_t _size; //< count of elements stored in the heap
+	Comparator _compare; //< user-defined comparator function
 
 protected:
 
-	/// deletes one linked list of binomial trees
+	// deletes one linked list of binomial trees
 	void deleteTreeList( Node * head );
 
-	/// searches the linked list and returns address of variable pointing to the node with maximum value
+	// searches the linked list and returns address of variable pointing to the node with maximum value
 	Node * * searchMax( Node * * head ) const;
-	/// merges linked lists from 2 binomial heaps and returns address of head of the new linked list
+	// merges linked lists from 2 binomial heaps and returns address of head of the new linked list
 
-	Node *   mergeHeaps( Node * head1, Node * head2 );
-	/// merges 2 linked lists of binomial trees and sorts the trees by increasing degree
+	Node * mergeHeaps( Node * head1, Node * head2 );
+	// merges 2 linked lists of binomial trees and sorts the trees by increasing degree
 
-	Node *   mergeListsByDeg( Node * head1, Node * head2 );
-	/// reverses a linked list
+	Node * mergeListsByDeg( Node * head1, Node * head2 );
+	// reverses a linked list
 
-	Node *   reverseList( Node * head );
-	/// links root of tree1 to root of tree2 (tree1 becomes child of tree2)
-	Node *   linkTreeToTree( Node * root1, Node * root2 );
+	Node * reverseList( Node * head );
+	// links root of tree1 to root of tree2 (tree1 becomes child of tree2)
+	Node * linkTreeToTree( Node * root1, Node * root2 );
 
 };
 
-
-template< typename elem_t >
-BinomialHeap<elem_t>::BinomialHeap( int (* compare)( const elem_t &, const elem_t & ) ) : _head( nullptr ), _size( 0 ), _compare( compare ) {
-}
-
-template< typename elem_t >
-BinomialHeap<elem_t>::~BinomialHeap() {
+template < typename T, typename Comparator >
+BinomialHeap < T, Comparator >::~BinomialHeap() {
 	deleteTreeList( _head );
 }
 
-template< typename elem_t >
-void BinomialHeap<elem_t>::deleteTreeList( Node * head ) {
+template < typename T, typename Comparator >
+void BinomialHeap < T, Comparator >::deleteTreeList( Node * head ) {
 	while (head != nullptr) {
 		Node * sibling = head->sibling;
 		deleteTreeList( head->child );
@@ -96,51 +103,51 @@ void BinomialHeap<elem_t>::deleteTreeList( Node * head ) {
 	}
 }
 
-template< typename elem_t >
-void BinomialHeap<elem_t>::insert( const elem_t & value ) {
+template < typename T, typename Comparator >
+void BinomialHeap < T, Comparator >::insert( const T & value ) {
 	Node * newNode = new Node( value, 0, nullptr, nullptr, nullptr );
 
 	_head = mergeHeaps( _head, newNode ); // merge the current heap with the newNode,
-	                              // as if the newNode was a single-element heap
+	 // as if the newNode was a single-element heap
 	_size++;
 }
 
-template< typename elem_t >
-elem_t BinomialHeap<elem_t>::extractMax() {
+template< typename T, typename Comparator >
+T BinomialHeap< T, Comparator >::extractMax() {
 	if ( _size == 0 )
 		throw std::out_of_range ( "Heap is empty." );
 
-	Node * * ptrToMax = searchMax( &_head );    // find the node with maximum value
+	Node * * ptrToMax = searchMax( &_head ); // find the node with maximum value
 	Node * max = *ptrToMax;
 
-	*ptrToMax = max->sibling;       // disconnect it from the linked list
+	*ptrToMax = max->sibling; // disconnect it from the linked list
 
-	Node * chlHead = reverseList( max->child );       // merge them with the heap in reversed order
+	Node * chlHead = reverseList( max->child ); // merge them with the heap in reversed order
 	_head = mergeHeaps( this->_head, chlHead );
 
 	_size--;
-	elem_t maxVal = max->value;
-	delete max;                     // extract the value from node and return it
+	T maxVal = max->value;
+	delete max; // extract the value from node and return it
 	return maxVal;
 }
 
-template< typename elem_t >
-void BinomialHeap<elem_t>::mergeWith( BinomialHeap<elem_t> && that ) {
-	if (this->_compare != that._compare)    // nodes of these heaps are sorted by different condition
+template < typename T, typename Comparator >
+void BinomialHeap < T, Comparator >::mergeWith( BinomialHeap< T, Comparator > && that ) {
+	if (this->_compare != that._compare) // nodes of these heaps are sorted by different condition
 		throw std::logic_error("compare functions aren't equal, unable to merge");
 
-	this->_head = mergeHeaps( this->_head, that._head );    // move the other heap into this heap
+	this->_head = mergeHeaps( this->_head, that._head ); // move the other heap into this heap
 	that._head = nullptr;
 
 	this->_size += that._size;
 	that._size = 0;
 }
 
-template< typename elem_t >
-typename BinomialHeap<elem_t>::Node * * BinomialHeap<elem_t>::searchMax( Node * * head ) const {
+template < typename T, typename Comparator >
+typename BinomialHeap < T, Comparator >::Node * * BinomialHeap< T, Comparator >::searchMax( Node * * head ) const {
 	Node * max = *head, * * ptrToMax = head;
 	for (Node * actual = * head, * prev = nullptr; actual != nullptr; prev = actual, actual = actual->sibling) {
-		if (_compare( actual->value, max->value ) > 0) {
+		if ( threeWay ( actual->value, max->value ) > 0) {
 			max = actual;
 			ptrToMax = &prev->sibling;
 		}
@@ -148,15 +155,15 @@ typename BinomialHeap<elem_t>::Node * * BinomialHeap<elem_t>::searchMax( Node *
 	return ptrToMax;
 }
 
-template< typename elem_t >
-typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::mergeHeaps( Node * head1, Node * head2 ) {
+template < typename T, typename Comparator >
+typename BinomialHeap < T, Comparator >::Node * BinomialHeap< T, Comparator >::mergeHeaps( Node * head1, Node * head2 ) {
 	if ( ! head1 )
 		return head2;
 
 	if ( ! head2 )
 		return head1;
 
-	head1 = mergeListsByDeg( head1, head2 );   // first, merge the lists of trees by their degrees
+	head1 = mergeListsByDeg( head1, head2 ); // first, merge the lists of trees by their degrees
 
 	Node * actual = head1;
 	Node * * toLink = & head1;
@@ -164,45 +171,45 @@ typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::mergeHeaps( Node * h
 		Node * next = actual->sibling;
 
 		if (actual->degree != next->degree || (next->sibling && next->sibling->degree == actual->degree)) {
-			toLink = &actual->sibling;                // not merging trees with same degree
-			actual = next;                            // or postponing the merge by 1 iteration
-		} else if (_compare( actual->value, next->value ) >= 0) {
-			actual->sibling = next->sibling;          // merging 2 binomial trees with same degree
-			actual = linkTreeToTree( next, actual );  // 'next'    becomes child of   'actual'
+			toLink = &actual->sibling; // not merging trees with same degree
+			actual = next; // or postponing the merge by 1 iteration
+		} else if ( threeWay ( actual->value, next->value ) >= 0) {
+			actual->sibling = next->sibling; // merging 2 binomial trees with same degree
+			actual = linkTreeToTree( next, actual ); // 'next' becomes child of 'actual'
 		} else {
-			*toLink = next;                           // merging 2 binomial trees with same degree
-			actual = linkTreeToTree( actual, next );  // 'actual'  becomes child of   'next'
+			*toLink = next; // merging 2 binomial trees with same degree
+			actual = linkTreeToTree( actual, next ); // 'actual' becomes child of 'next'
 		}
 	}
 
 	return head1;
 }
 
-template< typename elem_t >
-typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::mergeListsByDeg( Node * head1, Node * head2 ) {
+template < typename T, typename Comparator >
+typename BinomialHeap < T, Comparator >::Node * BinomialHeap< T, Comparator >::mergeListsByDeg( Node * head1, Node * head2 ) {
 	Node * newHead = nullptr;
 	Node * * toLink = &newHead;
 	while (head1 && head2) {
 		if (head1->degree < head2->degree) {
-			*toLink = head1;                      // linking node from first list
-			toLink = &head1->sibling;             // and moving first pointer
+			*toLink = head1; // linking node from first list
+			toLink = &head1->sibling; // and moving first pointer
 			head1 = head1->sibling;
 		} else {
-			*toLink = head2;                      // linking node from second list
-			toLink = &head2->sibling;             // and moving second pointer
+			*toLink = head2; // linking node from second list
+			toLink = &head2->sibling; // and moving second pointer
 			head2 = head2->sibling;
 		}
 	}
 	if (!head1)
-		*toLink = head2;        // list1 ended, link the rest of list2
+		*toLink = head2; // list1 ended, link the rest of list2
 	else
-		*toLink = head1;        // list2 ended, link the rest of list1
+		*toLink = head1; // list2 ended, link the rest of list1
 
 	return newHead;
 }
 
-template< typename elem_t >
-typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::reverseList( Node * head ) {
+template < typename T, typename Comparator >
+typename BinomialHeap < T, Comparator >::Node * BinomialHeap< T, Comparator >::reverseList( Node * head ) {
 	Node * prev = nullptr;
 
 	while (head) {
@@ -215,8 +222,8 @@ typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::reverseList( Node *
 	return prev;
 }
 
-template< typename elem_t >
-typename BinomialHeap<elem_t>::Node * BinomialHeap<elem_t>::linkTreeToTree( Node * root1, Node * root2 ) {
+template < typename T, typename Comparator >
+typename BinomialHeap < T, Comparator >::Node * BinomialHeap< T, Comparator >::linkTreeToTree( Node * root1, Node * root2 ) {
 	root1->parent = root2;
 	root1->sibling = root2->child;
 	root2->child = root1;
diff --git a/alib2std/src/extensions/heaps/CppHeap.h b/alib2std/src/extensions/heaps/CppHeap.h
index eeebc4a6f49a43697f649081353848d39e1b0aff..681e83556b54012c77502d2163719e69d1a65d20 100644
--- a/alib2std/src/extensions/heaps/CppHeap.h
+++ b/alib2std/src/extensions/heaps/CppHeap.h
@@ -13,67 +13,58 @@
 
 namespace alib {
 
-/// binomial heap used as mergeable priority queue
-template < typename elem_t >
+/// heap build using C++ algorithm features
+template < typename T, typename Comparator = std::less < T > >
 class CppHeap {
 public:
-	CppHeap( int (* compare)( const elem_t &, const elem_t & ) );
-
-	~CppHeap();
+	CppHeap( Comparator comparator = Comparator ( ) ) : m_comparator( comparator ) {
+	}
 
-	/// inserts a node with new value into the heap
-	void insert( const elem_t & value );
+	// inserts a node with new value into the heap
+	void insert ( const T & value );
 
 	/// finds the maximum value in the heap
-	const elem_t & getMax() const {
-		return _data.front ( );
+	const T & getMax ( ) const {
+		return m_data.front ( );
 	}
 
 	/// finds and removes the maximum value from the heap
-	elem_t extractMax();
+	T extractMax ( );
 
 	/// merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!)
-	void mergeWith( CppHeap<elem_t> && that );
+	void mergeWith ( CppHeap < T, Comparator > && that );
 
-	size_t size() const {
-		return _data.size ( );
+	size_t size ( ) const {
+		return m_data.size ( );
 	}
 
 protected:
-	int (* _compare)( const elem_t &, const elem_t & ); ///< user-defined comparator function
-	std::vector < elem_t > _data;
+	Comparator m_comparator;
+	std::vector < T > m_data;
 };
 
 
-template< typename elem_t >
-CppHeap<elem_t>::CppHeap( int (* compare)( const elem_t &, const elem_t & ) ) : _compare( compare ) {
-}
-
-template< typename elem_t >
-CppHeap<elem_t>::~CppHeap() {
-}
-
-template< typename elem_t >
-void CppHeap<elem_t>::insert( const elem_t & value ) {
-	_data.push_back ( value );
-	std::push_heap ( _data.begin ( ), _data.end ( ), _compare );
+template < typename T, typename Comparator >
+void CppHeap < T, Comparator >::insert ( const T & value ) {
+	m_data.push_back ( value );
+	std::push_heap ( m_data.begin ( ), m_data.end ( ), m_comparator );
 }
 
-template< typename elem_t >
-elem_t CppHeap<elem_t>::extractMax() {
-	if ( _data.size ( ) == 0 )
+template < typename T, typename Comparator >
+T CppHeap < T, Comparator >::extractMax ( ) {
+	if ( m_data.size ( ) == 0 )
 		throw std::out_of_range ( "Heap is empty." );
 
-	elem_t res = _data.front ( );
-	std::pop_heap ( _data.begin ( ), _data.end ( ), _compare );
-	_data.pop_back ( );
+	std::pop_heap ( m_data.begin ( ), m_data.end ( ), m_comparator );
+	T res = std::move ( m_data.back ( ) );
+	m_data.pop_back ( );
 	return res;
 }
 
-template< typename elem_t >
-void CppHeap<elem_t>::mergeWith( CppHeap<elem_t> && that ) {
-	_data.insert ( _data.end ( ), that._data.begin ( ), that._data.end ( ) );
-	std::make_heap ( _data.begin ( ), _data.end ( ), _compare );
+template < typename T, typename Comparator >
+void CppHeap < T, Comparator >::mergeWith( CppHeap < T, Comparator > && that ) {
+	m_data.insert ( m_data.end ( ), that.m_data.begin ( ), that.m_data.end ( ) );
+	std::make_heap ( m_data.begin ( ), m_data.end ( ), m_comparator );
 }
 
 } /* namespace alib */
diff --git a/alib2std/src/extensions/heaps/FibonacciHeap.h b/alib2std/src/extensions/heaps/FibonacciHeap.h
index 73814ff9423d090954ab722fe35f9c16c4b38bfe..2afae091d34686fd16126d69f86e2d34b3ec4fde 100644
--- a/alib2std/src/extensions/heaps/FibonacciHeap.h
+++ b/alib2std/src/extensions/heaps/FibonacciHeap.h
@@ -1,41 +1,53 @@
 /*
  * FibonacciHeap.h
  *
- *   Created on: Apr 7, 2016
- *       Author: Jan Broz
+ * Created on: Apr 7, 2016
+ * Author: Jan Broz
  */
 
 #ifndef FIBONACCI_HEAP_INCLUDED
 #define FIBONACCI_HEAP_INCLUDED
 
 #include <stdexcept>
-#include <cmath>      // maxDegree
+#include <cmath> // maxDegree
 
 namespace alib {
 
-/// fibonacci heap used as mergeable priority queue
-template< typename elem_t >
+// fibonacci heap used as mergeable priority queue
+template < typename T, typename Comparator >
 class FibonacciHeap {
+	int threeWay ( const T & a, const T & b ) const {
+		bool less = _compare ( a, b );
+		bool more = _compare ( b, a );
+		if ( ! less && ! more )
+			return 0;
+		else if ( less )
+			return -1;
+		else
+			return 1;
+	}
+
 public:
-	FibonacciHeap( int (* compare)( const elem_t &, const elem_t & ) );
+	FibonacciHeap ( Comparator comparator = Comparator ( ) ) : _max( nullptr ), _size( 0 ), _compare( comparator ) {
+	}
 
-	~FibonacciHeap();
+	~FibonacciHeap ( );
 
-	/// inserts a node with new value into the heap
-	void insert( const elem_t & value );
+	// inserts a node with new value into the heap
+	void insert ( const T & value );
 
-	/// finds the maximum value in the heap
-	const elem_t & getMax() const {
+	// finds the maximum value in the heap
+	const T & getMax ( ) const {
 		return _max->value;
 	}
 
-	/// finds and removes the maximum value from the heap
-	elem_t extractMax();
+	// finds and removes the maximum value from the heap
+	T extractMax ( );
 
-	/// merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!)
-	void mergeWith( FibonacciHeap<elem_t> && that );
+	// merges this heap with another heap (!! this is a DESTRUCTIVE merge, heap in argument will be cleared !!)
+	void mergeWith ( FibonacciHeap< T, Comparator > && that );
 
-	size_t size() const {
+	size_t size ( ) const {
 		return _size;
 	}
 
@@ -45,33 +57,33 @@ public:
 
 protected:
 	struct Node {
-		elem_t value;
+		T value;
 		unsigned degree;
-		bool   mark;
+		bool mark;
 		Node * parent;
 		Node * child;
 		Node * prev;
 		Node * next;
-		Node(const elem_t & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * pr = nullptr, Node * ne = nullptr)
+		Node(const T & val, unsigned deg = 0, Node * par = nullptr, Node * chld = nullptr, Node * pr = nullptr, Node * ne = nullptr)
 		 : value(val), degree(deg), mark(false), parent(par), child(chld), prev(pr), next(ne) {}
 	};
 
-	Node *  _max;     ///< pointer to cyclic doubly linked list of trees
-	size_t    _size;    ///< count of elements stored in the heap
-	int (*  _compare)( const elem_t &, const elem_t & ); ///< user-defined comparator function
+	Node * _max; //< pointer to cyclic doubly linked list of trees
+	size_t _size; //< count of elements stored in the heap
+	Comparator _compare; //< user-defined comparator function
 
 protected:
 
-	/// deletes one linked list of trees
+	// deletes one linked list of trees
 	void deleteTreeList( Node * head );
 
-	/// connects doubly linked lists from 2 fibonacci heaps and returns address of head of the new linked list
+	// connects doubly linked lists from 2 fibonacci heaps and returns address of head of the new linked list
 	void mergeHeaps( Node * & max1, Node * & max2 );
 
-	/// goes through list of trees and merges trees with same degree
+	// goes through list of trees and merges trees with same degree
 	void consolidate();
 
-	/// links tree to child list of node
+	// links tree to child list of node
 	void linkTreeToNode( Node * node, Node * tree );
 
 //	void printNode ( Node * node );
@@ -80,17 +92,13 @@ protected:
 };
 
 
-template< typename elem_t >
-FibonacciHeap<elem_t>::FibonacciHeap ( int (* compare)( const elem_t &, const elem_t & ) ) : _max( nullptr ), _size( 0 ), _compare( compare ) {
-}
-
-template< typename elem_t >
-FibonacciHeap<elem_t>::~FibonacciHeap ( ) {
+template < typename T, typename Comparator >
+FibonacciHeap< T, Comparator >::~FibonacciHeap ( ) {
 	deleteTreeList( _max );
 }
 
-template< typename elem_t >
-void FibonacciHeap<elem_t>::deleteTreeList( Node * head ) {
+template < typename T, typename Comparator >
+void FibonacciHeap< T, Comparator >::deleteTreeList( Node * head ) {
 	if ( ! head )
 		return;
 
@@ -103,32 +111,32 @@ void FibonacciHeap<elem_t>::deleteTreeList( Node * head ) {
 	} while (actual != head);
 }
 
-template< typename elem_t >
-void FibonacciHeap<elem_t>::insert( const elem_t & value ) {
+template < typename T, typename Comparator >
+void FibonacciHeap< T, Comparator >::insert( const T & value ) {
 	Node * newNode = new Node( value, 0, nullptr, nullptr, nullptr, nullptr );
 	newNode->prev = newNode;
-	newNode->next = newNode;     // make this node be a single-element cyclic list
+	newNode->next = newNode; // make this node be a single-element cyclic list
 
 	if (!_max) {
-		_max = newNode;       // this heap is empty, newNode becomes head of a linked list
+		_max = newNode; // this heap is empty, newNode becomes head of a linked list
 		_size = 1;
 		return;
 	}
 
-	mergeHeaps( _max, newNode );    // link the newNode into the existing linked list
+	mergeHeaps( _max, newNode ); // link the newNode into the existing linked list
 
-	_max = _compare( _max->value, newNode->value ) > 0 ? _max : newNode;
+	_max = threeWay ( _max->value, newNode->value ) > 0 ? _max : newNode;
 
 	_size++;
 }
 
-template< typename elem_t >
-elem_t FibonacciHeap<elem_t>::extractMax() {
+template < typename T, typename Comparator >
+T FibonacciHeap< T, Comparator >::extractMax() {
 	if ( _max == nullptr )
 		throw std::out_of_range ( "Heap is empty." );
 
 	Node * z = _max;
-	elem_t maxVal = z->value;
+	T maxVal = z->value;
 
 	if (z->child != nullptr) {
 		Node * z1 = z->child;
@@ -154,35 +162,35 @@ elem_t FibonacciHeap<elem_t>::extractMax() {
 	return maxVal;
 }
 
-template< typename elem_t >
-void FibonacciHeap<elem_t>::mergeWith( FibonacciHeap<elem_t> && that ) {
-	if (this->_compare != that._compare)    // nodes of these heaps are sorted by different condition
+template < typename T, typename Comparator >
+void FibonacciHeap< T, Comparator >::mergeWith( FibonacciHeap< T, Comparator > && that ) {
+	if (this->_compare != that._compare) // nodes of these heaps are sorted by different condition
 		throw std::logic_error("compare functions aren't equal, unable to merge");
 
-	mergeHeaps( this->_max, that._max );    // link the other heap into this heap
-	this->_max = _compare( _max->value, that._max->value ) > 0 ? this->_max : that._max;
+	mergeHeaps( this->_max, that._max ); // link the other heap into this heap
+	this->_max = threeWay ( _max->value, that._max->value ) > 0 ? this->_max : that._max;
 	that._max = nullptr;
 
 	this->_size += that._size;
 	that._size = 0;
 }
 
-template< typename elem_t >
-void FibonacciHeap<elem_t>::mergeHeaps( Node * & max1, Node * & max2 ) {
+template < typename T, typename Comparator >
+void FibonacciHeap< T, Comparator >::mergeHeaps( Node * & max1, Node * & max2 ) {
 	if ( ! max1 ) {
-		max1 = max2;    // this heap is empty, move the content from the other heap inside
+		max1 = max2; // this heap is empty, move the content from the other heap inside
 	} else if ( max2 ) {
 		Node * max2prev = max2->prev;
 
 		max2->prev->next = max1;
-		max2->prev = max1->prev;    // this magicaly works even if the lists contain only one node
+		max2->prev = max1->prev; // this magicaly works even if the lists contain only one node
 		max1->prev->next = max2;
 		max1->prev = max2prev;
 	}
 }
 
-template< typename elem_t >
-void FibonacciHeap<elem_t>::consolidate() {
+template < typename T, typename Comparator >
+void FibonacciHeap< T, Comparator >::consolidate() {
 	unsigned maxDegree = log2( _size );
 	Node * * rootsByDegree = new Node * [ maxDegree + 1 ];
 	for (unsigned i = 0; i <= maxDegree; i++)
@@ -201,7 +209,7 @@ void FibonacciHeap<elem_t>::consolidate() {
 			Node * other = rootsByDegree[ actual->degree ];
 			rootsByDegree[ actual->degree ] = nullptr;
 
-			if (_compare( actual->value, other->value ) > 0) {
+			if ( threeWay ( actual->value, other->value ) > 0) {
 				linkTreeToNode( actual, other );
 			} else {
 				linkTreeToNode( other, actual );
@@ -217,14 +225,14 @@ void FibonacciHeap<elem_t>::consolidate() {
 	_max = actual;
 	Node * node = actual;
 	do {
-		if (_compare( node->value, _max->value ) > 0)
+		if ( threeWay ( node->value, _max->value ) > 0)
 			_max = node;
 		node = node->next;
 	} while ( node != actual );
 }
 
-template< typename elem_t >
-void FibonacciHeap<elem_t>::linkTreeToNode( Node * node, Node * tree ) {
+template < typename T, typename Comparator >
+void FibonacciHeap< T, Comparator >::linkTreeToNode( Node * node, Node * tree ) {
 	tree->prev->next = tree->next;
 	tree->next->prev = tree->prev;
 
@@ -237,16 +245,16 @@ void FibonacciHeap<elem_t>::linkTreeToNode( Node * node, Node * tree ) {
 	mergeHeaps ( node->child, tree );
 }
 
-/*template < typename elem_t >
-void FibonacciHeap<elem_t>::print() {
+/*template < typename T, typename Comparator >
+void FibonacciHeap< T, Comparator >::print() {
 	if ( _max == nullptr )
 		std::cout << "Empty" << std::endl;
 
 	printNode ( _max );
 }
 
-template < typename elem_t >
-void FibonacciHeap < elem_t >::printNode ( Node * node ) {
+template < typename T, typename Comparator >
+void FibonacciHeap < T >::printNode ( Node * node ) {
 	if ( node == nullptr )
 		return;
 
@@ -259,13 +267,13 @@ void FibonacciHeap < elem_t >::printNode ( Node * node ) {
 	} while ( node != actual );
 }
 
-template < typename elem_t >
-void FibonacciHeap<elem_t>::checkConsystency() {
+template < typename T, typename Comparator >
+void FibonacciHeap< T, Comparator >::checkConsystency() {
 	checkConsystency ( _max, nullptr );
 }
 
-template < typename elem_t >
-void FibonacciHeap < elem_t >::checkConsystency ( Node * node, Node * parent ) {
+template < typename T, typename Comparator >
+void FibonacciHeap < T >::checkConsystency ( Node * node, Node * parent ) {
 	if ( node == nullptr )
 		return;
 
diff --git a/alib2std/test-src/extensions/heaps/HeapsTest.cpp b/alib2std/test-src/extensions/heaps/HeapsTest.cpp
index 95225c3ae8126cc04ae7cc672c6f183e55d287be..6c4cd632044d6b6221d2cd3fb5f7752596b8f57b 100644
--- a/alib2std/test-src/extensions/heaps/HeapsTest.cpp
+++ b/alib2std/test-src/extensions/heaps/HeapsTest.cpp
@@ -4,19 +4,15 @@
 #include <alib/binomial_heap>
 #include <alib/fibonacci_heap>
 
-static int comparator ( const int & a, const int & b ) {
-	return ( b < a ) - ( a < b );
-}
-
 static int less ( const int & a, const int & b ) {
 	return a < b;
 }
 
 TEST_CASE ( "Heaps Test", "[unit][std][bits]" ) {
 	SECTION ( "Heaps" ) {
-		alib::BinomialHeap < int > bHeap ( comparator );
-		alib::CppHeap < int > cHeap ( less );
-		alib::FibonacciHeap < int > fHeap ( comparator );
+		alib::BinomialHeap < int, int ( * ) ( const int &, const int & ) > bHeap ( less );
+		alib::CppHeap < int, int ( * ) ( const int &, const int & ) > cHeap ( less );
+		alib::FibonacciHeap < int, int ( * ) ( const int &, const int & ) > fHeap ( less );
 
 		auto size = [ & ] ( ) {
 			int b = bHeap.size ( );
@@ -46,9 +42,9 @@ TEST_CASE ( "Heaps Test", "[unit][std][bits]" ) {
 		};
 
 		auto mergeRandom = [ & ] ( unsigned limit ) {
-			alib::BinomialHeap < int > rbHeap ( comparator );
-			alib::CppHeap < int > rcHeap ( comparator );
-			alib::FibonacciHeap < int > rfHeap ( comparator );
+			alib::BinomialHeap < int, int ( * ) ( const int &, const int & ) > rbHeap ( less );
+			alib::CppHeap < int, int ( * ) ( const int &, const int & ) > rcHeap ( less );
+			alib::FibonacciHeap < int, int ( * ) ( const int &, const int & ) > rfHeap ( less );
 
 			for ( unsigned i = 0; i < limit; ++ i ) {
 				unsigned val = rand ( ) % 1000;