www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: file i/o in a variety of languages

Andrei:
 The open() method saves on reallocating the refcounted
 structured stored inside the File.

Thank you for your answer. So the API is designed a bit larger than necessary for performance reasons. This the reformatted first part of the interesting implementation of File: struct File { private struct Impl { FILE* handle = null; uint refs = uint.max / 2; string name = null; this(FILE* h, uint r, string n) { handle = h; refs = r; name = n; } } private Impl* p; this(string name, in char[] stdioOpenmode="rb") { p = new Impl(errnoEnforce(.fopen(name, stdioOpenmode), text("Cannot open file `", name, "' in mode `", stdioOpenmode, "'")), 1, name); } ~this() { if (!p) return; if (p.refs == 1) close; else --p.refs; } this(this) { if (!p) return; assert(p.refs); ++p.refs; } void opAssign(File rhs) { swap(p, rhs.p); } void open(string name, in char[] stdioOpenmode="rb") { detach; auto another = File(name, stdioOpenmode); swap(this, another); } Few comments: I am slowly starting to understand the purpose of that Impl :-) It allows to use File as as a class instance, as it is by reference. According to D specs on the site, inner structs contain an extra scope pointer, so this may be better: private static struct Impl { I have seen the same problem in other parts of Phobos (see bug http://d.puremagic.com/issues/show_bug.cgi?id=4087 ). open() contains: auto another = File(name, stdioOpenmode); That calls File.this(), so isn't it creating a new Impl anyway? I don't understand the performance gain still. Given the presence of opAssign, I presume this code: auto another = File(name, stdioOpenmode); swap(this, another); May be written just as: this = File(name, stdioOpenmode); Bye and thank you, bearophile
Aug 27 2010