Index: libcfa/src/collections/string.cfa
===================================================================
--- libcfa/src/collections/string.cfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/collections/string.cfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -216,5 +216,5 @@
 	}
 
-	void ?|?( ostype & out, string s ) {
+	void ?|?( ostype & out, string s ) with ( basic_ostream_table ) {
 		(ostype &)(out | (*s.inner)); ends( out );
 	}
@@ -229,5 +229,5 @@
 	} // ?|?
 
-	void ?|?( ostype & os, _Ostream_Manip(string) f ) {
+	void ?|?( ostype & os, _Ostream_Manip(string) f ) with ( basic_ostream_table ) {
 		(ostype &)(os | f); ends( os );
 	}
Index: libcfa/src/collections/string_res.cfa
===================================================================
--- libcfa/src/collections/string_res.cfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/collections/string_res.cfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -201,5 +201,6 @@
 forall( ostype & | basic_ostream( ostype ) )
 void ?|?( ostype & out, const string_res & s ) {
-	(ostype &)(out | s); ends( out );
+	(ostype &)(out | s);
+	basic_ostream_table.ends( out );
 }
 
@@ -249,5 +250,5 @@
 
 forall( istype & | basic_istream( istype ) )
-istype & ?|?( istype & is, _Istream_Rquote f ) with( f.rstr ) {
+istype & ?|?( istype & is, _Istream_Rquote f ) with( basic_istream_table, f.rstr ) {
 	if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 	int args;
Index: libcfa/src/fstream.cfa
===================================================================
--- libcfa/src/fstream.cfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/fstream.cfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -202,4 +202,71 @@
 } // nl
 
+static basic_ostream_data(ofstream) ofstream_basic_data = {
+	sepPrt$,
+	sepReset$,
+	sepReset$,
+	sepGetCur$,
+	sepSetCur$,
+	getNL$,
+	setNL$,
+	getANL$,
+	setANL$,
+	getPrt$,
+	setPrt$,
+	nlOn,
+	nlOff,
+	sep,
+	nosep,
+	sepOn,
+	sepOff,
+	sepGet,
+	sepSet,
+	sepGetTuple,
+	sepSetTuple,
+	ends,
+	fmt,
+};
+
+basic_ostream_data(ofstream) const & basic_ostream_table = ofstream_basic_data;
+
+static ostream_data(ofstream) ofstream_data;
+
+// This should be an initializer like for the basic table.
+// But, initialization of a structure with an inline structure doesn't work.
+__attribute__((constructor(200)))
+static void __ofstream_data_init__() {
+	basic_ostream_data(ofstream) & basic = ofstream_data;
+	basic.sepPrt$ = sepPrt$;
+	basic.sepReset$ = (void(*)(ofstream&))sepReset$;
+	basic.sepReset$ = (void(*)(ofstream&, bool))sepReset$;
+	basic.sepGetCur$ = sepGetCur$;
+	basic.sepSetCur$ = sepSetCur$;
+	basic.getNL$ = getNL$;
+	basic.setNL$ = setNL$;
+	basic.getANL$ = getANL$;
+	basic.setANL$ = setANL$;
+	basic.getPrt$ = getPrt$;
+	basic.setPrt$ = setPrt$;
+	basic.nlOn = nlOn;
+	basic.nlOff = nlOff;
+	basic.sep = sep;
+	basic.nosep = nosep;
+	basic.sepOn = sepOn;
+	basic.sepOff = sepOff;
+	basic.sepGet = sepGet;
+	basic.sepSet = sepSet;
+	basic.sepGetTuple = sepGetTuple;
+	basic.sepSetTuple = sepSetTuple;
+	basic.ends = ends;
+	basic.fmt = fmt;
+	ofstream_data.fail = fail;
+	ofstream_data.clearerr = clearerr;
+	ofstream_data.flush = flush;
+	ofstream_data.open = open;
+	ofstream_data.close = close;
+	ofstream_data.write = write;
+}
+
+ostream_data(ofstream) const & ostream_table = ofstream_data;
 
 // *********************************** ifstream ***********************************
@@ -211,4 +278,41 @@
 	nlOnOff$ = false;									// => skip newlines when reading single characters
 } // ?{}
+
+static basic_istream_data(ifstream) ifstream_basic_data = {
+	getANL$,
+	setANL$,
+	nlOn,
+	nlOff,
+	fmt,
+	ungetc,
+	eof,
+	clearerr,
+};
+
+basic_istream_data(ifstream) const & basic_istream_table = ifstream_basic_data;
+
+static istream_data(ifstream) ifstream_data;
+
+// This should be an initializer like for the basic table.
+// But, initialization of a structure with an inline structure doesn't work.
+__attribute__((constructor(200)))
+static void __ifstream_data_init__() {
+	basic_istream_data(ifstream) & basic = ifstream_data;
+	basic.getANL$ = getANL$;
+	basic.setANL$ = setANL$;
+	basic.nlOn = nlOn;
+	basic.nlOff = nlOff;
+	basic.fmt = fmt;
+	basic.ungetc = ungetc;
+	basic.eof = eof;
+	basic.clearerr = clearerr;
+	ifstream_data.fail = fail;
+	ifstream_data.open = (void(*)(ifstream &, const char *, const char *))open;
+	ifstream_data.open = (void(*)(ifstream &, const char *))open;
+	ifstream_data.close = close;
+	ifstream_data.read = read;
+}
+
+istream_data(ifstream) const & istream_table = ifstream_data;
 
 bool getANL$( ifstream & os ) { return os.nlOnOff$; }
Index: libcfa/src/fstream.hfa
===================================================================
--- libcfa/src/fstream.hfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/fstream.hfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -38,4 +38,6 @@
 
 // Satisfies ostream
+extern basic_ostream_data(ofstream) const & basic_ostream_table;
+extern ostream_data(ofstream) const & ostream_table;
 
 // private
@@ -106,4 +108,6 @@
 
 // Satisfies istream
+extern basic_istream_data(ifstream) const & basic_istream_table;
+extern istream_data(ifstream) const & istream_table;
 
 // private
Index: libcfa/src/gmp.hfa
===================================================================
--- libcfa/src/gmp.hfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/gmp.hfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -263,7 +263,8 @@
 	forall( ostype & | ostream( ostype ) ) {
 		ostype & ?|?( ostype & os, Int mp ) {
-			if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
+			ostream_data(ostype) const & table = ostream_table;
+			if ( table.sepPrt$( os ) ) table.fmt( os, "%s", table.sepGetCur$( os ) );
 			gmp_printf( "%Zd", mp.mpz );
-			sep( os );
+			table.sep( os );
 			return os;
 		} // ?|?
Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/iostream.cfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -42,5 +42,5 @@
 
 forall( ostype & | basic_ostream( ostype ) ) {
-	ostype & ?|?( ostype & os, bool b ) {
+	ostype & ?|?( ostype & os, bool b ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%s", b ? "true" : "false" );
@@ -49,5 +49,5 @@
 	OSTYPE_VOID_IMPL( os, bool )
 
-	ostype & ?|?( ostype & os, char c ) {
+	ostype & ?|?( ostype & os, char c ) with ( basic_ostream_table ) {
 		fmt( os, "%c", c );
 		if ( c == '\n' ) setNL$( os, true );
@@ -56,5 +56,5 @@
 	OSTYPE_VOID_IMPL( os, char )
 
-	ostype & ?|?( ostype & os, signed char sc ) {
+	ostype & ?|?( ostype & os, signed char sc ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'hhd", sc );
@@ -63,5 +63,5 @@
 	OSTYPE_VOID_IMPL( os, signed char )
 
-	ostype & ?|?( ostype & os, unsigned char usc ) {
+	ostype & ?|?( ostype & os, unsigned char usc ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'hhu", usc );
@@ -70,5 +70,5 @@
 	OSTYPE_VOID_IMPL( os, unsigned char )
 
-	ostype & ?|?( ostype & os, short int si ) {
+	ostype & ?|?( ostype & os, short int si ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'hd", si );
@@ -77,5 +77,5 @@
 	OSTYPE_VOID_IMPL( os, short int )
 
-	ostype & ?|?( ostype & os, unsigned short int usi ) {
+	ostype & ?|?( ostype & os, unsigned short int usi ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'hu", usi );
@@ -84,5 +84,5 @@
 	OSTYPE_VOID_IMPL( os, unsigned short int )
 
-	ostype & ?|?( ostype & os, int i ) {
+	ostype & ?|?( ostype & os, int i ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'d", i );
@@ -91,5 +91,5 @@
 	OSTYPE_VOID_IMPL( os, int )
 
-	ostype & ?|?( ostype & os, unsigned int ui ) {
+	ostype & ?|?( ostype & os, unsigned int ui ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'u", ui );
@@ -98,5 +98,5 @@
 	OSTYPE_VOID_IMPL( os, unsigned int )
 
-	ostype & ?|?( ostype & os, long int li ) {
+	ostype & ?|?( ostype & os, long int li ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'ld", li );
@@ -105,5 +105,5 @@
 	OSTYPE_VOID_IMPL( os, long int )
 
-	ostype & ?|?( ostype & os, unsigned long int uli ) {
+	ostype & ?|?( ostype & os, unsigned long int uli ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'lu", uli );
@@ -112,5 +112,5 @@
 	OSTYPE_VOID_IMPL( os, unsigned long int )
 
-	ostype & ?|?( ostype & os, long long int lli ) {
+	ostype & ?|?( ostype & os, long long int lli ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'lld", lli );
@@ -119,5 +119,5 @@
 	OSTYPE_VOID_IMPL( os, long long int )
 
-	ostype & ?|?( ostype & os, unsigned long long int ulli ) {
+	ostype & ?|?( ostype & os, unsigned long long int ulli ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%'llu", ulli );
@@ -130,5 +130,5 @@
 	#define P10_UINT64 10_000_000_000_000_000_000_ULL	// 19 zeroes
 
-	static inline void base10_128( ostype & os, unsigned int128 val ) {
+	static inline void base10_128( ostype & os, unsigned int128 val ) with ( basic_ostream_table ) {
 		#if defined(__GNUC__) && __GNUC_PREREQ(7,0)		// gcc version >= 7
 		if ( val > P10_UINT64 ) {
@@ -143,5 +143,5 @@
 	} // base10_128
 
-	static inline void base10_128( ostype & os, int128 val ) {
+	static inline void base10_128( ostype & os, int128 val ) with ( basic_ostream_table ) {
 		if ( val < 0 ) {
 			fmt( os, "-" );								// leading negative sign
@@ -151,5 +151,5 @@
 	} // base10_128
 
-	ostype & ?|?( ostype & os, int128 llli ) {
+	ostype & ?|?( ostype & os, int128 llli ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		base10_128( os, llli );
@@ -158,5 +158,5 @@
 	OSTYPE_VOID_IMPL( os, int128 )
 
-	ostype & ?|?( ostype & os, unsigned int128 ullli ) {
+	ostype & ?|?( ostype & os, unsigned int128 ullli ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		base10_128( os, ullli );
@@ -181,5 +181,5 @@
 		}
 
-	ostype & ?|?( ostype & os, float f ) {
+	ostype & ?|?( ostype & os, float f ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		PRINT_WITH_DP( os, "%'g", f );
@@ -188,5 +188,5 @@
 	OSTYPE_VOID_IMPL( os, float )
 
-	ostype & ?|?( ostype & os, double d ) {
+	ostype & ?|?( ostype & os, double d ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		PRINT_WITH_DP( os, "%'.*lg", d, DBL_DIG );
@@ -195,5 +195,5 @@
 	OSTYPE_VOID_IMPL( os, double )
 
-	ostype & ?|?( ostype & os, long double ld ) {
+	ostype & ?|?( ostype & os, long double ld ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		PRINT_WITH_DP( os, "%'.*Lg", ld, LDBL_DIG );
@@ -202,5 +202,5 @@
 	OSTYPE_VOID_IMPL( os, long double )
 
-	ostype & ?|?( ostype & os, float _Complex fc ) {
+	ostype & ?|?( ostype & os, float _Complex fc ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 //		os | crealf( fc ) | nonl;
@@ -212,5 +212,5 @@
 	OSTYPE_VOID_IMPL( os, float _Complex )
 
-	ostype & ?|?( ostype & os, double _Complex dc ) {
+	ostype & ?|?( ostype & os, double _Complex dc ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 //		os | creal( dc ) | nonl;
@@ -222,5 +222,5 @@
 	OSTYPE_VOID_IMPL( os, double _Complex )
 
-	ostype & ?|?( ostype & os, long double _Complex ldc ) {
+	ostype & ?|?( ostype & os, long double _Complex ldc ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 //		os | creall( ldc ) || nonl;
@@ -232,5 +232,5 @@
 	OSTYPE_VOID_IMPL( os, long double _Complex )
 
-	ostype & ?|?( ostype & os, const char s[] ) {
+	ostype & ?|?( ostype & os, const char s[] ) with ( basic_ostream_table ) {
 		enum { Open = 1, Close, OpenClose };
 		static const unsigned char mask[256] @= {		// 256 covers all Latin-1 characters
@@ -295,5 +295,5 @@
 // 	} // ?|?
 
-	ostype & ?|?( ostype & os, const void * p ) {
+	ostype & ?|?( ostype & os, const void * p ) with ( basic_ostream_table ) {
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
 		fmt( os, "%p", p );
@@ -306,5 +306,5 @@
 		return manip( os );
 	} // ?|?
-	void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
+	void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) with ( basic_ostream_table ) {
 		manip( os );
 		if ( getPrt$( os ) ) ends( os );				// something printed ?
@@ -312,5 +312,5 @@
 	} // ?|?
 
-	ostype & nl( ostype & os ) {
+	ostype & nl( ostype & os ) with ( basic_ostream_table ) {
 		(ostype &)(os | '\n');
 		setPrt$( os, false );							// turn off
@@ -319,43 +319,43 @@
 	} // nl
 
-	ostype & nonl( ostype & os ) {
+	ostype & nonl( ostype & os ) with ( basic_ostream_table ) {
 		setPrt$( os, false );							// turn off
 		return os;
 	} // nonl
 
-	ostype & nlOn( ostype & os ) {
+	ostype & nlOn( ostype & os ) with ( basic_ostream_table ) {
 		nlOn( os );										// call void returning
 		return os;
 	} // nlOn
 
-	ostype & nlOff( ostype & os ) {
+	ostype & nlOff( ostype & os ) with ( basic_ostream_table ) {
 		nlOff( os );									// call void returning
 		return os;
 	} // nlOff
 
-	ostype & sepVal( ostype & os ) {
+	ostype & sepVal( ostype & os ) with ( basic_ostream_table ) {
 		return (ostype &)(os | sepGet( os ));
 	} // sepVal
 
-	ostype & sepTupleVal( ostype & os ) {
+	ostype & sepTupleVal( ostype & os ) with ( basic_ostream_table ) {
 		return os | sepGetTuple( os );
 	} // sepTupleVal
 
-	ostype & sep( ostype & os ) {
+	ostype & sep( ostype & os ) with ( basic_ostream_table ) {
 		sep( os );										// call void returning
 		return os;
 	} // sep
 
-	ostype & nosep( ostype & os ) {
+	ostype & nosep( ostype & os ) with ( basic_ostream_table ) {
 		nosep( os );									// call void returning
 		return os;
 	} // nosep
 
-	ostype & sepOn( ostype & os ) {
+	ostype & sepOn( ostype & os ) with ( basic_ostream_table ) {
 		sepOn( os );									// call void returning
 		return os;
 	} // sepOn
 
-	ostype & sepOff( ostype & os ) {
+	ostype & sepOff( ostype & os ) with ( basic_ostream_table ) {
 		sepOff( os );									// call void returning
 		return os;
@@ -365,5 +365,5 @@
 // tuples
 forall( ostype &, T, Params... | writeable( T, ostype ) | { ostype & ?|?( ostype &, Params ); } ) {
-	ostype & ?|?( ostype & os, T arg, Params rest ) {
+	ostype & ?|?( ostype & os, T arg, Params rest ) with ( basic_ostream_table ) {
 		(ostype &)(os | arg);							// print first argument
 		sepSetCur$( os, sepGetTuple( os ) );			// switch to tuple separator
@@ -372,5 +372,5 @@
 		return os;
 	} // ?|?
-	void ?|?( ostype & os, T arg, Params rest ) {
+	void ?|?( ostype & os, T arg, Params rest ) with ( basic_ostream_table ) {
 		// (ostype &)(?|?( os, arg, rest )); ends( os );
 		(ostype &)(os | arg);							// print first argument
@@ -405,5 +405,5 @@
 #define INTEGRAL_FMT_IMPL( T, IFMTNP, IFMTP ) \
 forall( ostype & | basic_ostream( ostype ) ) { \
-	ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
+	ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) with ( basic_ostream_table ) { \
 		if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) ); \
 \
@@ -653,5 +653,5 @@
 	} /* eng */ \
 \
-	ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
+	ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) with ( basic_ostream_table ) { \
 		enum { size = 48 }; \
 		char buf[size]; \
@@ -692,5 +692,5 @@
 
 forall( ostype & | basic_ostream( ostype ) ) {
-	ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) {
+	ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) with ( basic_ostream_table ) {
 		if ( f.base != 'c' ) {							// bespoke binary/octal/hex format
 			_Ostream_Manip(unsigned char) fmtuc @= { f.val, f.wd, f.pc, f.base, {'\0'} };
@@ -724,5 +724,5 @@
 
 forall( ostype & | basic_ostream( ostype ) ) {
-	ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ) {
+	ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ) with ( basic_ostream_table ) {
 		if ( ! f.val ) return os;						// null pointer ?
 
@@ -776,5 +776,5 @@
 
 forall( istype & | basic_istream( istype ) ) {
-	istype & ?|?( istype & is, bool & b ) {
+	istype & ?|?( istype & is, bool & b ) with ( basic_istream_table ) {
 		int len = -1;									// len not set if no match
 		fmt( is, " " );									// remove leading whitespace
@@ -792,5 +792,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, char & c ) {
+	istype & ?|?( istype & is, char & c ) with ( basic_istream_table ) {
 		char temp;
 		for () {
@@ -804,5 +804,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, signed char & sc ) {
+	istype & ?|?( istype & is, signed char & sc ) with ( basic_istream_table ) {
 		int args = fmt( is, "%hhi", &sc );				// can be multiple characters (100)
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -811,5 +811,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, unsigned char & usc ) {
+	istype & ?|?( istype & is, unsigned char & usc ) with ( basic_istream_table ) {
 		int args = fmt( is, "%hhi", &usc );				// can be multiple characters (-100)
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -818,5 +818,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, short int & si ) {
+	istype & ?|?( istype & is, short int & si ) with ( basic_istream_table ) {
 		int args = fmt( is, "%hi", &si );				// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -825,5 +825,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, unsigned short int & usi ) {
+	istype & ?|?( istype & is, unsigned short int & usi ) with ( basic_istream_table ) {
 		int args = fmt( is, "%hi", &usi );				// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -832,5 +832,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, int & i ) {
+	istype & ?|?( istype & is, int & i ) with ( basic_istream_table ) {
 		int args = fmt( is, "%i", &i );					// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -839,5 +839,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, unsigned int & ui ) {
+	istype & ?|?( istype & is, unsigned int & ui ) with ( basic_istream_table ) {
 		int args = fmt( is, "%i", &ui );				// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -846,5 +846,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, long int & li ) {
+	istype & ?|?( istype & is, long int & li ) with ( basic_istream_table ) {
 		int args = fmt( is, "%li", &li );				// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -853,5 +853,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, unsigned long int & ulli ) {
+	istype & ?|?( istype & is, unsigned long int & ulli ) with ( basic_istream_table ) {
 		int args = fmt( is, "%li", &ulli );				// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -860,5 +860,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, long long int & lli ) {
+	istype & ?|?( istype & is, long long int & lli ) with ( basic_istream_table ) {
 		int args = fmt( is, "%lli", &lli );				// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -867,5 +867,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, unsigned long long int & ulli ) {
+	istype & ?|?( istype & is, unsigned long long int & ulli ) with ( basic_istream_table ) {
 		int args = fmt( is, "%lli", &ulli );			// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -879,5 +879,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, unsigned int128 & ullli ) {
+	istype & ?|?( istype & is, unsigned int128 & ullli ) with ( basic_istream_table ) {
 		char s[40];
 		bool sign = false;
@@ -896,5 +896,5 @@
 	#endif // __SIZEOF_INT128__
 
-	istype & ?|?( istype & is, float & f ) {
+	istype & ?|?( istype & is, float & f ) with ( basic_istream_table ) {
 		int args = fmt( is, "%f", &f );					// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -903,5 +903,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, double & d ) {
+	istype & ?|?( istype & is, double & d ) with ( basic_istream_table ) {
 		int args = fmt( is, "%lf", &d );				// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -910,5 +910,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, long double & ld ) {
+	istype & ?|?( istype & is, long double & ld ) with ( basic_istream_table ) {
 		int args = fmt( is, "%Lf", &ld );				// can be called with EOF on
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -917,5 +917,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, float _Complex & fc ) {
+	istype & ?|?( istype & is, float _Complex & fc ) with ( basic_istream_table ) {
 		float re, im;
 		int args = fmt( is, "%f%fi", &re, &im );		// can be called with EOF on
@@ -926,5 +926,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, double _Complex & dc ) {
+	istype & ?|?( istype & is, double _Complex & dc ) with ( basic_istream_table ) {
 		double re, im;
 		int args = fmt( is, "%lf%lfi", &re, &im );		// can be called with EOF on
@@ -935,5 +935,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, long double _Complex & ldc ) {
+	istype & ?|?( istype & is, long double _Complex & ldc ) with ( basic_istream_table ) {
 		long double re, im;
 		int args = fmt( is, "%Lf%Lfi", &re, &im );		// can be called with EOF on
@@ -944,5 +944,5 @@
 	} // ?|?
 
-	istype & ?|?( istype & is, const char fmt[] ) {		// match text
+	istype & ?|?( istype & is, const char fmt[] ) with ( basic_istream_table ) {		// match text
 		size_t len = strlen( fmt );
 		char fmtstr[len + 16];
@@ -966,5 +966,5 @@
 	} // ?|?
 
-	istype & nl( istype & is ) {
+	istype & nl( istype & is ) with ( basic_istream_table ) {
 		fmt( is, "%*[^\n]" );							// ignore characters to newline
 		if ( ! eof( is ) ) fmt( is, "%*c" );			// read newline
@@ -972,10 +972,10 @@
 	} // nl
 
-	istype & nlOn( istype & is ) {
+	istype & nlOn( istype & is ) with ( basic_istream_table ) {
 		nlOn( is );										// call void returning
 		return is;
 	} // nlOn
 
-	istype & nlOff( istype & is ) {
+	istype & nlOff( istype & is ) with ( basic_istream_table ) {
 		nlOff( is );									// call void returning
 		return is;
@@ -986,5 +986,5 @@
 
 forall( istype & | basic_istream( istype ) ) {
-	istype & ?|?( istype & is, _Istream_Cskip f ) {
+	istype & ?|?( istype & is, _Istream_Cskip f ) with ( basic_istream_table ) {
 		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		if ( f.scanset ) {
@@ -1006,5 +1006,5 @@
 	}
 
-	istype & ?|?( istype & is, _Istream_Cquote f ) with( f.cstr ) {
+	istype & ?|?( istype & is, _Istream_Cquote f ) with( basic_istream_table, f.cstr ) {
 		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args;
@@ -1031,5 +1031,6 @@
 	}
 
-	istype & ?|?( istype & is, _Istream_Cstr f ) with( f.cstr ) {
+	istype & ?|?( istype & is, _Istream_Cstr f ) with( basic_istream_table, f.cstr ) {
+		assert(eof);
 		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		const char * scanset;
@@ -1139,5 +1140,5 @@
 #define INPUT_FMT_IMPL( T, CODE ) \
 forall( istype & | basic_istream( istype ) ) { \
-	istype & ?|?( istype & is, _Istream_Manip(T) f ) { \
+	istype & ?|?( istype & is, _Istream_Manip(T) f ) with ( basic_istream_table ) { \
 		enum { size = 16 }; \
 		char fmtstr[size]; \
@@ -1203,5 +1204,5 @@
 
 forall( istype & | istream( istype ), E | CfaEnum( E ) | Serial( E ) )
-istype & ?|?( istype & is, E & e ) {
+istype & ?|?( istype & is, E & e ) with ( basic_istream_table ) {
 //	if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/iostream.hfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -22,43 +22,54 @@
 
 forall( ostype & )
+struct basic_ostream_data {
+	// private
+	bool (*sepPrt$)( ostype & );							// get separator state (on/off)
+	void (*sepReset$)( ostype & );							// set separator state to default state
+	void (*sepReset$)( ostype &, bool );					// set separator and default state
+	const char * (*sepGetCur$)( ostype & );				// get current separator string
+	void (*sepSetCur$)( ostype &, const char [] );			// set current separator string
+	bool (*getNL$)( ostype & );							// get newline
+	bool (*setNL$)( ostype &, bool );						// set newline
+	bool (*getANL$)( ostype & );							// get auto newline (on/off)
+	bool (*setANL$)( ostype &, bool );						// set auto newline (on/off), and return previous state
+	bool (*getPrt$)( ostype & );							// get fmt called in output cascade
+	bool (*setPrt$)( ostype &, bool );						// set fmt called in output cascade
+	// public
+	void (*nlOn)( ostype & );								// turn auto-newline state on
+	void (*nlOff)( ostype & );								// turn auto-newline state off
+
+	void (*sep)( ostype & );								// turn separator state on
+	void (*nosep)( ostype & );								// turn separator state off
+	bool (*sepOn)( ostype & );								// set default state to on, and return previous state
+	bool (*sepOff)( ostype & );							// set default state to off, and return previous state
+	const char * (*sepGet)( ostype & );					// get separator string
+	void (*sepSet)( ostype &, const char [] );				// set separator to string (15 character maximum)
+	const char * (*sepGetTuple)( ostype & );				// get tuple separator string
+	void (*sepSetTuple)( ostype &, const char [] );		// set tuple separator to string (15 character maximum)
+
+	void (*ends)( ostype & );								// end of output statement
+	int (*fmt)( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
+}; // basic_ostream
+
+forall( ostype & )
+struct ostream_data {
+	inline basic_ostream_data( ostype );
+	bool (*fail)( ostype & );								// operation failed?
+	void (*clearerr)( ostype & );
+	int (*flush)( ostype & );
+	void (*open)( ostype &, const char name[], const char mode[] );
+	void (*close)( ostype & );
+	ostype & (*write)( ostype &, const char [], size_t );
+}; // ostream
+
+forall( ostype & )
 trait basic_ostream {
-	// private
-	bool sepPrt$( ostype & );							// get separator state (on/off)
-	void sepReset$( ostype & );							// set separator state to default state
-	void sepReset$( ostype &, bool );					// set separator and default state
-	const char * sepGetCur$( ostype & );				// get current separator string
-	void sepSetCur$( ostype &, const char [] );			// set current separator string
-	bool getNL$( ostype & );							// get newline
-	bool setNL$( ostype &, bool );						// set newline
-	bool getANL$( ostype & );							// get auto newline (on/off)
-	bool setANL$( ostype &, bool );						// set auto newline (on/off), and return previous state
-	bool getPrt$( ostype & );							// get fmt called in output cascade
-	bool setPrt$( ostype &, bool );						// set fmt called in output cascade
-	// public
-	void nlOn( ostype & );								// turn auto-newline state on
-	void nlOff( ostype & );								// turn auto-newline state off
-
-	void sep( ostype & );								// turn separator state on
-	void nosep( ostype & );								// turn separator state off
-	bool sepOn( ostype & );								// set default state to on, and return previous state
-	bool sepOff( ostype & );							// set default state to off, and return previous state
-	const char * sepGet( ostype & );					// get separator string
-	void sepSet( ostype &, const char [] );				// set separator to string (15 character maximum)
-	const char * sepGetTuple( ostype & );				// get tuple separator string
-	void sepSetTuple( ostype &, const char [] );		// set tuple separator to string (15 character maximum)
-
-	void ends( ostype & );								// end of output statement
-	int fmt( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
-}; // basic_ostream
+	basic_ostream_data(ostype) const & basic_ostream_table;
+};
 
 forall( ostype & | basic_ostream( ostype ) )
 trait ostream {
-	bool fail( ostype & );								// operation failed?
-	void clearerr( ostype & );
-	int flush( ostype & );
-	void open( ostype &, const char name[], const char mode[] );
-	void close( ostype & );
-	ostype & write( ostype &, const char [], size_t );
-}; // ostream
+	ostream_data(ostype) const & ostream_table;
+};
 
 // forall( T )
@@ -77,5 +88,6 @@
 #define OSTYPE_VOID_IMPL( os, T ) \
 	void ?|?( ostype & os, T t ) { \
-		(ostype &)(os | t); ends( os ); \
+		(ostype &)(os | t); \
+		basic_ostream_table.ends( os ); \
 	} // ?|?
 
@@ -308,25 +320,36 @@
 
 forall( istype & )
+struct basic_istream_data {
+	// private
+	bool (*getANL$)( istype & );							// get scan newline (on/off)
+	bool (*setANL$)( istype &, bool );						// set scan newline (on/off)
+	// public
+	void (*nlOn)( istype & );								// read newline
+	void (*nlOff)( istype & );								// scan newline
+	int (*fmt)( istype &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
+	istype & (*ungetc)( char, istype & );
+	bool (*eof)( istype & );
+	void (*clearerr)( istype & );
+}; // basic_istream
+
+forall( istype & )
+struct istream_data {
+	inline basic_istream_data( istype );
+	bool (*fail)( istype & );
+	void (*open)( istype & is, const char name[], const char mode[] );
+	void (*open)( istype & is, const char name[] );
+	void (*close)( istype & is );
+	istype & (*read)( istype &, char [], size_t );
+}; // istream
+
+forall( istype & )
 trait basic_istream {
-	// private
-	bool getANL$( istype & );							// get scan newline (on/off)
-	bool setANL$( istype &, bool );						// set scan newline (on/off)
-	// public
-	void nlOn( istype & );								// read newline
-	void nlOff( istype & );								// scan newline
-	int fmt( istype &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
-	istype & ungetc( char, istype & );
-	bool eof( istype & );
-	void clearerr( istype & );
-}; // basic_istream
+	basic_istream_data(istype) const & basic_istream_table;
+};
 
 forall( istype & | basic_istream( istype ) )
 trait istream {
-	bool fail( istype & );
-	void open( istype & is, const char name[], const char mode[] );
-	void open( istype & is, const char name[] );
-	void close( istype & is );
-	istype & read( istype &, char [], size_t );
-}; // istream
+	istream_data(istype) const & istream_table;
+};
 
 forall( T )
Index: libcfa/src/strstream.cfa
===================================================================
--- libcfa/src/strstream.cfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/strstream.cfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -28,4 +28,31 @@
 // *********************************** strstream ***********************************
 
+static basic_ostream_data(ostrstream) ostrstream_basic_data = {
+	sepPrt$,
+	sepReset$,
+	sepReset$,
+	sepGetCur$,
+	sepSetCur$,
+	getNL$,
+	setNL$,
+	getANL$,
+	setANL$,
+	getPrt$,
+	setPrt$,
+	nlOn,
+	nlOff,
+	sep,
+	nosep,
+	sepOn,
+	sepOff,
+	sepGet,
+	sepSet,
+	sepGetTuple,
+	sepSetTuple,
+	ends,
+	fmt,
+};
+
+basic_ostream_data(ostrstream) const & basic_ostream_table = ostrstream_basic_data;
 
 #define IO_MSG "I/O error: "
@@ -130,4 +157,17 @@
 
 // *********************************** istrstream ***********************************
+
+static basic_istream_data(istrstream) istrstream_basic_data = {
+	getANL$,
+	setANL$,
+	nlOn,
+	nlOff,
+	fmt,
+	ungetc,
+	eof,
+	clearerr,
+};
+
+basic_istream_data(istrstream) const & basic_istream_data = istrstream_basic_data;
 
 // private
Index: libcfa/src/strstream.hfa
===================================================================
--- libcfa/src/strstream.hfa	(revision 6b33e891da6ed781bdcec69c5dfdd3cb8a9d0e44)
+++ libcfa/src/strstream.hfa	(revision bd72f517201f32b402a96297718f58f3eace1e0b)
@@ -39,4 +39,5 @@
 
 // Satisfies basic_ostream
+extern basic_ostream_data(ostrstream) const & basic_ostream_table;
 
 // private
@@ -90,4 +91,5 @@
 
 // Satisfies basic_istream
+extern basic_istream_data(istrstream) const & basic_istream_table;
 
 // private
