Boost logo

Boost :

Subject: Re: [boost] [iostreams]ANNOUNCE:indent_filtering_ostream.zip in vault
From: Larry Evans (cppljevans_at_[hidden])
Date: 2010-01-13 14:46:22


On 01/13/10 11:17, dherring_at_[hidden] wrote:
> On Tue, 12 Jan 2010, Larry Evans wrote:
>> On 01/12/10 11:29, dherring_at_[hidden] wrote:
>>> On Mon, 11 Jan 2010, vicente.botet wrote:
>>>> From: "Larry Evans" <cppljevans_at_[hidden]>
>>>>>
>>>>> The .zip file in subject is here:
>>>>>
>>>>> http://www.boostpro.com/vault/index.php?&directory=Input%20-%20Output
>>>>>
>> [snip]
>>> I wrote a similar utility, but made different tradeoffs. The basic
>>> usage looks like
>>>
>>> Indentation nl; // takes optional max depth and depth/level params
>>> Indentation::Indent in(nl); // could have used a reference notation
>>> Indentation::Outdent out(nl);
>>> std::ostream os;
>>> os << nl "class x
>>> << nl << '{' << in /* or nl.in */
>>> << nl << "int x;"
>>> << nl << "int y;" << out
>>> << nl << "};"
>>>
>>> Rationale:
>>> - operator++ and operator-- don't mix "as expected" with operator<<
>>
>> The functions provided in the indent_filtering_ostream.hpp include:
>>
>> indent_in
>> indent_out
>
> Ok, I didn't see these; I just looked at the previous email's example.
>
>
>>> - distinguishes between indenting and normal newlines
>>
>> I'm not sure what this means. Does it mean that to indent
>> a line, you have to use nl, as shown in this snippet of the code
>> you posted:
>>
>> > << nl << "int x;"
>>
>> If so, then I'm not sure that's an advantage. Could you
>> please elaborate on what you mean?
>
> Yes. In my work, this is a great advantage. People don't like text
> with trailing whitespaces, but they want blank lines for visual separation.

Doesn't:

   os<<nl<<"\n"

produce trailing whitespace whose length is the current indentation
level which is stored somewhere in nl. Hmm... What's the return
type from os<<nl. I'm guessing it must be typeof(nl)& because
otherwise, how would the change in indentation be communicated from
the <<out at the end of the output line:

   << nl << "int y;" << out

Could you clarify how out changes the indentation? Does it modify
the nl that occurs at the beginning?

>
> I could see an argument for having \n indent and nl not; it may make it
> easier to compose indentation with output functions that do not
> understand it. However, my experience has been that an indenting
> newlines semantically belong before the line text while a traditional \n
> appears after the text. This creates a mismatch; a general indentation
> tool should probably have a (scoped) mechanism for switching behaviors.
>
> Example: (pseudo C++)
> // code oblivious to indentation
> ostream & operator<<(ostream &os, vector<int> &v)
> {
> for(x=v.begin(); x!=v.end(); x++)
> os << x << "\n";
> return os;
> }
> // pretty printing
> void pretty(Struct s)
> {
> out << nl << "Struct s" << indent
> << nl << "x=" << s.x
> << nl << "vector=" << indent // one item per line
> << nl << s.vector << outdent
> << nl << "y=" << s.y << outdent;
> }
>
> This will give
> Struct s
> x=5
> vector=
> 1
> 2
> 3
>
> y=6
>
> Note the undesired newline.

IIUC, nl outputs 1st a '\n' and *then* prints the indentation
spaces? Thus the specialization of operator<< for vector<int>
ends in a newline which is then followed by another newline
produced by the << nl here:

       << nl << "y=" << s.y << outdent;

Is that right.

However, I don't see where the indentation for the vector comes
from because there's no calls to nl in the operator<< specializtion
for vector<int>. Am I missing something?

Anyway, I've used the proposed boost indent_ostream (or really it's
predecessor) to print out nested structures such as your Struct s in the
past. IIRC, the last element printed in a struct has no trailing
nl. The task of appending the nl is left to the caller. This
protocol is illustrated by the attachment, whose output is:

{
Struct
   x=5
   v=vector<int>
     1
     2
     3
   y=6
}

> But if nl appears in the traditional \n
> location, you have the issue of undesired indentation (the inner printer
> has to anticipate outdents in the outer) or extra buffering to clean
> such mistakes.

OK, but I still don't see how your 'nl' and 'out' and 'in' solve the
problem better than the solution shown in the attachment.

>
> I have had the best results by putting nl first and defining "pretty
> printers" that use it for each type I want to print.
>

But I thought the pseudo code above and the supposed output
demonstrate that it *does* produce the extra newline after the
vector print. IOW, as I said, I don't syet ee an advantage of
using 'nl,out,in'.

>
>>> - possible to maintain several indentation systems
>>
>> Could you describe when this would be an advantage?
>
> This is rarely useful, but there are times when indentation
> differentiates between classes of output line. This is naturally
> represented by having one indentation object per class.

Couldn't this be handled by defining operator<< for each class?

-Larry




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