Boost logo

Boost :

Subject: Re: [boost] Boost.Convert+Boost.Parameter
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2009-02-28 10:22:20


Vladimir Batov wrote:

>> I don't understand what exactly you are trying to achieve. The
>> conversion logic has to be concentrated somewhere,
>
> The conversion logic for user-defined typed is often merely to provide
> op>> and op<< (as lexical_cast integrates user types). When one needs
> more, additional conversion logic is often concentrated in I/O Stream
> manipulators.
>
>> and I think it should be somewhere related to the source or the target
>> type. In the nearby thread we were discussing conversion of
>> user-defined types:
>>
>> std::string str = convert::to< std::string >(u, uppercase_ = true);
>
> Yes, it's is a typical case. All needed to have it integrated is to
> provide op>> and op<<. That is
>
> std::ostream& operator<<(std::ostream& str, uuid const& id)
> {
> str << id.as_string();
> return str;
> }
>
> and a similar op>> get uuid integrated. I.e. nothing close to the
> complexity of your example.

I'm all for using the user-defined operator<< for default
lexical_cast-style conversion. The code snippet I posted did not support
it as I did not invest much time in it.

What isn't clear to me is how the more elaborate cases will be covered
by your library.

> If you need additional (like "uppercase")
> configuration, one writes uppercase manipulator that will pass an
> additional parameter to op<<. Like
>
> string s = convert::to<string>(uuid) >> uppercase;
>
> std::ostream& operator<<(std::ostream& str, uuid const& id)
> {
> ...extract uppercase command from the stream...
> str << id.as_string();
> return str;
> }

Two notes regarding this:
1. If I understand you correctly, the "casual" user won't be able to
extend the conversion, because the operator<< defined by the uuid
developer still has to know what kind of hint the manipulator may have
put into the stream.
2. It's not clear to me how the conversion hint will be put into the
stream. What's behind the "...extract uppercase command from the
stream..." line?

>> Do I understand correctly that the manipulators are used to format or
>> parse the input by defining their streaming operators? If so, then how
>> do the manipulators compose with each other? If I write:
>>
>> int i = convert::from(str, -1) >> my_special_formatter
>> >> my_super_special_formatter;
>>
>> which one will be called?
>
> They are called in the order or their appearance. Sometimes it matters,
> sometimes it does not. Like std::ws (enabled by default) needs to be first.

I assume, you mean that the manipulators don't actually do
formatting/parsing, but instead do something tricky with the stream, am
I right?

If so, it begins to look like you're trying to invent a run-time
alternative to Boost.Parameter with a different syntax.

>> I think that the default value should be immediately recognizable. The
>> default_ keyword does that. There were alternative syntax suggestions
>> that provided that, too. I think, we should strive to the cleanest
>> interface we can provide.
>
> Oh, well, sounds great... but I am not sure. Feels like you are chasing
> that immediate recognize-ability a bit too hard.

You asked my opinion, didn't you? :)

>> If you declare conversion functions with Boost.Parameter macros, you
>> will be able to get rid of the inner parenthesis:
>>
>> int i = convert::to<int>(str, radix_ = 10, locale_= ...);
>> int i = convert::from(str, -1, radix_ = 10, locale_= ...);
>
> Yes, I know. I am not that keen though... and does not it have some
> limit on the number of arguments?

Well, everything has its limits. Are up to 10 arguments limiting for
you? 20? 50? Since we're talking about syntax nuances, trying to polish
the interface, having more than 10 arguments for type conversion is a
bit out of line, no matter how these arguments are specified.


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