Re: [boost] [review] string convert

Hi, are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion? If it is the first I could accept names as convert_cast or convert_to. If it is the second, I don't think it is appropriated to use this generic form and something in the name must recall this feature. lexical_cast is used for exactly this purpose and the name is appropriated. How could we rename the Boost.Convert library? Boost.StreamConvert? and the operations? Best, vicente

Vicente BOTET wrote:
are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion?
I've been considering it the former. Why does using a stream to make the conversion affect that? _____ Rob Stewart robert.stewart@sig.com Software Engineer using std::disclaimer; Dev Tools & Components Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On 5/5/2011 12:45 PM, Stewart, Robert wrote:
Vicente BOTET wrote:
are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion?
I've been considering it the former. Why does using a stream to make the conversion affect that?
Same here. And lexical_cast may be reimplemented with optimized type-to-type specializations. Nothing in the name requires it to be type-to-stream-to-type. -Matt

On 5-5-2011 19:50, Matthew Chambers wrote:
On 5/5/2011 12:45 PM, Stewart, Robert wrote:
Vicente BOTET wrote:
are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion?
I've been considering it the former. Why does using a stream to make the conversion affect that?
Same here. And lexical_cast may be reimplemented with optimized type-to-type specializations. Nothing in the name requires it to be type-to-stream-to-type.
I fully agree with type-to-type conversions. Regards, Barend

Message du 05/05/11 19:48 De : "Stewart, Robert" A : "'boost@lists.boost.org'" Copie à : Objet : Re: [boost] [review] string convert
Vicente BOTET wrote:
are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion?
I've been considering it the former. Why does using a stream to make the conversion affect that?
The fact that we want to add some formatting parameters, apply manipulators and so on to a generic interface disturb me.
- T convert_cast(S, formatting = none); can throw - T convert_cast(S, T, formatting = none) - optional name_me_1(S, formatting = none) - optional name_me_1(S, T, formatting = none) - pair name_me_2(S, T, formatting = none)
I would prefer to don't pay for these defaulted parameters in the generic case. Maybe I'm wrong, but the manipulators are only useful when converting from a string or to a string. If this is the case, all the stream stuff should be moved to a string conversion interface. I would even prefer that the stream part stay away and independent. In another post I proposed to use an istream proxy when converting from a string to a type as_istream(str) >> std::hex >> i; For conversions from a type to a string, we can use an ostream proxy, which is implicitly convertible to string. string str = as_ostream() << std::hex << i; Best, Vicente

On 5/5/2011 3:17 PM, Vicente BOTET wrote:
Message du 05/05/11 19:48 De : "Stewart, Robert" A : "'boost@lists.boost.org'" Copie à : Objet : Re: [boost] [review] string convert
Vicente BOTET wrote:
are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion?
I've been considering it the former. Why does using a stream to make the conversion affect that?
The fact that we want to add some formatting parameters, apply manipulators and so on to a generic interface disturb me.
- T convert_cast(S, formatting = none); can throw - T convert_cast(S, T, formatting = none) - optional name_me_1(S, formatting = none) - optional name_me_1(S, T, formatting = none) - pair name_me_2(S, T, formatting = none)
I would prefer to don't pay for these defaulted parameters in the generic case.
Maybe I'm wrong, but the manipulators are only useful when converting from a string or to a string. If this is the case, all the stream stuff should be moved to a string conversion interface. I would even prefer that the stream part stay away and independent. In another post I proposed to use an istream proxy when converting from a string to a type
as_istream(str)>> std::hex>> i;
For conversions from a type to a string, we can use an ostream proxy, which is implicitly convertible to string.
string str = as_ostream()<< std::hex<< i;
Conversions from strings to primitives and vice versa will vastly outnumber other type-to-types. If we're going to bias the interface in some way, I believe in doing it for the general case. And unless I'm missing something, the as_xstream syntax has the same implicit conversion problem that the convert<T>::from<S>() syntax has. Other kinds of type-to-type conversion that aren't better served by numeric_cast (unless you're proposing to wrap numeric_cast with boost.conversion?) are practically edge cases, aren't they? We can allow the interface to support them, but we shouldn't reduce it to the lowest common denominator when the general requirements are higher. Also, the string conversion will be optimized for the common cases: integral<->string and floating<->string. Lexical_cast's current stream-only implementation won't suffice. Basically, I think type-to-stream-to-type should be the fallback mechanism if no specialization is available. And of course sometimes even that fallback mechanism will fail with UDTs. -Matt

Message du 05/05/11 22:57 De : "Matthew Chambers" A : boost@lists.boost.org Copie à : Objet : Re: [boost] [review] string convert
On 5/5/2011 3:17 PM, Vicente BOTET wrote:
Message du 05/05/11 19:48 De : "Stewart, Robert" A : "'boost@lists.boost.org'" Copie à : Objet : Re: [boost] [review] string convert
Vicente BOTET wrote:
are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion?
I've been considering it the former. Why does using a stream to make the conversion affect that?
The fact that we want to add some formatting parameters, apply manipulators and so on to a generic interface disturb me.
- T convert_cast(S, formatting = none); can throw - T convert_cast(S, T, formatting = none) - optional name_me_1(S, formatting = none) - optional name_me_1(S, T, formatting = none) - pair name_me_2(S, T, formatting = none)
I would prefer to don't pay for these defaulted parameters in the generic case.
Maybe I'm wrong, but the manipulators are only useful when converting from a string or to a string. If this is the case, all the stream stuff should be moved to a string conversion interface. I would even prefer that the stream part stay away and independent. In another post I proposed to use an istream proxy when converting from a string to a type
as_istream(str)>> std::hex>> i;
For conversions from a type to a string, we can use an ostream proxy, which is implicitly convertible to string.
string str = as_ostream()<< std::hex<< i;
Conversions from strings to primitives and vice versa will vastly outnumber other type-to-types. If we're going to bias the interface in some way, I believe in doing it for the general case. And unless I'm missing something, the as_xstream syntax has the same implicit conversion problem that the convert::from() syntax has.
Hrr, you are right for the as_ostream It will be great if we could write str << as_ostream() << std::hex<< i; and str >> as_iistream() >> std::hex>> i; In these cases there will not be implicit conversion. Another possibility is to have a string converter that follows the numeric converter pattern template (*...*) struct converter { static result_type convert ( argument_type s ) ; result_type operator() ( argument_type s ) const ; // other specific functions }
Other kinds of type-to-type conversion that aren't better served by numeric_cast (unless you're proposing to wrap numeric_cast with boost.conversion?) are practically edge cases, aren't they? We can allow the interface to support them, but we shouldn't reduce it to the lowest common denominator when the general requirements are higher.
Well, this is the intent of my library Boost.Conversion. If you think that this is not useful, I have lost client ;-)
Also, the string conversion will be optimized for the common cases: integral<->string and floating<->string. Lexical_cast's current stream-only implementation won't suffice. Basically, I think type-to-stream-to-type should be the fallback mechanism if no specialization is available. And of course sometimes even that fallback mechanism will fail with UDTs.
Boost.conversion fallback mechanism for convert_to is a call to the explicit conversion Target(rhs). If the user wants another kind of conversion he must overload the convert_to function. If the user think that two types can be converted using lexical_cast, numeric_cast or other specific mechanism, he will need to make an overload and forward to the corresponding cast. I like this generic interface, as it allows to name all the conversions the same way. If more sophisticated conversion are needed it will be better to use a string converter, numeric converter or any other specific mechanism. Well, this is how I see this conflicting subject. Best, Vicente

Vicente BOTET wrote:
De : "Stewart, Robert"
Vicente BOTET wrote:
are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion?
I've been considering it the former. Why does using a stream to make the conversion affect that?
The fact that we want to add some formatting parameters, apply manipulators and so on to a generic interface disturb me.
I see.
- T convert_cast(S, formatting = none); can throw - T convert_cast(S, T, formatting = none) - optional name_me_1(S, formatting = none) - optional name_me_1(S, T, formatting = none) - pair name_me_2(S, T, formatting = none)
I would prefer to don't pay for these defaulted parameters in the generic case.
I mentioned before that overloading can avoid such concerns. If you don't supply any formatting, then you get the simpler implementation. If you do, you get the more complicated implementation. Maybe there should be distinct names for each set in order to clarify that they work differently. Obviously, to use manipulators requires the use of a stream. Without them, other implementations are possible, though some l10n functionality is needed still for string<->type conversions.
Maybe I'm wrong, but the manipulators are only useful when converting from a string or to a string. If this is the case, all the stream stuff should be moved to a string conversion interface. I would even prefer that the stream part stay away and independent.
Maybe. First, there's the lexical_cast approach to always convert (or, in the modern interpretation, as if) via a stream. In that design, manipulators can influence the resulting conversion. Second, string<->type conversions are an extremely important use case.
In another post I proposed to use an istream proxy when converting from a string to a type
as_istream(str) >> std::hex >> i;
I do find that interesting, but does it offer enough benefit relative to the following? std::istringstream s; s >> std::hex >> i;
For conversions from a type to a string, we can use an ostream proxy, which is implicitly convertible to string.
string str = as_ostream() << std::hex << i;
That is troublesome. However, we could create a more efficient form of std::ostringstream: string str; converting_ostream(str) << std::hex << i; Obviously, move semantics make using std::ostringstream just as efficient, though slightly less convenient: std::ostringstream s; s << std::hex << i; string const str(s.str()); If operator <<() returned std::ostringstream, it could be streamlined still more: string const str((ostringstream() << std::hex << i).str()); _____ Rob Stewart robert.stewart@sig.com Software Engineer using std::disclaimer; Dev Tools & Components Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Message du 06/05/11 13:31 De : "Stewart, Robert" A : "'boost@lists.boost.org'" Copie à : Objet : Re: [boost] [review] string convert
Vicente BOTET wrote:
De : "Stewart, Robert"
Vicente BOTET wrote:
are we discussing here a generic interface from type-to-type or one that uses an intermediary stream to make the conversion?
I've been considering it the former. Why does using a stream to make the conversion affect that?
The fact that we want to add some formatting parameters, apply manipulators and so on to a generic interface disturb me.
I see.
- T convert_cast(S, formatting = none); can throw - T convert_cast(S, T, formatting = none) - optional name_me_1(S, formatting = none) - optional name_me_1(S, T, formatting = none) - pair name_me_2(S, T, formatting = none)
I would prefer to don't pay for these defaulted parameters in the generic case.
I mentioned before that overloading can avoid such concerns.
You are right, overloading could be used, I missed this point.
If you don't supply any formatting, then you get the simpler implementation. If you do, you get the more complicated implementation.
Maybe there should be distinct names for each set in order to clarify that they work differently. Obviously, to use manipulators requires the use of a stream. Without them, other implementations are possible, though some l10n functionality is needed still for string<->type conversions.
Maybe I'm wrong, but the manipulators are only useful when converting from a string or to a string. If this is the case, all the stream stuff should be moved to a string conversion interface. I would even prefer that the stream part stay away and independent.
Maybe. First, there's the lexical_cast approach to always convert (or, in the modern interpretation, as if) via a stream. In that design, manipulators can influence the resulting conversion. Second, string<->type conversions are an extremely important use case.
lexical cast hides the stream usage, but we have ios << source; ios >> target; If we want to support type-to-type via stream and manimulators we will need to be able to do in the implementation ios << omn_1 << ... << omnp_n << source; ios >> imnp_1 >> ... >> imnp_k >> target; As far as I perceive the Boost.Convert library the manipulators are used either to convert to a string or from a string. I have not see deeply hwat allows the converter class. Can someone tell me if the reviewed interface can be used to make such type-to-type conversions?
In another post I proposed to use an istream proxy when converting from a string to a type
as_istream(str) >> std::hex >> i;
I do find that interesting, but does it offer enough benefit relative to the following?
std::istringstream s; s >> std::hex >> i;
I have no problems with that. I was just proposing a one-line solution.
For conversions from a type to a string, we can use an ostream proxy, which is implicitly convertible to string.
string str = as_ostream() << std::hex << i;
That is troublesome. However, we could create a more efficient form of std::ostringstream:
string str; converting_ostream(str) << std::hex << i;
Yes this could be useful.
Obviously, move semantics make using std::ostringstream just as efficient, though slightly less convenient:
std::ostringstream s; s << std::hex << i; string const str(s.str());
If operator <<() returned std::ostringstream, it could be streamlined still more:
string const str((ostringstream() << std::hex << i).str()); It usually is.
We could also define an operation that takes the stream and extract a type returning the value instead of requesting a variable int i = extract(str >> ios >> std::hex) string str = extract(ios << std::hex << i); With this interface we can add in a single expression output manipulators and input manipulators. Best, Vicente

Vicente BOTET wrote:
lexical cast hides the stream usage, but we have
ios << source; ios >> target;
If we want to support type-to-type via stream and manimulators we will need to be able to do in the implementation
ios << omn_1 << ... << omnp_n << source; ios >> imnp_1 >> ... >> imnp_k >> target;
As far as I perceive the Boost.Convert library the manipulators are used either to convert to a string or from a string. I have not see deeply hwat allows the converter class. Can someone tell me if the reviewed interface can be used to make such type-to-type conversions?
It is one way and, you're right, that's an issue.
We could also define an operation that takes the stream and extract a type returning the value instead of requesting a variable
int i = extract(str >> ios >> std::hex)
OK. To make str >> ios work requires something like this: convert::iostream & operator >> (std::string const &, convert::iostream &);
string str = extract(ios << std::hex << i);
OK, that works if convert::iostream holds a std::string, or wraps a std::ostringstream, which extract can access.
With this interface we can add in a single expression output manipulators and input manipulators.
That offers convenience and a lot of flexibility. Furthermore, convert_cast, try_converting_to*, etc. can be specified as using the convert::iostream mechanism, by default, relying on default stream formatting. That would provide a convenient, well understood fallback mechanism while leaving room for customized conversions for particular types. More concretely, the non-stream interfaces can use a converter class to effect the conversions. That class can have a primary specialization that uses convert::iostream to effect the conversion with no special formatting, thereby defaulting to using the IOStreams-based insertion and extraction operators for the source and target types. Specializations of the converter class can provide optimized conversions for particular types or type pairs. Then, if that converter class were also the functor type, there would be a single point of customization for all supported conversions, stream-based and not. _____ Rob Stewart robert.stewart@sig.com Software Engineer using std::disclaimer; Dev Tools & Components Susquehanna International Group, LLP http://www.sig.com * "try_converting_to" is a better name than "try_convert_to." IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
participants (4)
-
Barend Gehrels
-
Matthew Chambers
-
Stewart, Robert
-
Vicente BOTET