|
Boost : |
Subject: Re: [boost] Boost.Convert+Boost.Parameter
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2009-02-28 10:57:22
Hi,
the Boost.Range library introduce the concept of adaptor (or view). I'm wondering if this could be also convenient for the Boost.Convert library.
Take the uuid user data type.
uuid u;
string res;
u | corverted_to<string> | uppercased > res;
The evaluation should be lazy, only when we assign throwg the > operator we force the evaluation.
or
string str;
int i = str | radix(10) | locale(...) | converted_to<int>;
Could this approach work for the Boost.Convert library?
Best
Vicente
----- Original Message -----
From: "Vladimir Batov" <batov_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Saturday, February 28, 2009 2:37 PM
Subject: Re: [boost] Boost.Convert+Boost.Parameter
>
>> From: "Andrey Semashev" <andrey.semashev_at_[hidden]>
>> Just to restate my opinion, I don't quite like the "to" and "from" names.
>> At least "from", in your notation, is confusing to me.
>
> Yes, I remember. :-) We happen to like different things. So far I find
> to/from the cleanest of all the alternatives. Somehow you insist on
>
> int i = convert<int>(str)
>
> that in turn I do not find that great. ;-)
>
>> 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:
>>
>> namespace user {
>> struct uuid;
>> }
>>
>> user::uuid u;
>> std::string str = convert::to< std::string >(u);
>>
>> Do you plan to support this use case? How would you suggest the "casual
>> user" to extend the conversion to
>>
>> 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. 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;
> }
>
>> without support from the underlying conversion implementation for
>> user::uuid?
>
>>> unlike I/O Stream-based approach which allows the user to write his own
>>> manipulator and deploy it like
>>>
>>> int i = convert::from(str, -1) >> my_special_formatter;
>>
>> 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 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. People somehow have survived
> without exlicitly naming every parameter and convert(str, -1) does not look
> the trickiest of all. And somehow you are not that concerned with the
> verbosity any more. I remember
>
> boost::string::from(s, -1);
>
> seemed long. Now
>
> convert::from(s, default = -1);
>
> does not seem that long at all. Nuh, that "immediate recognize-ability"
> pitch somehow does not stick with me. Sorry.
>
>> 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?
>
>> That way the default value really gets lost in the arguments. So, unless
>> we move to an alternative syntax, I'm for making it a named parameter as
>> well:
>>
>> int i = convert::from(str, default_ = -1, radix_ = 10, locale_= ...);
>
> Yes, in this setting all parameters kinda asking for a name. A different
> style I guess. I am not sure it's growing on me. We'll see.
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk