Boost logo

Boost :

From: Jonathan Turkanis (technews_at_[hidden])
Date: 2004-09-08 22:41:21


"Jonathan Turkanis" <technews_at_[hidden]> wrote in message
news:chalsi$cmb$1_at_sea.gmane.org...
>
> "Rob Stewart" <stewart_at_[hidden]> wrote in message
> news:200409031905.i83J5JU21799_at_lawrencewelk.systems.susq.com...
> > From: "Jonathan Turkanis" <technews_at_[hidden]>
> > > "Thorsten Ottosen" <nesotto_at_[hidden]> wrote in message
>
> > > One of the original motivations for introducing the i/o categories (they
> turned
> > > out to be useful for a lot of other things) was to avoid having separate
> > > functions push_filter and push_resource. I consider it a major
> simplification of
> > > the interface.
> >
> > I agree with Thorsten that some means of ensuring that parts
> > aren't assembled in the wrong order would be helpful. Whether
> > that means separate functions, or detection of the type of object
> > being pushed, it seems like preventing misuse should be a bigger
> > priority than "a major simplification of the interface."
>
> I'm not sure I follow. You already get a runtime error if you try to add a
> filter or resource to a chain that is already complete. This is mention in the
> specification for push (see http://tinyurl.com/49j6u) E.g.,
>
> filtering_ostream out;
> out.push(zlib_compressor());
> out.push(file_sink("hello.z"));
> out.push(base64_encoder()); // error !!
> out.push(tcp_sink(www.microsoft.com, 80)); // error !!
>
> Isn't this enough? (Maybe it should be an assertion failure instead of an
> exception.)
>
> Perhaps you would like a compile-time error instead. Note that having separate
> functions for pushing filters and resources would not help in that case. To
> generate a compile-time error would require that the types of all the filters
> and resources be encoded into the type of the filtering stream. This was
> suggested last year by Larry Evans and recently by Robert Ramey (if I
understood
> hime correctly.)
>
> The problems are:
>
> - much more complex interface
> - less flexible a runtime
> - neglible gain in efficiency, since most filtering operations aren't
inlineable
>
> Finally, it's already the programmer's responsibility to ensure that the
filters
> are added in the right order -- no amount of template magic will guarantee
> this -- so making sure to add the resource at the end is not much of an extra
> burden.
>
> > There are plenty of places where one can misuse existing
> > libraries, including the Standard Library, so perhaps requiring
> > that protection from this library is misguided. So, here's
> > another approach: perhaps you could create a set of overloaded
> > make_* functions that take a varying number of filter arguments
> > followed by an optional (via overloading) resource argument.
> > Then, those functions can ensure that if there is a resource, it
> > is push()'d last.
>
> Yes, that would work. There are two versions I can think of:
>
> 1. Orginally I had a function link(...) which created an inline chain of
filters
> and resources, but I eliminated it to make the library smaller. It didn't
occur
> to me to add a compile-time check that the last element was a resource; in
fact,
> I thought it would also be useful for chaining filters alone. However, this
> might be a good reason to restore the function link, with the added check.
>
> 2. Dietmar Kuehl mentioned a piping syntax originall proposed by JC van
Winkel.
> E.g.,
>
> filtering_stream
> out( base64_encoder() | zlib_compressor() | file_sink("file") );
>
> This syntax, too, could be modified to do a compile-time check that the last
> item in the chain is a resource.
>
> I like both of these ideas as a syntactic convenience but not as a way to
> enforce at compile time that resources are added last. For this enforcement to
> have teeth, it would be necessary to remove the stack interface, which would
be
> considered 'unsafe'. But the stack interface is natural and convenient, and
> essential for some purposes.
>
> For example, a natural way to implement a compression stream would be to
derive
> from a filtering stream and push a compression filter onto the stack in the
> stream's constructor. Templated open and close functions would then be
> implemented by pushing and popping resources:
>
> struct zlib_ostream : filtering_ostream {
> zlib_ostream() { push(zlib_compressor()); }
>
> template<typename Source>
> zlib_ostream(const Source& src )
> {
> push(zlib_compressor());
> open(src);
> }
>
> template<typename Source>
> void open(const Source& src )
> {
> BOOST_STATIC_ASSERT(is_resource<src>::value);
> push(src);
> }
>
> bool is_open() const { return is_complete(); }
>
> template<typename Source>
> void close(const Source& src )
> {
> assert(is_open());
> pop();
> }
> };
>
> I sort of feel like I'm beating a dead horse :-) Is a runtime error (or
> assertion failure) sufficient, or do you feel strongly that there needs to be
a
> compile-time check?
>
> Jonathan
>
>
>
>
>
>
>
>
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk