Index: src/libcfa/stdlib
===================================================================
--- src/libcfa/stdlib	(revision e672372dcffd6ac8335882a71d5b294e036bda92)
+++ src/libcfa/stdlib	(revision 9c47a4703e167be1d751e6ac55951251b078e14c)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jan 28 17:12:35 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Dec 23 18:21:42 2017
-// Update Count     : 267
+// Last Modified On : Thu Dec 28 18:43:12 2017
+// Update Count     : 277
 //
 
@@ -185,13 +185,18 @@
 //---------------------------------------
 
-forall( otype T | { int ?<?( T, T ); } )
-T * bsearch( T key, const T * arr, size_t dim );
-
-forall( otype T | { int ?<?( T, T ); } )
-unsigned int bsearch( T key, const T * arr, size_t dim );
-
-
-forall( otype T | { int ?<?( T, T ); } )
-void qsort( const T * arr, size_t dim );
+forall( otype E | { int ?<?( E, E ); } )
+E * bsearch( E key, const E * arr, size_t dim );
+
+forall( otype E | { int ?<?( E, E ); } )
+unsigned int bsearch( E key, const E * arr, size_t dim );
+
+forall( otype K, otype E | { int ?<?( K, K ); K getKey( E & ); } )
+E * bsearch( K key, const E * arr, size_t dim );
+
+forall( otype K, otype E | { int ?<?( K, K ); K getKey( E & ); } )
+unsigned int bsearch( K key, const E * arr, size_t dim );
+
+forall( otype E | { int ?<?( E, E ); } )
+void qsort( E * arr, size_t dim );
 
 //---------------------------------------
Index: src/libcfa/stdlib.c
===================================================================
--- src/libcfa/stdlib.c	(revision e672372dcffd6ac8335882a71d5b294e036bda92)
+++ src/libcfa/stdlib.c	(revision 9c47a4703e167be1d751e6ac55951251b078e14c)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jan 28 17:10:29 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Dec 24 13:00:15 2017
-// Update Count     : 344
+// Last Modified On : Thu Dec 28 18:43:16 2017
+// Update Count     : 378
 //
 
@@ -128,20 +128,32 @@
 //---------------------------------------
 
-forall( otype T | { int ?<?( T, T ); } )
-T * bsearch( T key, const T * arr, size_t dim ) {
-	int comp( const void * t1, const void * t2 ) { return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0; }
-	return (T *)bsearch( &key, arr, dim, sizeof(T), comp );
+forall( otype E | { int ?<?( E, E ); } )
+E * bsearch( E key, const E * arr, size_t dim ) {
+	int comp( const void * t1, const void * t2 ) { return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0; }
+	return (E *)bsearch( &key, arr, dim, sizeof(E), comp );
 } // bsearch
 
-forall( otype T | { int ?<?( T, T ); } )
-unsigned int bsearch( T key, const T * arr, size_t dim ) {
-	T * result = bsearch( key, arr, dim );
-	return result ? result - arr : dim;					// pointer subtraction includes sizeof(T)
+forall( otype E | { int ?<?( E, E ); } )
+unsigned int bsearch( E key, const E * arr, size_t dim ) {
+	E * result = bsearch( key, arr, dim );
+	return result ? result - arr : dim;					// pointer subtraction includes sizeof(E)
 } // bsearch
 
-forall( otype T | { int ?<?( T, T ); } )
-void qsort( const T * arr, size_t dim ) {
-	int comp( const void * t1, const void * t2 ) { return *(T *)t1 < *(T *)t2 ? -1 : *(T *)t2 < *(T *)t1 ? 1 : 0; }
-	qsort( arr, dim, sizeof(T), comp );
+forall( otype K, otype E | { int ?<?( K, K ); K getKey( E & ); } )
+E * bsearch( K key, const E * arr, size_t dim ) {
+	int comp( const void * t1, const void * t2 ) { return *(K *)t1 < getKey( *(E *)t2 ) ? -1 : getKey( *(E *)t2 ) < *(K *)t1 ? 1 : 0; }
+	return (E *)bsearch( &key, arr, dim, sizeof(E), comp );
+} // bsearch
+
+forall( otype K, otype E | { int ?<?( K, K ); K getKey( E & ); } )
+unsigned int bsearch( K key, const E * arr, size_t dim ) {
+	E * result = bsearch( key, arr, dim );
+	return result ? result - arr : dim;					// pointer subtraction includes sizeof(E)
+} // bsearch
+
+forall( otype E | { int ?<?( E, E ); } )
+void qsort( E * arr, size_t dim ) {
+	int comp( const void * t1, const void * t2 ) { return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0; }
+	qsort( arr, dim, sizeof(E), comp );
 } // qsort
 
Index: src/tests/.expect/searchsort.txt
===================================================================
--- src/tests/.expect/searchsort.txt	(revision e672372dcffd6ac8335882a71d5b294e036bda92)
+++ src/tests/.expect/searchsort.txt	(revision 9c47a4703e167be1d751e6ac55951251b078e14c)
@@ -2,21 +2,25 @@
 
 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
-10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 
-10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 
-10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 
+10:10, 9:9, 8:8, 7:7, 6:6, 5:5, 4:4, 3:3, 2:2, 1:1, 
+10:10, 9:9, 8:8, 7:7, 6:6, 5:5, 4:4, 3:3, 2:2, 1:1, 
+10:10, 9:9, 8:8, 7:7, 6:6, 5:5, 4:4, 3:3, 2:2, 1:1, 
 
 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 
-10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 
-10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 
+10:10, 9:9, 8:8, 7:7, 6:6, 5:5, 4:4, 3:3, 2:2, 1:1, 
+10:10, 9:9, 8:8, 7:7, 6:6, 5:5, 4:4, 3:3, 2:2, 1:1, 
 
 10.5, 9.5, 8.5, 7.5, 6.5, 5.5, 4.5, 3.5, 2.5, 1.5, 
 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 
-10.5, 9.5, 8.5, 7.5, 6.5, 5.5, 4.5, 3.5, 2.5, 1.5, 
-10.5, 9.5, 8.5, 7.5, 6.5, 5.5, 4.5, 3.5, 2.5, 1.5, 
+10.5:10.5, 9.5:9.5, 8.5:8.5, 7.5:7.5, 6.5:6.5, 5.5:5.5, 4.5:4.5, 3.5:3.5, 2.5:2.5, 1.5:1.5, 
+10.5:10.5, 9.5:9.5, 8.5:8.5, 7.5:7.5, 6.5:6.5, 5.5:5.5, 4.5:4.5, 3.5:3.5, 2.5:2.5, 1.5:1.5, 
 
 10 11, 9 10, 8 9, 7 8, 6 7, 5 6, 4 5, 3 4, 2 3, 1 2, 
 1 2, 2 3, 3 4, 4 5, 5 6, 6 7, 7 8, 8 9, 9 10, 10 11, 
-10 11, 9 10, 8 9, 7 8, 6 7, 5 6, 4 5, 3 4, 2 3, 1 2, 
-10 11, 9 10, 8 9, 7 8, 6 7, 5 6, 4 5, 3 4, 2 3, 1 2, 
+10 11:10 11, 9 10:9 10, 8 9:8 9, 7 8:7 8, 6 7:6 7, 5 6:5 6, 4 5:4 5, 3 4:3 4, 2 3:2 3, 1 2:1 2, 
+10 11:10 11, 9 10:9 10, 8 9:8 9, 7 8:7 8, 6 7:6 7, 5 6:5 6, 4 5:4 5, 3 4:3 4, 2 3:2 3, 1 2:1 2, 
 
+1 2, 2 3, 3 4, 4 5, 5 6, 6 7, 7 8, 8 9, 9 10, 10 11, 
+11:10 11, 10:9 10, 9:8 9, 8:7 8, 7:6 7, 6:5 6, 5:4 5, 4:3 4, 3:2 3, 2:1 2, 
+11:10 11, 10:9 10, 9:8 9, 8:7 8, 7:6 7, 6:5 6, 5:4 5, 4:3 4, 3:2 3, 2:1 2, 
+
Index: src/tests/searchsort.c
===================================================================
--- src/tests/searchsort.c	(revision e672372dcffd6ac8335882a71d5b294e036bda92)
+++ src/tests/searchsort.c	(revision 9c47a4703e167be1d751e6ac55951251b078e14c)
@@ -10,6 +10,6 @@
 // Created On       : Thu Feb  4 18:17:50 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Dec  7 09:14:06 2017
-// Update Count     : 77
+// Last Modified On : Thu Dec 28 18:48:10 2017
+// Update Count     : 99
 // 
 
@@ -38,16 +38,17 @@
 	for ( unsigned int i = 0; i < size; i += 1 ) {		// C version
 		int key = size - i;
-		int *v = bsearch( &key, iarr, size, sizeof( iarr[0] ), comp );
-		sout | *v | ", ";
+		int * v = bsearch( &key, iarr, size, sizeof( iarr[0] ), comp );
+		sout | key | ':' | *v | ", ";
 	} // for
 	sout | endl;
+
 	for ( unsigned int i = 0; i < size; i += 1 ) {
-		int *v = bsearch( size - i, iarr, size );
-		sout | *v | ", ";
+		int * v = bsearch( size - i, iarr, size );
+		sout | size - i | ':' | *v | ", ";
 	} // for
 	sout | endl;
 	for ( unsigned int i = 0; i < size; i += 1 ) {
 		unsigned int posn = bsearch( size - i, iarr, size );
-		sout | iarr[posn] | ", ";
+		sout | size - i | ':' | iarr[posn] | ", ";
 	} // for
 	sout | endl | endl;
@@ -67,11 +68,11 @@
 		sout | endl;
 		for ( unsigned int i = 0; i < size; i += 1 ) {
-			int *v = bsearch( size - i, iarr, size );
-			sout | *v | ", ";
+			int * v = bsearch( size - i, iarr, size );
+			sout | size - i | ':' | *v | ", ";
 		} // for
 		sout | endl;
 		for ( unsigned int i = 0; i < size; i += 1 ) {
 			unsigned int posn = bsearch( size - i, iarr, size );
-			sout | iarr[posn] | ", ";
+			sout | size - i | ':' | iarr[posn] | ", ";
 		} // for
 	}
@@ -90,11 +91,11 @@
 	sout | endl;
 	for ( unsigned int i = 0; i < size; i += 1 ) {
-		double *v = bsearch( size - i + 0.5, darr, size );
-		sout | *v | ", ";
+		double * v = bsearch( size - i + 0.5, darr, size );
+		sout | size - i + 0.5 | ':' | *v | ", ";
 	} // for
 	sout | endl;
 	for ( unsigned int i = 0; i < size; i += 1 ) {
 		unsigned int posn = bsearch( size - i + 0.5, darr, size );
-		sout | darr[posn] | ", ";
+		sout | size - i + 0.5 | ':' | darr[posn] | ", ";
 	} // for
 	sout | endl | endl;
@@ -116,6 +117,6 @@
 	for ( unsigned int i = 0; i < size; i += 1 ) {
 		S temp = { size - i, size - i + 1 };
-		S *v = bsearch( temp, sarr, size );
-		sout | *v | ", ";
+		S * v = bsearch( temp, sarr, size );
+		sout | temp | ':' | *v | ", ";
 	} // for
 	sout | endl;
@@ -123,7 +124,24 @@
 		S temp = { size - i, size - i + 1 };
 		unsigned int posn = bsearch( temp, sarr, size );
-		sout | sarr[posn] | ", ";
+		sout | temp | ':' | sarr[posn] | ", ";
 	} // for
 	sout | endl | endl;
+	{
+		unsigned int getKey( S & s ) { return s.j; }
+		for ( unsigned int i = 0; i < size; i += 1 ) {
+			sout | sarr[i] | ", ";
+		} // for
+		sout | endl;
+		for ( unsigned int i = 0; i < size; i += 1 ) {
+			S * v = bsearch( size - i + 1, sarr, size );
+			sout | size - i + 1 | ':' | *v | ", ";
+		} // for
+		sout | endl;
+		for ( unsigned int i = 0; i < size; i += 1 ) {
+			unsigned int posn = bsearch( size - i + 1, sarr, size );
+			sout | size - i + 1 | ':' | sarr[posn] | ", ";
+		} // for
+		sout | endl | endl;
+	}
 } // main
 
