Index: libcfa/src/collections/string.cfa
===================================================================
--- libcfa/src/collections/string.cfa	(revision 234c4328242f343169846cf6693f3c5807ae5b67)
+++ libcfa/src/collections/string.cfa	(revision 3f631d63dc8a3d8d5bd5e664c971d336878cb507)
@@ -214,39 +214,45 @@
 // Input-Output
 
-ofstream & ?|?( ofstream & out, const string & s ) {
-	return out | (*s.inner); // print internal string_res
-}
-
-void ?|?( ofstream & out, const string & s ) {
-	(ofstream &)(out | (*s.inner)); ends( out );
-}
-
-ofstream & ?|?( ofstream & os, _Ostream_Manip(string) f ) {
-	size_t l = len( f.val );
-	char cstr[l + 1];									// room for null terminator
-	for ( i; l ) cstr[i] = f.val[i];					// copy string
-	cstr[l] = '\0';										// terminate
-	_Ostream_Manip(const char *) cf @= { cstr, f.wd, f.pc, f.base, {f.all} };
-	return os | cf | nonl;
-} // ?|?
-
-void ?|?( ofstream & os, _Ostream_Manip(string) f ) {
-	(ofstream &)(os | f); ends( os );
-}
-
-ifstream & ?|?( ifstream & in, string & s ) {
-	return in | (*s.inner); // read to internal string_res
-}
-
-ifstream & ?|?( ifstream & is, _Istream_Squoted f ) {
-	_Istream_Rquoted f2 = { { f.sstr.s.inner, (_Istream_str_base)f.sstr } };
-	return is | f2;
-} // ?|?
-
-ifstream & ?|?( ifstream & is, _Istream_Sstr f ) {
-// 	_Istream_Rstr f2 = {f.sstr.s.inner, (_Istream_str_base)f.sstr};
- 	_Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f};
-	return is | f2;
-} // ?|?
+forall( ostype & | basic_ostream( ostype ) ) {
+
+	ostype & ?|?( ostype & out, string s ) {
+		return out | (*s.inner); // print internal string_res
+	}
+
+	void ?|?( ostype & out, string s ) {
+		(ostype &)(out | (*s.inner)); ends( out );
+	}
+
+	ostype & ?|?( ostype & os, _Ostream_Manip(string) f ) {
+		size_t l = len( f.val );
+		char cstr[l + 1];									// room for null terminator
+		for ( i; l ) cstr[i] = f.val[i];					// copy string
+		cstr[l] = '\0';										// terminate
+		_Ostream_Manip(const char *) cf @= { cstr, f.wd, f.pc, f.base, {f.all} };
+		return os | cf | nonl;
+	} // ?|?
+
+	void ?|?( ostype & os, _Ostream_Manip(string) f ) {
+		(ostype &)(os | f); ends( os );
+	}
+}
+
+forall( istype & | basic_istream( istype ) ) {
+
+	istype & ?|?( istype & in, string & s ) {
+		return in | (*s.inner); // read to internal string_res
+	}
+
+	istype & ?|?( istype & is, _Istream_Squoted f ) {
+		_Istream_Rquoted f2 = { { f.sstr.s.inner, (_Istream_str_base)f.sstr } };
+		return is | f2;
+	} // ?|?
+
+	istype & ?|?( istype & is, _Istream_Sstr f ) {
+	// 	_Istream_Rstr f2 = {f.sstr.s.inner, (_Istream_str_base)f.sstr};
+		_Istream_Rstr f2 = {f.s.inner, (_Istream_str_base)f};
+		return is | f2;
+	} // ?|?
+}
 
 ////////////////////////////////////////////////////////
Index: libcfa/src/collections/string.hfa
===================================================================
--- libcfa/src/collections/string.hfa	(revision 234c4328242f343169846cf6693f3c5807ae5b67)
+++ libcfa/src/collections/string.hfa	(revision 3f631d63dc8a3d8d5bd5e664c971d336878cb507)
@@ -16,5 +16,5 @@
 #pragma once
 
-#include <fstream.hfa>
+#include <iostream.hfa>
 #include <string_res.hfa>
 
@@ -80,7 +80,10 @@
 
 // IO Operator
-ofstream & ?|?( ofstream & out, const string & s );
-void ?|?( ofstream & out, const string & s );
-ifstream & ?|?( ifstream & in, string & s );
+forall( ostype & | basic_ostream( ostype ) ) {
+	ostype & ?|?( ostype & out, string s );
+	void ?|?( ostype & out, string s );
+}
+forall( istype & | basic_istream( istype ) )
+istype & ?|?( istype & in, string & s );
 
 static inline {
@@ -95,6 +98,8 @@
 	_Ostream_Manip(string) & nobase( _Ostream_Manip(string) & fmt ) { fmt.flags.nobsdp = true; return fmt; }
 } // distribution
-ofstream & ?|?( ofstream & os, _Ostream_Manip(string) f );
-void ?|?( ofstream & os, _Ostream_Manip(string) );
+forall( ostype & | basic_ostream( ostype ) ) {
+	ostype & ?|?( ostype & os, _Ostream_Manip(string) f );
+	void ?|?( ostype & os, _Ostream_Manip(string) );
+}
 
 struct _Istream_Swidth {
@@ -143,7 +148,9 @@
 	_Istream_Sstr & ignore( _Istream_Sstr & f ) { f.flags.ignore = true; return (_Istream_Sstr &)f; }
 } // distribution
-ifstream & ?|?( ifstream & is, _Istream_Squoted f );
-ifstream & ?|?( ifstream & is, _Istream_Sstr f );
-static inline ifstream & ?|?( ifstream & is, _Istream_Swidth f ) { return is | *(_Istream_Sstr *)&f; }
+forall( istype & | basic_istream( istype ) ) {
+	istype & ?|?( istype & is, _Istream_Squoted f );
+	istype & ?|?( istype & is, _Istream_Sstr f );
+	static inline istype & ?|?( istype & is, _Istream_Swidth f ) { return is | *(_Istream_Sstr *)&f; }
+}
 
 // Concatenation
Index: libcfa/src/collections/string_res.cfa
===================================================================
--- libcfa/src/collections/string_res.cfa	(revision 234c4328242f343169846cf6693f3c5807ae5b67)
+++ libcfa/src/collections/string_res.cfa	(revision 3f631d63dc8a3d8d5bd5e664c971d336878cb507)
@@ -193,15 +193,18 @@
 
 // Output operator
-ofstream & ?|?(ofstream & out, const string_res & s) {
+forall( ostype & | basic_ostream( ostype ) )
+ostype & ?|?( ostype & out, const string_res & s ) {
 	// CFA string is NOT null terminated, so print exactly lnth characters in a minimum width of 0.
 	return out | wd( 0, s.Handle.lnth, s.Handle.s ) | nonl;
 }
 
-void ?|?(ofstream & out, const string_res & s) {
-	(ofstream &)(out | s); ends( out );
+forall( ostype & | basic_ostream( ostype ) )
+void ?|?( ostype & out, const string_res & s ) {
+	(ostype &)(out | s); ends( out );
 }
 
 // Input operator
-ifstream & ?|?(ifstream & in, string_res & s) {
+forall( istype & | basic_istream( istype ) )
+istype & ?|?( istype & in, string_res & s ) {
 	// Reading into a temp before assigning to s is near zero overhead in typical cases because of sharing.
 	// If s is a substring of something larger, simple assignment takes care of that case correctly.
@@ -245,5 +248,6 @@
 }
 
-ifstream & ?|?( ifstream & is, _Istream_Rquoted f ) with( f.rstr ) {
+forall( istype & | basic_istream( istype ) )
+istype & ?|?( istype & is, _Istream_Rquoted f ) with( f.rstr ) {
 	if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 	int args;
@@ -270,5 +274,6 @@
 }
 
-ifstream & ?|?( ifstream & is, _Istream_Rstr f ) {
+forall( istype & | basic_istream( istype ) )
+istype & ?|?( istype & is, _Istream_Rstr f ) {
  	// .---------------,
  	// | | | | |...|0|0| null terminator and guard if missing
Index: libcfa/src/collections/string_res.hfa
===================================================================
--- libcfa/src/collections/string_res.hfa	(revision 234c4328242f343169846cf6693f3c5807ae5b67)
+++ libcfa/src/collections/string_res.hfa	(revision 3f631d63dc8a3d8d5bd5e664c971d336878cb507)
@@ -16,5 +16,5 @@
 #pragma once
 
-#include <fstream.hfa>
+#include <iostream.hfa>
 #include <string.h>    // e.g. strlen
 
@@ -120,7 +120,10 @@
 
 // IO Operator
-ofstream & ?|?(ofstream & out, const string_res & s);
-void ?|?(ofstream & out, const string_res & s);
-ifstream & ?|?(ifstream & in, string_res & s);
+forall( ostype & | basic_ostream( ostype ) ) {
+	ostype & ?|?(ostype & out, const string_res & s);
+	void ?|?(ostype & out, const string_res & s);
+}
+forall( istype & | basic_istream( istype ) )
+istype & ?|?(istype & in, string_res & s);
 
 struct _Istream_Rwidth {
@@ -167,7 +170,9 @@
 	_Istream_Rstr & ignore( _Istream_Rstr & f ) { f.flags.ignore = true; return (_Istream_Rstr &)f; }
 } // distribution
-ifstream & ?|?( ifstream & is, _Istream_Rquoted f );
-ifstream & ?|?( ifstream & is, _Istream_Rstr f );
-static inline ifstream & ?|?( ifstream & is, _Istream_Rwidth f ) { return is | *(_Istream_Rstr *)&f; }
+forall( istype & | basic_istream( istype ) ) {
+	istype & ?|?( istype & is, _Istream_Rquoted f );
+	istype & ?|?( istype & is, _Istream_Rstr f );
+	static inline istype & ?|?( istype & is, _Istream_Rwidth f ) { return is | *(_Istream_Rstr *)&f; }
+}
 
 // Concatenation
