Boost logo

Boost :

From: John Torjo (john.lists_at_[hidden])
Date: 2004-09-22 02:24:41


Reece Dunn wrote:

> John Torjo wrote:
>
>> Hi Reece,
>>
>> This just popped into my head. A lot of confusion seems to come from
>> how you pass decorators. What I'm trying to say is that it can be very
>> difficult to get the decorator strings right (especially for more
>> complex things like XML) from the first time.
>>
>> I would suggest every formatter takes only one string which parses and
>> finds all decorators itself.
>> Each formatter will have one or more escape sequences which it uses to
>> find the decorators.
>>
>> Something like:
>>
>> // in this case, '%' is used for identifying an element
>> // '*' is to mean "leave default" (don't change)
>>
>> std::vector<int> v;
>> // equivalent to your "[ ", ", ", " ]"
>> std::cout << formatob(v, "[ %, % ]");
>
>
> This looks good :) On the implementation side it would require splitting

Great!

> the string into the 2/3 components and constructing the decorators
> accordingly. Maybe defining an "extract_decorators" function internally,
> so wrapper_decorators and sequence_decorators can process this
> internally. How about:
>
> std::cout << io::object( v )( "[ %, % ]" );
>
> I am sure this would be feasible.
>
>> // eq. to "<< ", " | ", " >>"
>> std::cout << formatob(v, "<< % | % >>");
>>
>> // set only open/close decorators
>> std::cout << formatob(v, "<< %*% >>");
>
>
> Here, you would need special handling of string == "*". This should also
> be implementable.

Basically I just gave examples. You need to have two code characters:
- one to specify an element
- one to specify a "leave as default"

>
>> // sets only the separator
>> std::cout << formatob(v, "*% | %*");
>>
>> // for pair - you have "%1" and "%2"
>> std::vector< std::pair<int,long> > vp;
>> // write XML
>> std::cout << formatob(vp,
>> containerfmt("<elem> % </elem><elem> % </elem>",
>> pairfrt("<int>%1</int><long>%2</long>")));
>
>
> Here, you don't need %1 and %2. You just do: "<int>%</int><long>%</long>".

That would work. But what if you want second element and then first
element, like:
<long>%2</long><int>%1</int>

>
>> How's that?
>
>
> In terms of implementability, I don't see a problem. The two issues I
> have are:
> [1] What are the performance penalties for this?

Man, you really worry too much about performance ;)

Imagine that you do the parsing only once per print - which compared to
the rest of the output is really nothing.

Second of all, you should be able to hold the decorators inside the
stream object as well. Thus, you'll only do parsing once - keep
decorators internally and then use them for each print.

> [2] What if you want '%' or '*' in your format string, e.g. "[ a * b * c
> ]"? You would thus need to implement some sort of escaping capability.

Of course ;)

>
> NOTE: This could sit along side using the 'decorate' function and
> Volodya's idea for expressions, e.g.:
>
> io::object( v,
> "<<" + fmt::container( fmt::pair()( "<a>%</a><b>%</b>" )) + " >>"
> ).decorate( " : " );
> // output: << <a>2.75</a><b>1</b> : <a>3.14159</a><b>7</b> >>
>

Since this seems to me *much simpler* to use the the other ideas, I
don't thik you'd really need this. But it's up to you.

Best,
John

-- 
John Torjo
-- john_at_[hidden]
Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.4 - save_dlg - true binding of your data to UI controls!
    + easily add validation rules (win32gui/examples/smart_dlg)

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