Index: src/libcfa/iostream.c
===================================================================
--- src/libcfa/iostream.c	(revision b6dc097803496f54ca0749c8149c4191a0113485)
+++ src/libcfa/iostream.c	(revision 28f3a190cabb48116467ce6e1ebc74a38dac95b7)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Apr 28 13:08:25 2018
-// Update Count     : 469
+// Last Modified On : Sat Jun  2 08:24:56 2018
+// Update Count     : 471
 //
 
@@ -26,200 +26,223 @@
 }
 
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, _Bool b ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%s", b ? "true" : "false" );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, char ch ) {
-	fmt( os, "%c", ch );
-	if ( ch == '\n' ) setNL( os, true );
-	sepOff( os );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, signed char c ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%hhd", c );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, unsigned char c ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%hhu", c );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, short int si ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%hd", si );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, unsigned short int usi ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%hu", usi );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, int i ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%d", i );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, unsigned int ui ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%u", ui );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, long int li ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%ld", li );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, unsigned long int uli ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%lu", uli );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, long long int lli ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%lld", lli );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, unsigned long long int ulli ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%llu", ulli );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, float f ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%g", f );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, double d ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%.*lg", DBL_DIG, d );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, long double ld ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%.*Lg", LDBL_DIG, ld );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, float _Complex fc ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%g%+gi", crealf( fc ), cimagf( fc ) );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, double _Complex dc ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%.*lg%+.*lgi", DBL_DIG, creal( dc ), DBL_DIG, cimag( dc ) );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, long double _Complex ldc ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%.*Lg%+.*Lgi", LDBL_DIG, creall( ldc ), LDBL_DIG, cimagl( ldc ) );
-	return os;
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, const char * str ) {
-	enum { Open = 1, Close, OpenClose };
-	static const unsigned char mask[256] @= {
-		// opening delimiters, no space after
-		['('] : Open, ['['] : Open, ['{'] : Open,
-		['='] : Open, ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open,
-		[(unsigned char)'¡'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
-		// closing delimiters, no space before
-		[','] : Close, ['.'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close,
-		['%'] : Close, [(unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close,
-		[')'] : Close, [']'] : Close, ['}'] : Close,
-		// opening-closing delimiters, no space before or after
-		['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose, [':'] : OpenClose,
-		[' '] : OpenClose, ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
-	}; // mask
-
-  if ( str[0] == '\0' ) { sepOff( os ); return os; }		// null string => no separator
-
-	// first character IS NOT spacing or closing punctuation => add left separator
-	unsigned char ch = str[0];							// must make unsigned
-	if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
-		fmt( os, "%s", sepGetCur( os ) );
-	} // if
-
-	// if string starts line, must reset to determine open state because separator is off
-	sepReset( os );										// reset separator
-
-	// last character IS spacing or opening punctuation => turn off separator for next item
-	size_t len = strlen( str );
-	ch = str[len - 1];									// must make unsigned
-	if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
+forall( dtype ostype | ostream( ostype ) ) {
+	ostype & ?|?( ostype & os, _Bool b ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%s", b ? "true" : "false" );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, char ch ) {
+		fmt( os, "%c", ch );
+		if ( ch == '\n' ) setNL( os, true );
+		sepOff( os );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, signed char c ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%hhd", c );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, unsigned char c ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%hhu", c );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, short int si ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%hd", si );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, unsigned short int usi ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%hu", usi );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, int i ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%d", i );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, unsigned int ui ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%u", ui );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, long int li ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%ld", li );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, unsigned long int uli ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%lu", uli );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, long long int lli ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%lld", lli );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, unsigned long long int ulli ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%llu", ulli );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, float f ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%g", f );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, double d ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%.*lg", DBL_DIG, d );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, long double ld ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%.*Lg", LDBL_DIG, ld );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, float _Complex fc ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%g%+gi", crealf( fc ), cimagf( fc ) );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, double _Complex dc ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%.*lg%+.*lgi", DBL_DIG, creal( dc ), DBL_DIG, cimag( dc ) );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, long double _Complex ldc ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%.*Lg%+.*Lgi", LDBL_DIG, creall( ldc ), LDBL_DIG, cimagl( ldc ) );
+		return os;
+	} // ?|?
+
+	ostype & ?|?( ostype & os, const char * str ) {
+		enum { Open = 1, Close, OpenClose };
+		static const unsigned char mask[256] @= {
+			// opening delimiters, no space after
+			['('] : Open, ['['] : Open, ['{'] : Open,
+			['='] : Open, ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open,
+			[(unsigned char)'¡'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
+			// closing delimiters, no space before
+			[','] : Close, ['.'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close,
+			['%'] : Close, [(unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close,
+			[')'] : Close, [']'] : Close, ['}'] : Close,
+			// opening-closing delimiters, no space before or after
+			['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose, [':'] : OpenClose,
+			[' '] : OpenClose, ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
+		}; // mask
+
+	  if ( str[0] == '\0' ) { sepOff( os ); return os; } // null string => no separator
+
+		// first character IS NOT spacing or closing punctuation => add left separator
+		unsigned char ch = str[0];						// must make unsigned
+		if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
+			fmt( os, "%s", sepGetCur( os ) );
+		} // if
+
+		// if string starts line, must reset to determine open state because separator is off
+		sepReset( os );									// reset separator
+
+		// last character IS spacing or opening punctuation => turn off separator for next item
+		size_t len = strlen( str );
+		ch = str[len - 1];								// must make unsigned
+		if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
+			sepOn( os );
+		} else {
+			sepOff( os );
+		} // if
+		if ( ch == '\n' ) setNL( os, true );			// check *AFTER* sepPrt call above as it resets NL flag
+		return write( os, str, len );
+	} // ?|?
+
+// 	ostype & ?|?( ostype & os, const char16_t * str ) {
+// 		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+// 		fmt( os, "%ls", str );
+// 		return os;
+// 	} // ?|?
+
+// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
+// 	ostype & ?|?( ostype & os, const char32_t * str ) {
+// 		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+// 		fmt( os, "%ls", str );
+// 		return os;
+// 	} // ?|?
+// #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
+
+// 	ostype & ?|?( ostype & os, const wchar_t * str ) {
+// 		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+// 		fmt( os, "%ls", str );
+// 		return os;
+// 	} // ?|?
+
+	ostype & ?|?( ostype & os, const void * p ) {
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+		fmt( os, "%p", p );
+		return os;
+	} // ?|?
+
+
+	// manipulators
+	ostype & ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
+		return manip( os );
+	} // ?|?
+
+	ostype & sep( ostype & os ) {
+		os | sepGet( os );
+		return os;
+	} // sep
+
+	ostype & sepTuple( ostype & os ) {
+		os | sepGetTuple( os );
+		return os;
+	} // sepTuple
+
+	ostype & endl( ostype & os ) {
+		os | '\n';
+		setNL( os, true );
+		flush( os );
+		sepOff( os );									// prepare for next line
+		return os;
+	} // endl
+
+	ostype & sepOn( ostype & os ) {
 		sepOn( os );
-	} else {
+		return os;
+	} // sepOn
+
+	ostype & sepOff( ostype & os ) {
 		sepOff( os );
-	} // if
-	if ( ch == '\n' ) setNL( os, true );				// check *AFTER* sepPrt call above as it resets NL flag
-	return write( os, str, len );
-} // ?|?
-
-// forall( dtype ostype | ostream( ostype ) )
-// ostype & ?|?( ostype & os, const char16_t * str ) {
-// 	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-// 	fmt( os, "%ls", str );
-// 	return os;
-// } // ?|?
-
-// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
-// forall( dtype ostype | ostream( ostype ) )
-// ostype & ?|?( ostype & os, const char32_t * str ) {
-// 	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-// 	fmt( os, "%ls", str );
-// 	return os;
-// } // ?|?
-// #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
-
-// forall( dtype ostype | ostream( ostype ) )
-// ostype & ?|?( ostype & os, const wchar_t * str ) {
-// 	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-// 	fmt( os, "%ls", str );
-// 	return os;
-// } // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, const void * p ) {
-	if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
-	fmt( os, "%p", p );
-	return os;
-} // ?|?
+		return os;
+	} // sepOff
+
+	ostype & sepEnable( ostype & os ) {
+		sepEnable( os );
+		return os;
+	} // sepEnable
+
+	ostype & sepDisable( ostype & os ) {
+		sepDisable( os );
+		return os;
+	} // sepDisable
+} // distribution
 
 
@@ -234,58 +257,7 @@
 } // ?|?
 
-
-// manipulators
-forall( dtype ostype | ostream( ostype ) )
-ostype & ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
-	return manip( os );
-} // ?|?
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & sep( ostype & os ) {
-	os | sepGet( os );
-	return os;
-} // sep
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & sepTuple( ostype & os ) {
-	os | sepGetTuple( os );
-	return os;
-} // sepTuple
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & endl( ostype & os ) {
-	os | '\n';
-	setNL( os, true );
-	flush( os );
-	sepOff( os );										// prepare for next line
-	return os;
-} // endl
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & sepOn( ostype & os ) {
-	sepOn( os );
-	return os;
-} // sepOn
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & sepOff( ostype & os ) {
-	sepOff( os );
-	return os;
-} // sepOff
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & sepEnable( ostype & os ) {
-	sepEnable( os );
-	return os;
-} // sepEnable
-
-forall( dtype ostype | ostream( ostype ) )
-ostype & sepDisable( ostype & os ) {
-	sepDisable( os );
-	return os;
-} // sepDisable
-
 //---------------------------------------
 
+// writes the range [begin, end) to the given stream
 forall( dtype ostype, otype elt_type | writeable( elt_type, ostype ), otype iterator_type | iterator( iterator_type, elt_type ) )
 void write( iterator_type begin, iterator_type end, ostype & os ) {
@@ -302,137 +274,121 @@
 //---------------------------------------
 
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, _Bool & b ) {
-	char val[6];
-	fmt( is, "%5s", val );
-	if ( strcmp( val, "true" ) == 0 ) b = true;
-	else if ( strcmp( val, "false" ) == 0 ) b = false;
-	else {
-		fprintf( stderr, "invalid _Bool constant\n" );
-		abort();
-	} // if
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, char & c ) {
-	fmt( is, "%c", &c );								// must pass pointer through varg to fmt
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, signed char & sc ) {
-	fmt( is, "%hhd", &sc );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, unsigned char & usc ) {
-	fmt( is, "%hhu", &usc );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, short int & si ) {
-	fmt( is, "%hd", &si );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, unsigned short int & usi ) {
-	fmt( is, "%hu", &usi );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, int & i ) {
-	fmt( is, "%d", &i );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, unsigned int & ui ) {
-	fmt( is, "%u", &ui );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, long int & li ) {
-	fmt( is, "%ld", &li );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, unsigned long int & ulli ) {
-	fmt( is, "%lu", &ulli );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, long long int & lli ) {
-	fmt( is, "%lld", &lli );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, unsigned long long int & ulli ) {
-	fmt( is, "%llu", &ulli );
-	return is;
-} // ?|?
-
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, float & f ) {
-	fmt( is, "%f", &f );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, double & d ) {
-	fmt( is, "%lf", &d );
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, long double & ld ) {
-	fmt( is, "%Lf", &ld );
-	return is;
-} // ?|?
-
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, float _Complex & fc ) {
-	float re, im;
-	fmt( is, "%g%gi", &re, &im );
-	fc = re + im * _Complex_I;
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, double _Complex & dc ) {
-	double re, im;
-	fmt( is, "%lf%lfi", &re, &im );
-	dc = re + im * _Complex_I;
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, long double _Complex & ldc ) {
-	long double re, im;
-	fmt( is, "%Lf%Lfi", &re, &im );
-	ldc = re + im * _Complex_I;
-	return is;
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & ?|?( istype & is, istype & (* manip)( istype & ) ) {
-	return manip( is );
-} // ?|?
-
-forall( dtype istype | istream( istype ) )
-istype & endl( istype & is ) {
-	fmt( is, "%*[ \t\f\n\r\v]" );						// ignore whitespace
-	return is;
-} // endl
+forall( dtype istype | istream( istype ) ) {
+	istype & ?|?( istype & is, _Bool & b ) {
+		char val[6];
+		fmt( is, "%5s", val );
+		if ( strcmp( val, "true" ) == 0 ) b = true;
+		else if ( strcmp( val, "false" ) == 0 ) b = false;
+		else {
+			fprintf( stderr, "invalid _Bool constant\n" );
+			abort();
+		} // if
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, char & c ) {
+		fmt( is, "%c", &c );							// must pass pointer through varg to fmt
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, signed char & sc ) {
+		fmt( is, "%hhd", &sc );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, unsigned char & usc ) {
+		fmt( is, "%hhu", &usc );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, short int & si ) {
+		fmt( is, "%hd", &si );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, unsigned short int & usi ) {
+		fmt( is, "%hu", &usi );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, int & i ) {
+		fmt( is, "%d", &i );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, unsigned int & ui ) {
+		fmt( is, "%u", &ui );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, long int & li ) {
+		fmt( is, "%ld", &li );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, unsigned long int & ulli ) {
+		fmt( is, "%lu", &ulli );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, long long int & lli ) {
+		fmt( is, "%lld", &lli );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, unsigned long long int & ulli ) {
+		fmt( is, "%llu", &ulli );
+		return is;
+	} // ?|?
+
+
+	istype & ?|?( istype & is, float & f ) {
+		fmt( is, "%f", &f );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, double & d ) {
+		fmt( is, "%lf", &d );
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, long double & ld ) {
+		fmt( is, "%Lf", &ld );
+		return is;
+	} // ?|?
+
+
+	istype & ?|?( istype & is, float _Complex & fc ) {
+		float re, im;
+		fmt( is, "%g%gi", &re, &im );
+		fc = re + im * _Complex_I;
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, double _Complex & dc ) {
+		double re, im;
+		fmt( is, "%lf%lfi", &re, &im );
+		dc = re + im * _Complex_I;
+		return is;
+	} // ?|?
+
+	istype & ?|?( istype & is, long double _Complex & ldc ) {
+		long double re, im;
+		fmt( is, "%Lf%Lfi", &re, &im );
+		ldc = re + im * _Complex_I;
+		return is;
+	} // ?|?
+
+
+	// manipulators
+	istype & ?|?( istype & is, istype & (* manip)( istype & ) ) {
+		return manip( is );
+	} // ?|?
+
+	istype & endl( istype & is ) {
+		fmt( is, "%*[ \t\f\n\r\v]" );					// ignore whitespace
+		return is;
+	} // endl
+} // distribution
 
 _Istream_cstrUC cstr( char * str ) { return (_Istream_cstrUC){ str }; }
