D - Streaming in D
- Matthias Becker (78/78) Nov 20 2003 I thought a bit about how to do streaming in D. As you can't write globa...
I thought a bit about how to do streaming in D. As you can't write global operators, my first thought was using traits. This wouldn't be a problem in D, as it supports templates and specialization. But I haven't testet D's abilitys concerning that. Is it possible to specialize templates in multiple modules? But than I rememberd, that Object has a methode toString(), that could be used. So D's streams could accept an Object. But what if you haven't implemented toString()? Than you wouldn't get an error, but "Object" would be written into the stream. This is a stupid behavior. The implementation of toString should do something like assert(0); In my opinion all methodes of Object should be implemented like this. Perhaps a interface like ConvertableToString might be an option. So streams would accept objects that implement this interface. This interface only provides the methode toString(). So you know whether a object is realy convertable to string or not. Well, it seems a bit strange as Object already has a toString(). But as it can be used without warnings or errors this seems to be the only safe way. Back to the traits idea. It might look like the folowing (not tested): // in modul template_meta (should become part of std) class YesType {} class NoType {} template IsInternalType (T) { typedef NoType YesNo; } template IsInternalType (T : byte) { typedef YesType YesNo; } template IsInternalType (T : ubyte) { typedef YesType YesNo; } template IsInternalType (T : short) { typedef YesType YesNo; } template IsInternalType (T : ushort) { typedef YesType YesNo; } template IsInternalType (T : int) { typedef YesType YesNo; } template IsInternalType (T : uint) { typedef YesType YesNo; } template IsInternalType (T : long) { typedef YesType YesNo; } template IsInternalType (T : ulong) { typedef YesType YesNo; } template IsInternalType (T : float) { typedef YesType YesNo; } template IsInternalType (T : double) { typedef YesType YesNo; } template IsInternalType (T : real) { typedef YesType YesNo; } template IsInternalType (T : ireal) { typedef YesType YesNo; } template IsInternalType (T : creal) { typedef YesType YesNo; } template IsInternalType (T : char) { typedef YesType YesNo; } template IsInternalType (T : wchar) { typedef YesType YesNo; } // Strings count as special internal type template IsInternalType (T : char[]) { typedef YesType YesNo; } template IsInternalType (T : wchar[]){ typedef YesType YesNo; } // In modul stream_traits import std.template_meta; template StreamWriteTrait (T) { void writeToStream (T object, Stream stream) in { assert (stream.writable()); } body { stream.write (object.toString()); } template StreamReadTraitImplementation (T, U : YesType) { void readFromStream (out T object, Stream stream) body { stream.read (object); } } template StreamReadTraitImplementation (T, U : NoType) { void readFromStream (out T object, Stream stream) body { char [] temp; stream.read (temp); object = new T (temp); } } template StreamReadTrait (T) { instance IsInternalType (T) isInternal; instance StreamReadTraitImplementation (T, isInternal.YesNo) implementation; void readFromStream (out T object, Stream stream) in { assert (stream.readable()); } body { implementation.readFromStream (object, stream); } } // You have to specialize StreamReadTrait and StreamWriteTrait for your own types // if the default version doesn't fit.
Nov 20 2003