From: Aurélien on 7 Jun 2010 00:04 Hello, Some days ago, I decided that it would be fun to write a `streambuf` subclass that would use `mmap` and read-ahead. I looked at how my STL (SGI) implemented `filebuf` and realized that `basic_filebuf` contains a `FILE*`. So inheriting from `basic_filebuf` is out of the question. So I inherited from `basic_streambuf`. Then i wanted to bind my `mmapbuf` to a fstream. I thought the only thing that I would have to do would be to copy the implicit interface of `filebuf`... but that was a clear mistake. In the SGI, basic_fstream owns a `basic_filebuf`. No matter if I call `basic_filestream.std::::ios::rdbuf( streambuf* )`, the filestream completely ignores it and uses its own `filebuf`. So now I'm a bit confused... sure, I can create my own `mmfstream`, that would be the exact copy/paste of the `fstream` but that sounds really no DRY-oriented. What I can't understand, is: **why does `fstream` is so tightly coupled with `filebuf`, so that it is not possible to use anything else than a `filebuf`?** The whole point of separating streams and bufs is that one can use a stream with a different buffer. Solutions: => `filestream` should rely on the implicit interface of `filebuf`. That is, fstream should be templated by a streambuf class. That would allow everyone to provide its own streambuf subclass to a `fstream` as long as it implements `filebuf`'s implicit interface. Problem: we cannot add a template parameter to `fstream` since it would break template selectors while using `fstream` as template template parameter. => `filebuf` should be a pure virtual class without any additional attributes. So that one can inherit from it without carrying all its FILE* garbage. Your ideas on the subject ? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Ulrich Eckhardt on 8 Jun 2010 02:42 Aurélien wrote: > Some days ago, I decided that it would be fun to write a `streambuf` > subclass that would use `mmap` and read-ahead. Others thought so, too, at least e.g. STLport does this and I guess also any other implementation of rank and name. BTW: Even using a FILE* you can already use memory mapping! > I looked at how my STL (SGI) implemented `filebuf` and realized that > `basic_filebuf` contains a `FILE*`. So inheriting from `basic_filebuf` > is out of the question. > > So I inherited from `basic_streambuf`. Then i wanted to bind my > `mmapbuf` to a fstream. I wouldn't do that, because an fstream already includes a filebuf which would then be unused. Of course, you can redirect the fstream to a different filebuf, but that would be kind of useless. Instead, use a simple iostream which you pass a pointer to the streambuf in its constructor. Or, you create a class mmapfstream, publicly derived from iostream and containing an mmapfilebuf, which then gives the streambuf to the baseclass using rdbuf()[1]. You then forward calls to open/close to the streambuffer, just like fstream does. > I thought the only thing that I would have to do would be to copy the > implicit interface of `filebuf`... but that was a clear mistake. In > the SGI, basic_fstream owns a `basic_filebuf`. No matter if I call > `basic_filestream.std::::ios::rdbuf( streambuf* )`, the filestream > completely ignores it and uses its own `filebuf`. That would be a bug in the implementation, if I understand you correctly, which in turn I'm not 100% sure I do. Show some code and I'll be able to tell you. > So now I'm a bit confused... sure, I can create my own `mmfstream`, > that would be the exact copy/paste of the `fstream` but that sounds > really no DRY-oriented. True, but I'm afraid that's the way to go. > What I can't understand, is: **why does `fstream` is so tightly > coupled with `filebuf`, so that it is not possible to use anything > else than a `filebuf`?** The whole point of separating streams and > bufs is that one can use a stream with a different buffer. Actually, it never hurt me in practice. The code that makes up fstream, ifstream and ofstream is so little that it actually doesn't hurt repeating it when you create your own versions thereof, most of the actual code is in the streambuffer. Cheers! Uli [1] You can't pass the streambuffer to the baseclass because the streambuffer's constructor has not been called at that time, hence you must switch it later (e.g. in the constructor's body) using rdbuf()! Sator Laser GmbH Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932 -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: VisualC++ vs GCC: read in a number in exponential notation Next: Critique of code quality |