Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision e63326ba72611df5ee717d0f906ad9161aacd0eb)
+++ libcfa/src/iostream.cfa	(revision 67130fe7c6ae00bc7c6da280f8b700e5bc850a3c)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 21 13:01:26 2019
-// Update Count     : 674
+// Last Modified On : Tue Jun  4 17:32:34 2019
+// Update Count     : 761
 //
 
@@ -20,10 +20,12 @@
 #include <stdbool.h>									// true/false
 //#include <string.h>									// strlen, strcmp
+extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
 extern int strcmp (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
-extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
+extern char *strcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
+extern void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
 #include <float.h>										// DBL_DIG, LDBL_DIG
 #include <math.h>										// isfinite
 #include <complex.h>									// creal, cimag
-}
+} // extern "C"
 
 forall( dtype ostype | ostream( ostype ) ) {
@@ -198,8 +200,6 @@
 		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
 //		os | crealf( fc ) | nonl;
-		float f = crealf( fc );
-		PrintWithDP( os, "%g", f );
-		f = cimagf( fc );
-		PrintWithDP( os, "%+g", f );
+		PrintWithDP( os, "%g", crealf( fc ) );
+		PrintWithDP( os, "%+g", cimagf( fc ) );
 		fmt( os, "i" );
 		return os;
@@ -212,8 +212,6 @@
 		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
 //		os | creal( dc ) | nonl;
-		double d = creal( dc );
-		PrintWithDP( os, "%.*lg", d, DBL_DIG );
-		d = cimag( dc );
-		PrintWithDP( os, "%+.*lg", d, DBL_DIG );
+		PrintWithDP( os, "%.*lg", creal( dc ), DBL_DIG );
+		PrintWithDP( os, "%+.*lg", cimag( dc ), DBL_DIG );
 		fmt( os, "i" );
 		return os;
@@ -226,8 +224,6 @@
 		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
 //		os | creall( ldc ) || nonl;
-		long double ld = creall( ldc );
-		PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
-		ld = cimagl( ldc );
-		PrintWithDP( os, "%+.*Lg", ld, LDBL_DIG );
+		PrintWithDP( os, "%.*Lg", creall( ldc ), LDBL_DIG );
+		PrintWithDP( os, "%+.*Lg", cimagl( ldc ), LDBL_DIG );
 		fmt( os, "i" );
 		return os;
@@ -395,4 +391,219 @@
 } // distribution
 
+
+//*********************************** Integral ***********************************
+
+static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
+static const char * longbin[]  = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
+
+// Default prefix for non-decimal prints is 0b, 0, 0x.
+#define IntegralFMTImpl( T, CODE, IFMTNP, IFMTP ) \
+forall( dtype ostype | ostream( ostype ) ) { \
+	ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
+\
+		if ( f.base == 'b' || f.base == 'B' ) {			/* bespoke binary format */ \
+			int bits;													\
+			if ( f.val == (T){0} ) bits = 1;			/* force at least one bit to print */ \
+			else bits = sizeof(long long int) * 8 - __builtin_clzll( f.val ); /* position of most significant bit */ \
+			bits = bits > sizeof(f.val) * 8 ? sizeof(f.val) * 8 : bits; \
+			int spaces = f.wd - bits;					/* can be negative */ \
+			if ( ! f.flags.nobsdp ) { spaces -= 2; }	/* base prefix takes space */ \
+			/* printf( "%d %d\n", bits, spaces ); */ \
+			if ( ! f.flags.left ) {						/* right justified ? */ \
+				/* Note, base prefix then zero padding or spacing then prefix. */ \
+				if ( f.flags.pad0 || f.flags.pc ) { \
+					if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
+					if ( f.flags.pc ) spaces = f.pc - bits; \
+					if ( spaces > 0 ) fmt( os, "%0*d", spaces, 0 ); /* zero pad */ \
+				} else { \
+					if ( spaces > 0 ) fmt( os, "%*s", spaces, " " ); /* space pad */ \
+					if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
+				} /* if */ \
+			} else if ( ! f.flags.nobsdp ) { \
+				fmt( os, "0%c", f.base ); \
+			} /* if */ \
+			int shift = (bits - 1) / 4 * 4; /* floor( bits - 1, 4 ) */ \
+			typeof( f.val ) temp = f.val; \
+			fmt( os, "%s", shortbin[(temp >> shift) & 0xf] ); \
+			for () { \
+				shift -= 4; \
+			  if ( shift < 0 ) break; \
+				temp = f.val; \
+				fmt( os, "%s", longbin[(temp >> shift) & 0xf] ); \
+			} /* for */ \
+			if ( f.flags.left && spaces > 0 ) fmt( os, "%*s", spaces, " " ); \
+			return os; \
+		} /* if  */ \
+\
+		char fmtstr[sizeof(IFMTP)];						/* sizeof includes '\0' */ \
+		if ( ! f.flags.pc ) memcpy( &fmtstr, IFMTNP, sizeof(IFMTNP) ); \
+		else memcpy( &fmtstr, IFMTP, sizeof(IFMTP) ); \
+		int star = 4;									/* position before first '*' */ \
+\
+		/* Insert flags into spaces before '*', from right to left. */ \
+		if ( ! f.flags.nobsdp ) { fmtstr[star] = '#'; star -= 1; } \
+		if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
+		if ( f.flags.sign && f.base == CODE ) { fmtstr[star] = '+'; star -= 1; } \
+		if ( f.flags.pad0 && ! f.flags.pc ) { fmtstr[star] = '0'; star -= 1; } \
+		fmtstr[star] = '%'; \
+\
+		if ( ! f.flags.pc ) {							/* no precision */ \
+			/* printf( "%s\n", &fmtstr[star] ); */ \
+			fmtstr[sizeof(IFMTNP)-2] = f.base;			/* sizeof includes '\0' */ \
+			fmt( os, &fmtstr[star], f.wd, f.val ); \
+		} else {										/* precision */ \
+			fmtstr[sizeof(IFMTP)-2] = f.base;			/* sizeof includes '\0' */ \
+			/* printf( "%s\n", &fmtstr[star] ); */ \
+			fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
+		} /* if */ \
+		return os; \
+	} /* ?|? */ \
+	void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
+} // distribution
+
+IntegralFMTImpl( signed char, 'd', "%    *hh ", "%    *.*hh " )
+IntegralFMTImpl( unsigned char, 'u', "%    *hh ", "%    *.*hh " )
+IntegralFMTImpl( signed short int, 'd', "%    *h ", "%    *.*h " )
+IntegralFMTImpl( unsigned short int, 'u', "%    *h ", "%    *.*h " )
+IntegralFMTImpl( signed int, 'd', "%    * ", "%    *.* " )
+IntegralFMTImpl( unsigned int, 'u', "%    * ", "%    *.* " )
+IntegralFMTImpl( signed long int, 'd', "%    *l ", "%    *.*l " )
+IntegralFMTImpl( unsigned long int, 'u', "%    *l ", "%    *.*l " )
+IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
+IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
+
+//*********************************** Floating Point ***********************************
+
+#define PrintWithDP2( os, format, val, ... ) \
+	{ \
+		enum { size = 48 }; \
+		char buf[size]; \
+		int bufbeg = 0, i, len = snprintf( buf, size, format, ##__VA_ARGS__, val ); \
+		if ( isfinite( val ) && (f.base != 'g' || f.pc != 0) ) { /* if number, print decimal point */ \
+			for ( i = 0; i < len && buf[i] != '.' && buf[i] != 'e' && buf[i] != 'E'; i += 1 ); /* decimal point or scientific ? */ \
+			if ( i == len && ! f.flags.nobsdp ) { \
+				if ( ! f.flags.left ) { \
+					buf[i] = '.'; buf[i + 1] = '\0'; \
+					if ( buf[0] == ' ' ) bufbeg = 1; /* decimal point within width */ \
+				} else { \
+					for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
+					buf[i] = '.'; \
+					if ( i == len ) buf[i + 1] = '\0'; \
+				} /* if */ \
+			} /* if */ \
+		} /* if */ \
+		fmt( os, "%s", &buf[bufbeg] ); \
+	}
+
+#define FloatingPointFMTImpl( T, DFMTNP, DFMTP ) \
+forall( dtype ostype | ostream( ostype ) ) { \
+	ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
+		char fmtstr[sizeof(DFMTP)];						/* sizeof includes '\0' */ \
+		if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
+		else memcpy( &fmtstr, DFMTP, sizeof(DFMTP) ); \
+		int star = 4;									/* position before first '*' */ \
+\
+		/* Insert flags into spaces before '*', from right to left. */ \
+		if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
+		if ( f.flags.sign ) { fmtstr[star] = '+'; star -= 1; } \
+		if ( f.flags.pad0 ) { fmtstr[star] = '0'; star -= 1; } \
+		fmtstr[star] = '%'; \
+\
+		if ( ! f.flags.pc ) {							/* no precision */ \
+			fmtstr[sizeof(DFMTNP)-2] = f.base;			/* sizeof includes '\0' */ \
+			/* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star]); */ \
+			PrintWithDP2( os, &fmtstr[star], f.val, f.wd ) \
+		} else {										/* precision */ \
+			fmtstr[sizeof(DFMTP)-2] = f.base;			/* sizeof includes '\0' */ \
+			/* printf( "%g %d %d %s\n", f.val, f.wd, f.pc, &fmtstr[star] ); */ \
+			PrintWithDP2( os, &fmtstr[star], f.val, f.wd, f.pc ) \
+		} /* if */ \
+		return os; \
+	} /* ?|? */ \
+	void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
+} // distribution
+
+FloatingPointFMTImpl( double, "%    * ", "%    *.* " )
+FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
+
+//*********************************** Character ***********************************
+
+forall( dtype ostype | ostream( ostype ) ) {
+	ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) {
+		if ( f.base != 'c' ) {								// bespoke binary/octal/hex format
+			_Ostream_Manip(unsigned char) fmtuc @= { f.val, f.wd, f.pc, f.base, {'\0'} };
+			fmtuc.flags.pc = f.flags.pc;
+			fmtuc.flags.nobsdp = f.flags.nobsdp;
+//			os | fmtuc | nonl;
+			(ostype &)(os | fmtuc);
+			return os;
+		} // if
+
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+
+		#define CFMTNP "% * "
+		char fmtstr[sizeof(CFMTNP)];						// sizeof includes '\0'
+		memcpy( &fmtstr, CFMTNP, sizeof(CFMTNP) );
+		int star = 1;										// position before first '*'
+
+		// Insert flags into spaces before '*', from right to left.
+		if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; }
+		fmtstr[star] = '%';
+
+		fmtstr[sizeof(CFMTNP)-2] = f.base;					// sizeof includes '\0'
+		// printf( "%d %s\n", f.wd, &fmtstr[star] );
+		fmt( os, &fmtstr[star], f.wd, f.val );
+		return os;
+	} // ?|?
+	void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); nl( os ); }
+} // distribution
+
+//*********************************** C String ***********************************
+
+forall( dtype ostype | ostream( ostype ) ) {
+	ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ) {
+		if ( ! f.val ) return os;						// null pointer ?
+
+		if ( f.base != 's' ) {							// bespoke binary/octal/hex format
+			_Ostream_Manip(unsigned char) fmtuc @= { 0, f.wd, f.pc, f.base, {'\0'} };
+			fmtuc.flags.pc = f.flags.pc;
+			fmtuc.flags.nobsdp = f.flags.nobsdp;
+			for ( unsigned int i = 0; f.val[i] != '\0'; i += 1 ) {
+				fmtuc.val = f.val[i];
+//				os | fmtuc | nonl;
+				(ostype &)(os | fmtuc);
+			} // for
+			return os;
+		} // if
+
+		if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
+
+		#define SFMTNP "% * "
+		#define SFMTP "% *.* "
+		char fmtstr[sizeof(SFMTP)];						// sizeof includes '\0'
+		if ( ! f.flags.pc ) memcpy( &fmtstr, SFMTNP, sizeof(SFMTNP) );
+		else memcpy( &fmtstr, SFMTP, sizeof(SFMTP) );
+		int star = 1;									// position before first '*'
+
+		// Insert flags into spaces before '*', from right to left.
+		if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; }
+		fmtstr[star] = '%';
+
+		if ( ! f.flags.pc ) {							// no precision
+			// printf( "%d %s\n", f.wd, &fmtstr[star] );
+			fmtstr[sizeof(SFMTNP)-2] = f.base;			// sizeof includes '\0'
+			fmt( os, &fmtstr[star], f.wd, f.val );
+		} else {										// precision
+			fmtstr[sizeof(SFMTP)-2] = f.base;			// sizeof includes '\0'
+			// printf( "%d %d %s\n", f.wd, f.pc, &fmtstr[star] );
+			fmt( os, &fmtstr[star], f.wd, f.pc, f.val );
+		} // if
+		return os;
+	} // ?|?
+	void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); nl( os ); }
+} // distribution
+
 //---------------------------------------
 
@@ -410,5 +621,7 @@
 } // distribution
 
-//---------------------------------------
+
+//*********************************** Istream ***********************************
+
 
 forall( dtype istype | istream( istype ) ) {
@@ -437,50 +650,50 @@
 
 	istype & ?|?( istype & is, signed char & sc ) {
-		fmt( is, "%hhd", &sc );
+		fmt( is, "%hhi", &sc );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, unsigned char & usc ) {
-		fmt( is, "%hhu", &usc );
+		fmt( is, "%hhi", &usc );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, short int & si ) {
-		fmt( is, "%hd", &si );
+		fmt( is, "%hi", &si );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, unsigned short int & usi ) {
-		fmt( is, "%hu", &usi );
+		fmt( is, "%hi", &usi );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, int & i ) {
-		fmt( is, "%d", &i );
+		fmt( is, "%i", &i );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, unsigned int & ui ) {
-		fmt( is, "%u", &ui );
+		fmt( is, "%i", &ui );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, long int & li ) {
-		fmt( is, "%ld", &li );
+		fmt( is, "%li", &li );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, unsigned long int & ulli ) {
-		fmt( is, "%lu", &ulli );
+		fmt( is, "%li", &ulli );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, long long int & lli ) {
-		fmt( is, "%lld", &lli );
+		fmt( is, "%lli", &lli );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, unsigned long long int & ulli ) {
-		fmt( is, "%llu", &ulli );
+		fmt( is, "%lli", &ulli );
 		return is;
 	} // ?|?
@@ -505,5 +718,5 @@
 	istype & ?|?( istype & is, float _Complex & fc ) {
 		float re, im;
-		fmt( is, "%g%gi", &re, &im );
+		fmt( is, "%f%fi", &re, &im );
 		fc = re + im * _Complex_I;
 		return is;
@@ -561,4 +774,91 @@
 } // cstr
 
+#if 0
+forall( dtype istype | istream( istype ) )
+istype & ?|?( istype & is, _Istream_skip skip ) {
+	fmt( is, skip.s, "" );								// no input arguments
+	return is;
+} // skip
+
+forall( dtype istype | istream( istype ) )
+istype & ?|?( istype & is, _Istream_incl incl ) {
+	size_t len = strlen( incl.scanset ) + 4;			// extras: "%[]\0"
+	char fmtstr[len];
+	fmtstr[0] = '%'; fmtstr[1] = '[';
+	strcpy( &fmtstr[2], incl.scanset );					// after '[', copy includes '\0'
+	fmtstr[len - 2] = ']'; fmtstr[len - 1] = '\0';
+	fmt( is, fmtstr, incl.s );
+	return is;
+} // incl
+
+forall( dtype istype | istream( istype ) )
+istype & ?|?( istype & is, _Istream_excl excl ) {
+	size_t len = strlen( excl.scanset );
+	char fmtstr[len+5];
+	fmtstr[0] = '%'; fmtstr[1] = '['; fmtstr[2] = '^';
+	strcpy( &fmtstr[3], excl.scanset );					// after '^', copy includes '\0'
+	fmtstr[len - 2] = ']'; fmtstr[len - 1] = '\0';
+	fmt( is, fmtstr, excl.s );
+	return is;
+} // excl
+
+forall( dtype istype | istream( istype ) )
+istype & ?|?( istype & is, _Istream_cstr cstr ) {
+	fmt( is, "%s", cstr.s );
+	return is;
+} // cstr
+
+_Istream_cstrW cstr( char * s, int size ) { return (_Istream_cstrW){ s, size }; }
+forall( dtype istype | istream( istype ) )
+istype & ?|?( istype & is, _Istream_cstrW cstr ) {
+	enum { size = 16 };
+	char fmtstr[size];
+	sprintf( fmtstr, "%%%ds", cstr.size );
+	fmt( is, fmtstr, cstr.s );
+	return is;
+} // cstr
+
+forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_Cstr ) {
+	
+}
+
+//*********************************** Manipulators ***********************************
+
+#define InputFMTImpl( T, CODE ) \
+forall( dtype istype | istream( istype ) ) \
+istype & ?|?( istype & is, _Istream_Manip(T) f ) { \
+	enum { size = 16 }; \
+	char fmtstr[size]; \
+	if ( f.wd == -1 ) { \
+		snprintf( fmtstr, size, "%%%s%s", f.ignore ? "*" : "", CODE ); \
+	} else { \
+		snprintf( fmtstr, size, "%%%s%d%s", f.ignore ? "*" : "", f.wd, CODE ); \
+	} /* if */ \
+	/* printf( "%d %s %p\n", f.wd, fmtstr, &f.val ); */ \
+	fmt( is, fmtstr, &f.val ); \
+	return is; \
+} /* ?|? */
+
+InputFMTImpl( char, "c" )
+InputFMTImpl( signed char, "hhi" )
+InputFMTImpl( unsigned char, "hhi" )
+InputFMTImpl( signed short int, "hi" )
+InputFMTImpl( unsigned short int, "hi" )
+InputFMTImpl( signed int, "i" )
+InputFMTImpl( unsigned int, "i" )
+InputFMTImpl( signed long int, "li" )
+InputFMTImpl( unsigned long int, "li" )
+InputFMTImpl( signed long long int, "lli" )
+InputFMTImpl( unsigned long long int, "lli" )
+
+InputFMTImpl( float, "f" )
+InputFMTImpl( double, "lf" )
+InputFMTImpl( long double, "Lf" )
+
+InputFMTImpl( float _Complex, "ff" )
+InputFMTImpl( double _Complex, "lf" )
+InputFMTImpl( long double _Complex, "Lf" )
+#endif // 0
+
 // Local Variables: //
 // tab-width: 4 //
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision e63326ba72611df5ee717d0f906ad9161aacd0eb)
+++ libcfa/src/iostream.hfa	(revision 67130fe7c6ae00bc7c6da280f8b700e5bc850a3c)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// iostream --
+// iostream.hfa --
 //
 // Author           : Peter A. Buhr
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat May 11 10:31:27 2019
-// Update Count     : 232
+// Last Modified On : Tue Jun  4 17:33:43 2019
+// Update Count     : 286
 //
 
@@ -17,4 +17,8 @@
 
 #include "iterator.hfa"
+
+
+//*********************************** Ostream ***********************************
+
 
 trait ostream( dtype ostype ) {
@@ -146,5 +150,124 @@
 } // distribution
 
-//---------------------------------------
+//*********************************** Manipulators ***********************************
+
+forall( otype T )
+struct _Ostream_Manip {
+	T val;												// polymorphic base-type
+	unsigned char wd, pc;								// width, precision
+	char base;											// numeric base / floating-point style
+	union {
+		unsigned char all;
+		struct {
+			unsigned char pc:1;							// precision specified
+			unsigned char left:1;						// left justify
+			unsigned char nobsdp:1;						// base prefix / decimal point
+			unsigned char sign:1;						// plus / minus sign
+			unsigned char pad0:1;						// zero pad
+		} flags;
+	};
+}; // _Ostream_Manip
+
+//*********************************** Integral ***********************************
+
+#define IntegralFMTDecl( T, CODE ) \
+static inline { \
+	_Ostream_Manip(T) bin( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'b', { .all : 0 } }; } \
+	_Ostream_Manip(T) oct( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'o', { .all : 0 } }; } \
+	_Ostream_Manip(T) hex( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'x', { .all : 0 } }; } \
+	_Ostream_Manip(T) wd( unsigned char w, T v ) { return (_Ostream_Manip(T))@{ v, w, 0, CODE, { .all : 0 } }; } \
+	_Ostream_Manip(T) wd( unsigned char w, unsigned char p, T v ) { return (_Ostream_Manip(T))@{ v, w, p, CODE, { .flags.pc : true } }; } \
+	_Ostream_Manip(T) & wd( unsigned char w, _Ostream_Manip(T) & fmt ) with(fmt) { wd = w; return fmt; } \
+	_Ostream_Manip(T) & wd( unsigned char w, unsigned char p, _Ostream_Manip(T) & fmt ) with(fmt) { wd = w; pc = p; flags.pc = true; return fmt; } \
+	_Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \
+	_Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; } \
+	_Ostream_Manip(T) & nobase( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \
+	_Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \
+	_Ostream_Manip(T) sign( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, CODE, { .flags.sign : true } }; } \
+	_Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \
+} \
+forall( dtype ostype | ostream( ostype ) ) { \
+	ostype & ?|?( ostype & os, _Ostream_Manip(T) f ); \
+	void ?|?( ostype & os, _Ostream_Manip(T) f ); \
+}
+
+IntegralFMTDecl( signed char, 'd' )
+IntegralFMTDecl( unsigned char, 'u' )
+IntegralFMTDecl( signed short int, 'd' )
+IntegralFMTDecl( unsigned short int, 'u' )
+IntegralFMTDecl( signed int, 'd' )
+IntegralFMTDecl( unsigned int, 'u' )
+IntegralFMTDecl( signed long int, 'd' )
+IntegralFMTDecl( unsigned long int, 'u' )
+IntegralFMTDecl( signed long long int, 'd' )
+IntegralFMTDecl( unsigned long long int, 'u' )
+
+//*********************************** Floating Point ***********************************
+
+// Default suffix for values with no fraction is "."
+#define FloatingPointFMTDecl( T ) \
+static inline { \
+	_Ostream_Manip(T) sci( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'e', { .all : 0 } }; } \
+	_Ostream_Manip(T) hex( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'a', { .all : 0 } }; } \
+	_Ostream_Manip(T) wd( unsigned char w, T v ) { return (_Ostream_Manip(T))@{ v, w, 0, 'f', { .all : 0 } }; } \
+	_Ostream_Manip(T) wd( unsigned char w, unsigned char p, T v ) { return (_Ostream_Manip(T))@{ v, w, p, 'f', { .flags.pc : true } }; } \
+	_Ostream_Manip(T) ws( unsigned char w, unsigned char p, T v ) { return (_Ostream_Manip(T))@{ v, w, p, 'g', { .flags.pc : true } }; } \
+	_Ostream_Manip(T) & wd( unsigned char w, _Ostream_Manip(T) & fmt ) with(fmt) { wd = w; return fmt; } \
+	_Ostream_Manip(T) & wd( unsigned char w, unsigned char p, _Ostream_Manip(T) & fmt ) with(fmt) { wd = w; pc = p; flags.pc = true; return fmt; } \
+	_Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \
+	_Ostream_Manip(T) upcase( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'G', { .all : 0 } }; } \
+	_Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { fmt.base -= 32; /* upper case */ return fmt; } \
+	_Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \
+	_Ostream_Manip(T) sign( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'g', { .flags.sign : true } }; } \
+	_Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \
+	_Ostream_Manip(T) nodp( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'g', { .flags.nobsdp : true } }; } \
+	_Ostream_Manip(T) & nodp( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \
+} \
+forall( dtype ostype | ostream( ostype ) ) { \
+	ostype & ?|?( ostype & os, _Ostream_Manip(T) f ); \
+	void ?|?( ostype & os, _Ostream_Manip(T) f ); \
+}
+
+FloatingPointFMTDecl( double )
+FloatingPointFMTDecl( long double )
+
+//*********************************** Character ***********************************
+
+static inline {
+	_Ostream_Manip(char) bin( char v ) { return (_Ostream_Manip(char))@{ v, 1, 0, 'b', { .all : 0 } }; }
+	_Ostream_Manip(char) oct( char v ) { return (_Ostream_Manip(char))@{ v, 1, 0, 'o', { .all : 0 } }; }
+	_Ostream_Manip(char) hex( char v ) { return (_Ostream_Manip(char))@{ v, 1, 0, 'x', { .all : 0 } }; }
+	_Ostream_Manip(char) wd( unsigned char w, char v ) { return (_Ostream_Manip(char))@{ v, w, 0, 'c', { .all : 0 } }; }
+	_Ostream_Manip(char) & wd( unsigned char w, _Ostream_Manip(char) & fmt ) with(fmt) { wd = w; return fmt; }
+	_Ostream_Manip(char) & left( _Ostream_Manip(char) & fmt ) { fmt.flags.left = true; return fmt; }
+	_Ostream_Manip(char) & upcase( _Ostream_Manip(char) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; }
+	_Ostream_Manip(char) & nobase( _Ostream_Manip(char) & fmt ) { fmt.flags.nobsdp = true; return fmt; }
+} // distribution
+forall( dtype ostype | ostream( ostype ) ) {
+	ostype & ?|?( ostype & os, _Ostream_Manip(char) f );
+	void ?|?( ostype & os, _Ostream_Manip(char) f );
+}
+
+//*********************************** C String ***********************************
+
+static inline {
+	_Ostream_Manip(const char *) bin( const char * v ) { return (_Ostream_Manip(const char *))@{ v, 1, 0, 'b', { .all : 0 } }; }
+	_Ostream_Manip(const char *) oct( const char * v ) { return (_Ostream_Manip(const char *))@{ v, 1, 0, 'o', { .all : 0 } }; }
+	_Ostream_Manip(const char *) hex( const char * v ) { return (_Ostream_Manip(const char *))@{ v, 1, 0, 'x', { .all : 0 } }; }
+	_Ostream_Manip(const char *) wd( unsigned char w, const char * v ) { return (_Ostream_Manip(const char *))@{ v, w, 0, 's', { .all : 0 } }; }
+	_Ostream_Manip(const char *) wd( unsigned char w, unsigned char p, const char * v ) { return (_Ostream_Manip(const char *))@{ v, w, p, 's', { .flags.pc : true } }; }
+	_Ostream_Manip(const char *) & wd( unsigned char w, _Ostream_Manip(const char *) & fmt ) with(fmt) { wd = w; return fmt; }
+	_Ostream_Manip(const char *) & wd( unsigned char w, unsigned char p, _Ostream_Manip(const char *) & fmt ) with(fmt) { wd = w; pc = p; flags.pc = true; return fmt; }
+	_Ostream_Manip(const char *) & left( _Ostream_Manip(const char *) & fmt ) { fmt.flags.left = true; return fmt; }
+	_Ostream_Manip(const char *) & nobase( _Ostream_Manip(const char *) & fmt ) { fmt.flags.nobsdp = true; return fmt; }
+} // distribution
+forall( dtype ostype | ostream( ostype ) ) {
+	ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f );
+	void ?|?( ostype & os, _Ostream_Manip(const char *) f );
+}
+
+
+//*********************************** Istream ***********************************
+
 
 trait istream( dtype istype ) {
@@ -204,4 +327,60 @@
 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_cstrC );
 
+#if 0
+struct _Istream_Cstr {
+	char * s, * scanset;
+	int wd;												// width
+	bool ignore;										// no input argument
+};
+static inline _Istream_Cstr skip( char * s ) { return (_Istream_Cstr){ 0p, s, -1, false }; }
+static inline _Istream_Cstr incl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, false }; }
+static inline _Istream_Cstr excl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, false }; }
+static inline _Istream_Cstr cstr( char * s ) { return (_Istream_Cstr){ s, 0p, -1, false }; }
+static inline _Istream_Cstr ignore( char * s ) { return (_Istream_Cstr)@{ s, 0p, -1, true }; }
+static inline _Istream_Cstr ignore( _Istream_Cstr & fmt ) { fmt.ignore = true; return fmt; }
+static inline _Istream_Cstr wd( unsigned int w, char * s ) { return (_Istream_Cstr)@{ s, 0p, w, false }; }
+forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_Cstr );
+
+//*********************************** Manipulators ***********************************
+
+forall( otype T )
+struct _Istream_Manip {
+	T & val;											// polymorphic base-type
+	int wd;												// width
+	bool ignore;										// no input argument
+}; // _Istream_Manip
+
+#define InputFMTDecl( T ) \
+static inline _Istream_Manip(T) ignore( T & v ) { return (_Istream_Manip(T))@{ v, -1, true }; } \
+static inline _Istream_Manip(T) ignore( _Istream_Manip(T) & fmt ) { fmt.ignore = true; return fmt; } \
+static inline _Istream_Manip(T) wd( unsigned int w, T & v ) { return (_Istream_Manip(T))@{ v, w, false }; } \
+forall( dtype istype | istream( istype ) ) { \
+	istype & ?|?( istype & is, _Istream_Manip(T) f ); \
+}
+
+InputFMTDecl( char )
+InputFMTDecl( signed char )
+InputFMTDecl( unsigned char )
+InputFMTDecl( signed short int )
+InputFMTDecl( unsigned short int )
+InputFMTDecl( signed int )
+InputFMTDecl( unsigned int )
+InputFMTDecl( signed long int )
+InputFMTDecl( unsigned long int )
+InputFMTDecl( signed long long int )
+InputFMTDecl( unsigned long long int )
+
+InputFMTDecl( float )
+InputFMTDecl( double )
+InputFMTDecl( long double )
+
+InputFMTDecl( float _Complex )
+InputFMTDecl( double _Complex )
+InputFMTDecl( long double _Complex )
+#endif // 0
+
+
+//*********************************** Time ***********************************
+
 
 #include <time_t.hfa>									// Duration (constructors) / Time (constructors)
