On Tue, Oct 21, 2003 at 09:25:46AM +0000, Angus Leeming wrote:
> Andre Poenitz wrote:
> >> Is this just a wild flight of fancy, or does anybody else think
> >> that it's a sensible proposal?
> > 
> > I think this could be handled on a case-by-case base by using some
> > helper functions in the insets that really need it.
> 
> Actually, I did some reading and I think I have stumbled across 
> something very powerful.
> 
> The C++ streams allow us to define arbitrary new modifiers --- and 
> enable subsequent operations on the stream to be aware of them. For 
> example, the code below would be used
>         std::ostringstream os;
>         os << font::setFamily(font::SERIF) << "Andr? "
>            << font::setFamily(font::SANS_SERIF) << "P?nitz\n";

I know this in theory but never managed to work with that in praxi.

I wanted to transform the different "math output stream" to a scheme
like that at one point of time but then got distracted somehow...

> Note that it works on existing stream types!!! Thereafter one would 
> need to write a 'decipherer'. For example, something to establish the 
> width of the string in this font, or to paint it, but the beauty is 
> that this 'mark-up' is entirely separate.

Not really, is it?

You just modify some state of the stream (i.e. to "SERIF"). Than every
write on that stream has to check this state and respond to it.

It is not a kind of out-of-band signalling, rather some fancy way to add
more data room to a stream.

This safes you writing lots of 'operator<<' for the standard types like
int, double, ... fro your custom streams, but that's it.

> class setFamily {
> public:
>         static int getAlloc() { return xalloc_id_; }
> 
>         explicit setFamily(Family family) : family_(family) {}
>         friend std::ostream & operator<<(std::ostream &, setFamily const &);
> private:
>         Family family_;
>         static int const xalloc_id_;
> };
> 
> int const setFamily::xalloc_id_ = std::ios_base::xalloc();
> 
> std::ostream & operator<<(std::ostream & os, setFamily const & sf)
> {
>         os.iword(CName::GetAlloc()) = sf.family_;
>         return os;
> }

And now you've got some new state in the stream object. It does not
affect the data buffer at all. This is basically only syntactic sugar
over

   void write(ostream & os, MyObject const &, SomeExtraData const & extra)

by combining 'os' and 'extra' and re-using operator<<() for the base
types.

Andre'

-- 
Those who desire to give up Freedom in order to gain Security, will not have,
nor do they deserve, either one.     (T. Jefferson or B. Franklin or both...)

Reply via email to