Formal Review Request: Boost.String.Convert

Well, the fishing trip did not work out. :-\ Therefore, I would like to request a formal review for the Boost.String.Convert functionality. I've uploaded the file called boost-string-convert.zip to the Vault (http://www.boostpro.com/vault/index.php). It has the conversion-related header, the test/usage executable and the documentation (MS Word, HTML). Compiled on Linux and Visual Studio 2008. At the bottom is the "motivation" introductory section from the docs. There is very little of actually code, so you might just read it rather that suffering through my document mumble. Currently-known issues. 1) The attention was given to the behavior (to provide simple/advanced conversion-failure check, throw/no-throw behavior, locale, formatting) and not to the efficiency. I am sure people will come up with ways to run this damn thing much faster. I am very much looking forward to your contributions as I do not really feel I am any good at it. 2) I've implemented the recently suggested boost::stirng::convert() interface but that might need some additional work to handle corner cases correctly. I promise to look into it in due course. I would like to thank everyone participated in the lexica_cast and boost::string::convert-related discussions and expressing their views and opinions and coming up with suggestions. All of them were heard, considered and much and truly appreciated. I apologize if in the end it does not look out as you might like to see it. I swear, your contributions were not in vain. Thanks, Vladimir. Motivation I had a need for a convenient and uniform facility to convert values to and from a literal textual form. Such a need is common when converting between internal (to a program) data types and their external representations. Typical applications would be reading of configuration files, packing and unpacking internal data to and from, say, XML, etc. The boost::lexical_cast looked very promising and was the preferred solution compared to others (such as C functions, std::stringstream, etc., see the lexical_cast documentation for more discussion about alternatives). Unfortunately, I needed functionality beyond what lexical_cast was providing (configurable throw/no-throw behavior, formatting support, locale support, etc.). After discussions on the Boost developers list and with the lexical_cast author (Kevlin Henney) and the maintainer (Alexander Nasonov) it was collectively decided that the required functionality extensions were not compatible with the idea of what lexical_cast embodied and a more dedicated family of conversion functions with richer interfaces was needed. That decision resulted in the development of the following header-only string-conversion library described in this document: boost::string::convert() The interface is explicit about its purpose ? string-related -- string-to-type and type-to-string -- conversions. It builds on the lexical_cast past experience, offers the already familiar conversion functionality and more: · throw and no-throw conversion-failure handling behavior; · support for the default value to be returned when conversion fails; · formatting support based on the standard (or user-defined) manipulators (like std::hex, std::scientific, etc.); · locale support; · support for various (boost::range-compliant) char and wchar_t-based containers (std::string, std::wstring, char const*, wchar_t const*, char array[], std::vector<char>, etc.); · no DefaultConstructibility requirement for the Target type; · room to grow.

I like the idea of a library for converting to and from strings. I have two comments: 1) I don't like the string namespace. I would prefer to use boost::to_string and boost::from_string: std::string s=boost::to_string(x) reads better than std::string s=boost::string::to(x). 2) What's the motivation for the convert function? Is it supposed to convert anything to anything? (It seems to me the motivation is to mimic the lexical_cast functionality but I don't think that's necessary.) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
I like the idea of a library for converting to and from strings.
I have two comments:
1) I don't like the string namespace. I would prefer to use boost::to_string and boost::from_string:
std::string s=boost::to_string(x)
reads better than
std::string s=boost::string::to(x).
We had a hot discussion on the naming issue just recently. http://article.gmane.org/gmane.comp.lib.boost.devel/185961 The outcome was that to_string/from_string are not verbs, are slightly longer than convert and duplicate the namespace name; to/from are meaningless without the surrounding namespace name, which may be omitted or mangled with aliases.
2) What's the motivation for the convert function? Is it supposed to convert anything to anything? (It seems to me the motivation is to mimic the lexical_cast functionality but I don't think that's necessary.)
The convert function will eventually convert different things to strings and vice versa. So far conversion between strings and numeric types and between strings of different types were extensively discussed. The background for not extending lexical_cast is also expressed in the initial post of the aforementioned thread.

On Tue, Feb 17, 2009 at 14:19, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote:
I like the idea of a library for converting to and from strings.
I have two comments:
1) I don't like the string namespace. I would prefer to use boost::to_string and boost::from_string:
std::string s=boost::to_string(x)
reads better than
std::string s=boost::string::to(x).
We had a hot discussion on the naming issue just recently.
http://article.gmane.org/gmane.comp.lib.boost.devel/185961
The outcome was that to_string/from_string are not verbs, are slightly longer than convert and duplicate the namespace name; to/from are meaningless without the surrounding namespace name, which may be omitted or mangled with aliases.
Is that really the outcome? The from and to functions are still there, and still confusing. I'm much prefer to_string, especially since string::to is the opposite meaning of what std::bitset and every java programmer expect from "to" in the context of strings. I'm still not sure why we're stuck with such a lexical-cast-like interface anyways. Every single example is always used to assign to a variable, and since the functions have to be returning proxies anyways (since it's apparently possible to add manipulators) you often can't pass directly to functions because of template argument deduction issues. Using an output parameter would free up the return value for success, which may well be more natural. It also trivially avoids the default construction problem...

On Tue, Feb 17, 2009 at 11:19 AM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
The outcome was that to_string/from_string are not verbs, are slightly longer than convert and duplicate the namespace name; to/from are meaningless without the surrounding namespace name, which may be omitted or mangled with aliases.
Are you saying that boost::string::to(x) reads better than boost::to_string(x)?
2) What's the motivation for the convert function? Is it supposed to convert anything to anything? (It seems to me the motivation is to mimic the lexical_cast functionality but I don't think that's necessary.)
The convert function will eventually convert different things to strings and vice versa.
You can convert different things to string using to_string. You can convert different things from strings using from_string. My question is, what is the motivation for the convert function? What's the use case for it that doesn't work with to_string/from_string? Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Tuesday, February 17, 2009 2:39 PM Emil Dotchevski wrote:
My question is, what is the motivation for the convert function? What's the use case for it that doesn't work with to_string/from_string?
That was my suggestion to account for both conversion directions and eliminate "string" from the name, thus opening the interface to other conversions. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Tue, Feb 17, 2009 at 11:43 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
On Tuesday, February 17, 2009 2:39 PM Emil Dotchevski wrote:
My question is, what is the motivation for the convert function? What's the use case for it that doesn't work with to_string/from_string?
That was my suggestion to account for both conversion directions and eliminate "string" from the name, thus opening the interface to other conversions.
An interface that converts anything to anything else is a separate issue, and requires a separate discussion. If we concentrate on converting from and to string, I think that two families of functions, to_string and from_string is the most logical approach. When I want a string, I know that I want a string and at that time I don't care about any other conversions. I can't think of a use case when I might want a string but might also want something else. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Tuesday, February 17, 2009 2:51 PM Emil Dotchevski wrote:
On Tuesday, February 17, 2009 2:39 PM Emil Dotchevski wrote:
My question is, what is the motivation for the convert function? What's the use case for it that doesn't work with to_string/from_string?
That was my suggestion to account for both conversion
On Tue, Feb 17, 2009 at 11:43 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote: directions and eliminate "string" from the name, thus opening the interface to other conversions.
An interface that converts anything to anything else is a separate issue, and requires a separate discussion.
If we concentrate on converting from and to string, I think that two families of functions, to_string and from_string is the most logical approach. When I want a string, I know that I want a string and at that time I don't care about any other conversions. I can't think of a use case when I might want a string but might also want something else.
The arguments, whether function or template, would specify the conversion to apply. For example, to_string<int>(s) could also be written as convert<int>(s). (Both can be rearranged to take two arguments and return a bool, for example, so the point is merely to eliminate directionality and "string" from the name.) _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Tue, Feb 17, 2009 at 11:55 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
On Tuesday, February 17, 2009 2:51 PM Emil Dotchevski wrote:
On Tuesday, February 17, 2009 2:39 PM Emil Dotchevski wrote:
My question is, what is the motivation for the convert function? What's the use case for it that doesn't work with to_string/from_string?
That was my suggestion to account for both conversion
On Tue, Feb 17, 2009 at 11:43 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote: directions and eliminate "string" from the name, thus opening the interface to other conversions.
An interface that converts anything to anything else is a separate issue, and requires a separate discussion.
If we concentrate on converting from and to string, I think that two families of functions, to_string and from_string is the most logical approach. When I want a string, I know that I want a string and at that time I don't care about any other conversions. I can't think of a use case when I might want a string but might also want something else.
The arguments, whether function or template, would specify the conversion to apply. For example, to_string<int>(s) could also be written as convert<int>(s). (Both can be rearranged to take two arguments and return a bool, for example, so the point is merely to eliminate directionality and "string" from the name.)
I don't buy this. In general, converting to_string requires formatting specifiers, etc. If the semantics of convert() are that it can convert anything to anything, it needs a way to configure the conversion, and I don't see how all this can be crammed into a single practical interface for all types (and even if that's possible, it's outside of the scope of this discussion IMO.) I'd much rather treat to_string and from_string not as synonyms of convert(), but as two independent interfaces (meaning, two separate HPP files: to_string.hpp and from_string.hpp) each designed for its specific task. These two conversions are important enough to justify this special attention. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

on Tue Feb 17 2009, Emil Dotchevski <emildotchevski-AT-gmail.com> wrote:
For example, to_string<int>(s) could also be written as convert<int>(s).
Probably just a slip of the mind, but: to_string doesn't need a template parameter. Explicitly writing to_string<int>(s) is probably a bad idea and convert<int> would correspond to from_string<int>(s). However, maybe we ought to ask why this keeps happening. I think there's something about the convert<...>(...) interface that confuses people. Eliminating directionality might not be such a hot idea. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
on Tue Feb 17 2009, Emil Dotchevski <emildotchevski-AT-gmail.com> wrote:
For example, to_string<int>(s) could also be written as convert<int>(s).
Probably just a slip of the mind, but:
to_string doesn't need a template parameter.
Actually, it does, since I might want different string types to get. Right now there are string and wstring, and more are coming in C++0x.

On Tue, Feb 17, 2009 at 12:33 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
David Abrahams wrote:
on Tue Feb 17 2009, Emil Dotchevski <emildotchevski-AT-gmail.com> wrote:
For example, to_string<int>(s) could also be written as convert<int>(s).
Probably just a slip of the mind, but:
to_string doesn't need a template parameter.
Actually, it does, since I might want different string types to get. Right now there are string and wstring, and more are coming in C++0x.
I've needed to convert things specifically to std::string plenty of times to justify a simple interface where to_string returns std::string. I want to be able, in a header file, to just say: struct foo; std::string to_string( foo const & ); std::string to_string( foo const &, fmt ); and be done with it. In my mind, the motivation for such an interface is to standardize what fmt is (so that users have a consistent way of formatting foos and bars) and to provide helper functions for dealing with (and possibly extending) fmt (so that it's easy to implement converting foo to a string.) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Tuesday, February 17, 2009 5:59 PM Emil Dotchevski wrote:
On Tue, Feb 17, 2009 at 12:33 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
David Abrahams wrote:
to_string doesn't need a template parameter.
Actually, it does, since I might want different string types to get. Right now there are string and wstring, and more are coming in C++0x.
I've needed to convert things specifically to std::string plenty of times to justify a simple interface where to_string returns std::string. I want to be able, in a header file, to just say:
struct foo; std::string to_string( foo const & ); std::string to_string( foo const &, fmt );
Both are possible with std::string being implemented via ordinary functions and wstring and others via function templates. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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.

Emil Dotchevski wrote:
to_string doesn't need a template parameter. Actually, it does, since I might want different string types to get. Right now there are string and wstring, and more are coming in C++0x.
I've needed to convert things specifically to std::string plenty of times to justify a simple interface where to_string returns std::string. I want to be able, in a header file, to just say:
struct foo; std::string to_string( foo const & ); std::string to_string( foo const &, fmt );
and be done with it.
That simplification as absolutely not acceptable for me, as I convert to wstring just about as often as to string. I think that the library should provide flexibility in this aspect. You can create a tiny wrapper around it, if you only need narrow strings.

On Wed, Feb 18, 2009 at 9:26 AM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote:
to_string doesn't need a template parameter.
Actually, it does, since I might want different string types to get. Right now there are string and wstring, and more are coming in C++0x.
I've needed to convert things specifically to std::string plenty of times to justify a simple interface where to_string returns std::string. I want to be able, in a header file, to just say:
struct foo; std::string to_string( foo const & ); std::string to_string( foo const &, fmt );
and be done with it.
That simplification as absolutely not acceptable for me, as I convert to wstring just about as often as to string. I think that the library should provide flexibility in this aspect. You can create a tiny wrapper around it, if you only need narrow strings.
What I had in mind is that foo could implement to_string or to_wstring or both, and the library would supply generic overloads of to_string/to_wstring that would kick-in as needed. So, if I give you: std::string to_string( foo const & ); then after you include foo.hpp and presumably boost/to_string.hpp, you can say foo x; std::wstring s=to_wstring(x); which would bind to boost::to_wstring (since there isn't a foo overload of to_wstring) which would do the conversion using the foo to_string overload. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
What I had in mind is that foo could implement to_string or to_wstring or both, and the library would supply generic overloads of to_string/to_wstring that would kick-in as needed. So, if I give you:
std::string to_string( foo const & );
then after you include foo.hpp and presumably boost/to_string.hpp, you can say
foo x; std::wstring s=to_wstring(x);
which would bind to boost::to_wstring (since there isn't a foo overload of to_wstring) which would do the conversion using the foo to_string overload.
Hmm... No, that doesn't look very useful either. My common practice of operator<< definition is to define it as a template on the character type, like this: struct foo { template< typename CharT, typename TraitsT > friend std::basic_ostream< CharT, TraitsT >& operator<< ( std::basic_ostream< CharT, TraitsT >& strm, foo const& x); }; This allows to find the operator via ADL and have the common implementation for any character type under the same name (operator<< in this case). I would expect the same level of flexibility from the proposed library. Even more, I'd like it to use the operators if they are already defined for the class.

On Wed, Feb 18, 2009 at 1:03 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote:
What I had in mind is that foo could implement to_string or to_wstring or both, and the library would supply generic overloads of to_string/to_wstring that would kick-in as needed. So, if I give you:
std::string to_string( foo const & );
then after you include foo.hpp and presumably boost/to_string.hpp, you can say
foo x; std::wstring s=to_wstring(x);
which would bind to boost::to_wstring (since there isn't a foo overload of to_wstring) which would do the conversion using the foo to_string overload.
Hmm... No, that doesn't look very useful either. My common practice of operator<< definition is to define it as a template on the character type, like this:
struct foo { template< typename CharT, typename TraitsT > friend std::basic_ostream< CharT, TraitsT >& operator<< ( std::basic_ostream< CharT, TraitsT >& strm, foo const& x); };
This allows to find the operator via ADL and have the common implementation for any character type under the same name (operator<< in this case).
I would expect the same level of flexibility from the proposed library. Even more, I'd like it to use the operators if they are already defined for the class.
You can still do this with what I am proposing. When someone does foo x; std::string s=to_string(x); this would bind to the foo to_string overload if available, if not it would bind to the foo/ostream overload of << if available, etc. The idea is to automatically pick the best conversion available to produce the string the caller needs. This makes the to_string library implementation more complex, but the benefit is that it is possible to define simple, non-template to_string overloads for various types. The reason I like that is because I don't have to put to_string implementations in headers. Also, it makes it very easy to integrate 3rd party types into the framework. Suppose you have something like: class bar { public: std::string getstr() const; private: ... }; and you want to integrate it into the to_string framework. All you have to do is (presumably you can't alter bar itself): std::string to_string( bar const & x ) { return x.getstr(); } (note, no coupling between the above to_string overload and the to_string library) and now you can do: bar x; std::wstring s=to_wstring(x); //the library handles string->wstring conversion automatically. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
You can still do this with what I am proposing. When someone does
foo x; std::string s=to_string(x);
this would bind to the foo to_string overload if available, if not it would bind to the foo/ostream overload of << if available, etc. The idea is to automatically pick the best conversion available to produce the string the caller needs.
This makes the to_string library implementation more complex, but the benefit is that it is possible to define simple, non-template to_string overloads for various types. The reason I like that is because I don't have to put to_string implementations in headers.
Also, it makes it very easy to integrate 3rd party types into the framework. Suppose you have something like:
class bar { public: std::string getstr() const; private: ... };
and you want to integrate it into the to_string framework. All you have to do is (presumably you can't alter bar itself):
std::string to_string( bar const & x ) { return x.getstr(); }
(note, no coupling between the above to_string overload and the to_string library) and now you can do:
bar x; std::wstring s=to_wstring(x); //the library handles string->wstring conversion automatically.
And what if I write my own class outer_bar that owns bar and also want to be ostreamable? I would have to duplicate my operator<< in order to call either to_string or to_wstring, wouldn't I? struct outer_bar { bar b_; friend std::ostream& operator<< ( std::ostream& s, outer_bar const& ob) { return s << to_string(ob.b_); } friend std::wostream& operator<< ( std::wostream& s, outer_bar const& ob) { return s << to_wstring(ob.b_); } }; Things will get even worse with char16_t and char32_t. Why not make it a template? It would still cover your case just fine: struct outer_bar { bar b_; template< typename CharT, typename TraitsT > friend std::basic_ostream< CharT, TraitsT >& operator<< ( std::basic_ostream< CharT, TraitsT >& strm, outer_bar const& ob) { typedef std::basic_string< CharT, TraitsT > string_t; return s << convert< string_t >(ob.b_); } }; And supporting bar for the templated "convert" is no less difficult than what you suggested: template< typename StringT > StringT convert(bar const & x); template< > std::string convert(bar const & x) { return x.getstr(); } template< > std::wstring convert(bar const & x) { return convert< std::wstring >(convert< std::string >(x)); } The equivalent of the latter specialization will be needed in your approach, too. If the library is clever enough, it may be done in generic manner in the library itself.

On Wed, Feb 18, 2009 at 2:05 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote:
You can still do this with what I am proposing. When someone does
foo x; std::string s=to_string(x);
this would bind to the foo to_string overload if available, if not it would bind to the foo/ostream overload of << if available, etc. The idea is to automatically pick the best conversion available to produce the string the caller needs.
This makes the to_string library implementation more complex, but the benefit is that it is possible to define simple, non-template to_string overloads for various types. The reason I like that is because I don't have to put to_string implementations in headers.
Also, it makes it very easy to integrate 3rd party types into the framework. Suppose you have something like:
class bar { public: std::string getstr() const; private: ... };
and you want to integrate it into the to_string framework. All you have to do is (presumably you can't alter bar itself):
std::string to_string( bar const & x ) { return x.getstr(); }
(note, no coupling between the above to_string overload and the to_string library) and now you can do:
bar x; std::wstring s=to_wstring(x); //the library handles string->wstring conversion automatically.
And what if I write my own class outer_bar that owns bar and also want to be ostreamable? I would have to duplicate my operator<< in order to call either to_string or to_wstring, wouldn't I?
No. You can define template operator<< or you can define non-template std::string overload of operator<< only. The user would still be able to call to_wstring, which will bind to a wstring overload if it's available. If not, the generic to_wstring overload will call the std::string operator<< overload, and then convert the result to wstring. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
And what if I write my own class outer_bar that owns bar and also want to be ostreamable? I would have to duplicate my operator<< in order to call either to_string or to_wstring, wouldn't I?
No.
You can define template operator<<
How is that?
or you can define non-template std::string overload of operator<< only. The user would still be able to call to_wstring, which will bind to a wstring overload if it's available. If not, the generic to_wstring overload will call the std::string operator<< overload, and then convert the result to wstring.
But I will lose generic ostreamability for my class then. Sorry, I just don't see any advantages for differently named functions.

On 18 Feb 2009, at 22:16, Andrey Semashev wrote:
Emil Dotchevski wrote:
And what if I write my own class outer_bar that owns bar and also want to be ostreamable? I would have to duplicate my operator<< in order to call either to_string or to_wstring, wouldn't I? No. You can define template operator<<
How is that?
or you can define non-template std::string overload of operator<< only. The user would still be able to call to_wstring, which will bind to a wstring overload if it's available. If not, the generic to_wstring overload will call the std::string operator<< overload, and then convert the result to wstring.
But I will lose generic ostreamability for my class then. Sorry, I just don't see any advantages for differently named functions.
I find differently named functions important for readability and correctness, particularly in templated generic code. Wouldn't it be easy to add 'to' and 'from' functions as simple wrappers around 'convert', for those who want them? Chris

Christopher Jefferson wrote:
On 18 Feb 2009, at 22:16, Andrey Semashev wrote:
But I will lose generic ostreamability for my class then. Sorry, I just don't see any advantages for differently named functions.
I find differently named functions important for readability and correctness, particularly in templated generic code.
Wouldn't it be easy to add 'to' and 'from' functions as simple wrappers around 'convert', for those who want them?
Well, such wrappers may be added, if wanted. But I don't think it should be the main interface of the library. Such wrappers would have a more narrow range of use cases, presumably, "to-string" and "from-string" conversions. For other kinds of conversions the terms "to" and "from" are really meaningless.

On Wed, Feb 18, 2009 at 2:16 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote:
And what if I write my own class outer_bar that owns bar and also want to be ostreamable? I would have to duplicate my operator<< in order to call either to_string or to_wstring, wouldn't I?
No.
You can define template operator<<
How is that?
What do you mean how? You just define a template operator<< and the library-supplied to_string/to_wstring templates will bind to it, assuming the user's calls to_string or to_wstring doesn't bind to a better overload of to_string/to_wstring.
or you can define non-template std::string overload of operator<< only. The user would still be able to call to_wstring, which will bind to a wstring overload if it's available. If not, the generic to_wstring overload will call the std::string operator<< overload, and then convert the result to wstring.
But I will lose generic ostreamability for my class then.
Even that's not necessarily true, as the library can provide generic ostream template operator<< overload that's implemented in terms of to_wstring or to_string or other available operator<< overloads. I know this is tricky business, but it's tricky for the library itself. From user's point of view it's much more straight-forward: they can call to_string, to_wstring, operator<<, whatever, and the library automatically picks the best way to get it done. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
And what if I write my own class outer_bar that owns bar and also want to be ostreamable? I would have to duplicate my operator<< in order to call either to_string or to_wstring, wouldn't I? No.
You can define template operator<< How is that?
What do you mean how? You just define a template operator<< and the library-supplied to_string/to_wstring templates will bind to it, assuming the user's calls to_string or to_wstring doesn't bind to a better overload of to_string/to_wstring.
Which of the to_string/to_wstring functions should I call from the operator<< template?
or you can define non-template std::string overload of operator<< only. The user would still be able to call to_wstring, which will bind to a wstring overload if it's available. If not, the generic to_wstring overload will call the std::string operator<< overload, and then convert the result to wstring. But I will lose generic ostreamability for my class then.
Even that's not necessarily true, as the library can provide generic ostream template operator<< overload that's implemented in terms of to_wstring or to_string or other available operator<< overloads.
It looks like you suggest that the library should implement wide streaming capability for all classes that it can reach (i.e. those have the narrow operator<<). Somehow, I don't quite like that kind of a "helping hand". I suspect it may introduce problems with efficiency, as it will have to unnecessarily transcode strings. It's difficult to make any hard statements at this point, but I also have a gut feeling that it may also introduce ambiguities between the library-provided and the user-provided operators. I'd prefer using templates.

On Wed, Feb 18, 2009 at 2:47 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote:
And what if I write my own class outer_bar that owns bar and also want to be ostreamable? I would have to duplicate my operator<< in order to call either to_string or to_wstring, wouldn't I?
No.
You can define template operator<<
How is that?
What do you mean how? You just define a template operator<< and the library-supplied to_string/to_wstring templates will bind to it, assuming the user's calls to_string or to_wstring doesn't bind to a better overload of to_string/to_wstring.
Which of the to_string/to_wstring functions should I call from the operator<< template?
If all you want is to implement operator<< template in terms of to_string/to_wstring, you won't have to do that because the library will do it for you. That is, if I give you a foo overload of to_string only, but you want to use operator<< for foo, all you'd have to do is include the appropriate header from the library and foo.hpp, and then you can call operator<< as needed, which in this case will forward your call to to_string.
or you can define non-template std::string overload of operator<< only. The user would still be able to call to_wstring, which will bind to a wstring overload if it's available. If not, the generic to_wstring overload will call the std::string operator<< overload, and then convert the result to wstring.
But I will lose generic ostreamability for my class then.
Even that's not necessarily true, as the library can provide generic ostream template operator<< overload that's implemented in terms of to_wstring or to_string or other available operator<< overloads.
It looks like you suggest that the library should implement wide streaming capability for all classes that it can reach (i.e. those have the narrow operator<<). Somehow, I don't quite like that kind of a "helping hand". I suspect it may introduce problems with efficiency, as it will have to unnecessarily transcode strings.
If this inefficiency is a problem, it can be easily addressed by introducing the appropriate optimal overloads. If not, you're arguing premature optimization. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
You can define template operator<< How is that? What do you mean how? You just define a template operator<< and the library-supplied to_string/to_wstring templates will bind to it, assuming the user's calls to_string or to_wstring doesn't bind to a better overload of to_string/to_wstring. Which of the to_string/to_wstring functions should I call from the operator<< template?
If all you want is to implement operator<< template in terms of to_string/to_wstring, you won't have to do that because the library will do it for you. That is, if I give you a foo overload of to_string only, but you want to use operator<< for foo, all you'd have to do is include the appropriate header from the library and foo.hpp, and then you can call operator<< as needed, which in this case will forward your call to to_string.
I'm confused. So, the users will have to specify to_string overloads instead of streaming operators?
It looks like you suggest that the library should implement wide streaming capability for all classes that it can reach (i.e. those have the narrow operator<<). Somehow, I don't quite like that kind of a "helping hand". I suspect it may introduce problems with efficiency, as it will have to unnecessarily transcode strings.
If this inefficiency is a problem, it can be easily addressed by introducing the appropriate optimal overloads. If not, you're arguing premature optimization.
That's right, overloads for all character types, which is the duplication I'm against.

On Wed, Feb 18, 2009 at 3:10 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote:
You can define template operator<<
How is that?
What do you mean how? You just define a template operator<< and the library-supplied to_string/to_wstring templates will bind to it, assuming the user's calls to_string or to_wstring doesn't bind to a better overload of to_string/to_wstring.
Which of the to_string/to_wstring functions should I call from the operator<< template?
If all you want is to implement operator<< template in terms of to_string/to_wstring, you won't have to do that because the library will do it for you. That is, if I give you a foo overload of to_string only, but you want to use operator<< for foo, all you'd have to do is include the appropriate header from the library and foo.hpp, and then you can call operator<< as needed, which in this case will forward your call to to_string.
I'm confused. So, the users will have to specify to_string overloads instead of streaming operators?
No. The users will be able to pick what they provide, and whether it is a template or not; the library will provide the rest.
It looks like you suggest that the library should implement wide streaming capability for all classes that it can reach (i.e. those have the narrow operator<<). Somehow, I don't quite like that kind of a "helping hand". I suspect it may introduce problems with efficiency, as it will have to unnecessarily transcode strings.
If this inefficiency is a problem, it can be easily addressed by introducing the appropriate optimal overloads. If not, you're arguing premature optimization.
That's right, overloads for all character types, which is the duplication I'm against.
Overloads for all character types can be provided through template operator<< overload. The whole point of overload resolution is that overloads can be as specific or as generic as needed, without the caller having to know about it. Apropos, one of the reasons why I dislike the convert<string> syntax is that it unnecessarily demands that the call binds to a template. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Tuesday, February 17, 2009 3:25 PM David Abrahams wrote:
on Tue Feb 17 2009, Emil Dotchevski <emildotchevski-AT-gmail.com> wrote:
For example, to_string<int>(s) could also be written as convert<int>(s).
Probably just a slip of the mind, but:
to_string doesn't need a template parameter. Explicitly writing to_string<int>(s) is probably a bad idea and convert<int> would correspond to from_string<int>(s).
However, maybe we ought to ask why this keeps happening. I think there's something about the convert<...>(...) interface that confuses people. Eliminating directionality might not be such a hot idea.
There have been too many names and variations of signature for anyone to keep anything straight at this point. convert() doesn't require specifying a template parameter. The source and destination types can be deduced from the arguments, though that means the selected parameter order will confuse one group or another. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Tuesday, February 17, 2009 3:10 PM Emil Dotchevski wrote:
On Tue, Feb 17, 2009 at 11:55 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
The arguments, whether function or template, would specify the conversion to apply. For example, to_string<int>(s) could also be written as convert<int>(s). (Both can be rearranged to take two arguments and return a bool, for example, so the point is merely to eliminate directionality and "string" from the name.)
I don't buy this. In general, converting to_string requires formatting specifiers, etc. If the semantics of convert() are that it can convert anything to anything, it needs a way to configure the conversion, and I don't see how all this can be crammed into a single practical interface for all types
Valid points. The question is whether other inter-type conversions may require configurability, even if not the same as for strings, such as influencing rounding, truncation, etc. If so, then there may yet be room for a generalized framework. If not, I'm fine with treating conversions to/from strings as special.
(and even if that's possible, it's outside of the scope of this discussion IMO.)
The discussion originated from the desire to improve upon lexical_cast for some particular use cases. I suggested the possibility of widening the scope beyond just string conversions. If there is no agreement to widen the scope, so be it. Don't throw out convert because it exceeds a scope not yet fully established.
I'd much rather treat to_string and from_string not as synonyms of convert(), but as two independent interfaces (meaning, two separate HPP files: to_string.hpp and from_string.hpp) each designed for its specific task. These two conversions are important enough to justify this special attention.
That's not a technical justification. It is preference. I suggested "convert" as an alternative to the to/from/to_string/from_string/whatever discussion. Whether it proves meritorious is another matter. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Tue, Feb 17, 2009 at 12:31 PM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
On Tuesday, February 17, 2009 3:10 PM Emil Dotchevski wrote: The discussion originated from the desire to improve upon lexical_cast for some particular use cases. I suggested the possibility of widening the scope beyond just string conversions. If there is no agreement to widen the scope, so be it. Don't throw out convert because it exceeds a scope not yet fully established.
If I'm not mistaken, the proposed library is about string conversions. The wider scope can't be understood or appreciated from within a to_string/from_string discussion. If you want to consider to_string and from_string a starting point for a more generic convert() interface, fine -- but that's still a separate interface that should be outside this discussion. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Tuesday, February 17, 2009 5:28 PM Emil Dotchevski wrote:
On Tuesday, February 17, 2009 3:10 PM Emil Dotchevski wrote: The discussion originated from the desire to improve upon lexical_cast for some particular use cases. I suggested the
On Tue, Feb 17, 2009 at 12:31 PM, Stewart, Robert <Robert.Stewart@sig.com> wrote: possibility of widening the scope beyond just string conversions. If there is no agreement to widen the scope, so be it. Don't throw out convert because it exceeds a scope not yet fully established.
If I'm not mistaken, the proposed library is about string conversions.
I wasn't denying that.
The wider scope can't be understood or appreciated from within a to_string/from_string discussion.
I disagree. Any discussion can be expanded if those involved so choose. I thought doing so valuable and so tried to encourage it.
If you want to consider to_string and from_string a starting point for a more generic convert() interface, fine -- but that's still a separate interface that should be outside this discussion.
We disagree on that point, obviously. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Tue, Feb 17, 2009 at 14:55, Stewart, Robert <Robert.Stewart@sig.com> wrote:
The arguments, whether function or template, would specify the conversion to apply. For example, to_string<int>(s) could also be written as convert<int>(s). (Both can be rearranged to take two arguments and return a bool, for example, so the point is merely to eliminate directionality and "string" from the name.)
Why is removing directionality from the name a good idea? It seems like implicit_cast, for example, exists precisely for the readability gain of being unidirectional instead of using the bidirectional static_cast.

On Tuesday, February 17, 2009 3:11 PM Scott McMurray wrote:
On Tue, Feb 17, 2009 at 14:55, Stewart, Robert <Robert.Stewart@sig.com> wrote:
The arguments, whether function or template, would specify
the conversion to apply. For example, to_string<int>(s) could also be written as convert<int>(s). (Both can be rearranged to take two arguments and return a bool, for example, so the point is merely to eliminate directionality and "string" from the name.)
Why is removing directionality from the name a good idea?
With just one name to remember -- the arguments can supply the rest -- the interface is simpler. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Tue, Feb 17, 2009 at 15:32, Stewart, Robert <Robert.Stewart@sig.com> wrote:
On Tuesday, February 17, 2009 3:11 PM Scott McMurray wrote:
Why is removing directionality from the name a good idea?
With just one name to remember -- the arguments can supply the rest -- the interface is simpler.
To continue my analogy, it would have been possible to only have static_cast and dynamic_cast, with the arguments supplying the rest, but it's better to make it clearer which can of conversion is being applied. "Convert" seems like it could make a very nice namespace/library name because of the same generality that makes me dislike it as a function name: convert::to_string<wstring>, convert::to_integral<int, rounding::down>, convert::transcode_string<wstring, native_mbcs>, ... Although convert might allow mix-fix relatively nicely: convert("5").to<int>(), ...

convert::to_string<wstring>, convert::to_integral<int, rounding::down>, convert::transcode_string<wstring, native_mbcs>, ...
How about convert::to<wstring> convert::to<int, rounding::down> convert::to<wstring, native_mbcs> I am serious. I actually like it. I understand you do not like my to/from but you are almost there. By eliminating the repetition (as for _string<wstring) we get a laconic and expressive (IMHO of course) interface. No need for various to_string, to_integral, transcode_string, etc. We get rid of the string namespace as well (it should be a plus isn't it?). So, it'd be int i = boost::convert::to<int>(str); // explicit 'int' type int i = boost::convert::to(str, -1); // deduced 'int' string s = boost::convert::to<string>(-1); // explicit std::string type string s = boost::convert::to(-1, "failed to convert"); // deduced std::string wstring s = boost::convert::to<wstring>(-1); // explicit std::wstring type wstring s = boost::convert::to(-1, L"failed to convert"); // deduced std::wstring Can you meet me half-way? I'll "give" you the string namespace "back" and you get to keep "_string" as spare for something else... looks like you get two things :-)... in case I again embarassed myself with my English I am trying to be humorous here... but I really think it might be a good way forward. The code is pleasant to read (IMHO), it leaves plenty of room for growth (like convert::to<int, rounding::down>). I really like it. All the functionality above is already in place. All that is needed is to change the namespace and get rid of the redundant convert().
Although convert might allow mix-fix relatively nicely: convert("5").to<int>(), ...
It looks clever. However, with the default/failure parameter it will probably be int i = convert("5").to(-1); Now it looks confusing... to me. Somehow I feel more comfortable with the example further up. V.

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Vladimir Batov Sent: 18 February 2009 09:45 To: boost@lists.boost.org Subject: Re: [boost] Formal Review Request: Boost.String.Convert
How about
convert::to<wstring> convert::to<int, rounding::down> convert::to<wstring, native_mbcs>
Why not just convert_to<wstring>? Is the problem with convert by itself that it leaves the reader worrying about 'to' and/or 'from'? - leaving one feeling 'what?' Direction matters. Paul --- Paul A. Bristow Prizet Farmhouse Kendal, UK LA8 8AB +44 1539 561830, mobile +44 7714330204 pbristow@hetp.u-net.com

convert::to<wstring>
Why not just convert_to<wstring>?
Is the problem with convert by itself that it leaves the reader worrying about 'to' and/or 'from'?
- leaving one feeling 'what?'
Direction matters.
Yes, once I got comfortable with boost::convert::to I realized that after generalization the 'from' is obviously redundant as string-from-int can always be transformed to int-to-string. So, 'from' died out. When only 'to' left, I asked myself what it was doing on its own. I do agree in principle that having direction helps (even only somewhat) but 'to' does not seem to work. It all starts nicely: string s = boost::convert::to<int>(-1) Above 'to' does seem natural (IMHO of course) as the line kind of reads as "convert to int". However, with the default parameter it becomes string s = boost::convert::to(-1, "failed to convert") i.e. 'to' becomes a nuisance. In that setting I much prefer string s = boost::convert(-1, "failed to convert") which answers the "convert what" question as it reads as "convert int". Granted, the conversion destination becomes somewhat subtle. However, I do not feel it is too subtle to get one confused. More so, I feel the convert family is well discriminated (with enable_if) so that Wstring WIDE_str = boost::convert(-1, "failed to convert") will not compile. Therefore, I feel very safe with just string s = boost::convert(-1, "failed to convert"). That thought took me all the way from boost::string::convert() to boost::convert(). That looks like a reasonable and logical compromise which might not be as nice as "convert::to<int>" but overall holds better. I am OK with that. Others..? V.

On Wednesday, February 18, 2009 6:56 AM Vladimir Batov wrote:
string s = boost::convert(-1, "failed to convert").
I am OK with that. Others..?
It looks promising, but I imagine there will be some pushback regarding polluting the boost namespace. Perhaps boost::conversion::convert()? Using declarations and namespace aliases can simplify the longer name when desired. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Wed Feb 18 2009, "Vladimir Batov" <batov-AT-people.net.au> wrote:
convert::to<wstring>
Why not just convert_to<wstring>?
Is the problem with convert by itself that it leaves the reader worrying about 'to' and/or 'from'?
- leaving one feeling 'what?'
Direction matters.
Yes, once I got comfortable with boost::convert::to I realized that after generalization the 'from' is obviously redundant as string-from-int can always be transformed to int-to-string. So, 'from' died out. When only 'to' left, I asked myself what it was doing on its own.
I do agree in principle that having direction helps (even only somewhat) but 'to' does not seem to work. It all starts nicely:
string s = boost::convert::to<int>(-1)
Above 'to' does seem natural (IMHO of course) as the line kind of reads as "convert to int". However, with the default parameter it becomes
string s = boost::convert::to(-1, "failed to convert")
i.e. 'to' becomes a nuisance.
Not just a nuisance; it reads incorrectly, as "convert to -1." I think it would be better to always require the destination type, so: boost::convert::to<string>(-1, "not convertible"); and using boost::convert::to; to<string>(-1, "not convertible); looks good, too. If you want a name without angle brackets, boost::convert::to_string(-1, "not convertible"); works for me. Hmm, how do I convert to a hex string? -- Dave Abrahams BoostPro Computing http://www.boostpro.com

David Abrahams wrote:
Hmm, how do I convert to a hex string?
Great question for both directions (to/from string). I hack lexical_cast each release to add: stream.setf( std::ios::fmtflags(), std::ios::basefield ); That gets me the from_string hex conversion which is what I need most often. -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com

On Wed, Feb 18, 2009 at 04:45, Vladimir Batov <batov@people.net.au> wrote:
convert::to_string<wstring>, convert::to_integral<int, rounding::down>, convert::transcode_string<wstring, native_mbcs>, ...
How about
convert::to<wstring> convert::to<int, rounding::down> convert::to<wstring, native_mbcs>
I am serious. I actually like it. I understand you do not like my to/from but you are almost there. By eliminating the repetition (as for _string<wstring) we get a laconic and expressive (IMHO of course) interface. No need for various to_string, to_integral, transcode_string, etc. We get rid of the string namespace as well (it should be a plus isn't it?).
Actually, I agree with your point from the later email that once you get rid of the suffixes, keeping the to is a waste. I'm just not convinced that convert(-1) tells me that I should be getting a std::string. I think it's equally (if not more) plausible that it should be some internationalizable string, be it std::wstring, std::u8string, or what. I also haven't thought through how the policies would need to work in a general function.
Can you meet me half-way? I'll "give" you the string namespace "back" and you get to keep "_string" as spare for something else... looks like you get two things :-)... in case I again embarassed myself with my English I am trying to be humorous here...
The smilie is deserved, but your English is fine here.
Although convert might allow mix-fix relatively nicely: convert("5").to<int>(), ...
It looks clever. However, with the default/failure parameter it will probably be
int i = convert("5").to(-1);
Now it looks confusing... to me. Somehow I feel more comfortable with the example further up.
convert("5").to_typeof(-1) or convert("5").defaulting_to(-1) seem quite reasonable. They clearly give the choice between throwing and non-throwing, too. I like the possibility of allowing .into(outvar), too, to avoid copyage (though rvalue refs may help with that). This one's growing on me...

On Wednesday, February 18, 2009 10:11 AM Scott McMurray wrote:
I'm just not convinced that convert(-1) tells me that I should be getting a std::string. I think it's equally (if not more) plausible that it should be some internationalizable string, be it std::wstring, std::u8string, or what.
It doesn't. I contend that should be convert(s, -1), where s is a std::string, or convert<std::string>(-1). Other, more verbose spellings are possible, of course.
too, to avoid copyage (though rvalue refs may help with that). ^^^^^^^
Now you're just going to confuse Vladimir by fabricating words. ;-) _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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.

2009/2/18 Stewart, Robert <Robert.Stewart@sig.com>
On Wednesday, February 18, 2009 10:11 AM Scott McMurray wrote:
I'm just not convinced that convert(-1) tells me that I should be getting a std::string. I think it's equally (if not more) plausible that it should be some internationalizable string, be it std::wstring, std::u8string, or what.
It doesn't. I contend that should be convert(s, -1), where s is a std::string, or convert<std::string>(-1). Other, more verbose spellings are possible, of course.
Isn't it so that string to_string(T const&, Format) is about string generation, such as Spirit::Karma and boost::optional<T> from_string<T>(String) is about parsing, such as Spirit::Qi. and StringT convert_string<StringT>(String) about character conversion.
The name 'convert' doesn't tell me anything about strings, for all I know the following could be valid: convert<std::vector<int> >(std::list<float> >()) ; boost::to_string/boost::from_string would be very useful if made right, but seems this discussion is mostly about nifty expressions such as convert("5").to<int>(), which is close to unusable to me. How would the following trivial case be written? vector<int> v; std::vector<std::string> s; std::transform(v.begin(), v.end(), boost::bind(convert, _1, ????), std::back_inserter(s)); I've not seen much discussions on how to provide formatters, or how to extend with user-defined types. Isn't that important for such a library? / Christian

On Wed, Feb 18, 2009 at 11:40, Christian Holmquist <c.holmquist@gmail.com> wrote:
Isn't it so that string to_string(T const&, Format) is about string generation, such as Spirit::Karma and boost::optional<T> from_string<T>(String) is about parsing, such as Spirit::Qi. and StringT convert_string<StringT>(String) about character conversion.
Well said.
boost::to_string/boost::from_string would be very useful if made right, but seems this discussion is mostly about nifty expressions such as convert("5").to<int>(), which is close to unusable to me. How would the following trivial case be written? vector<int> v; std::vector<std::string> s; std::transform(v.begin(), v.end(), boost::bind(convert, _1, ????), std::back_inserter(s));
I was worried it was too cute, and that's a great example why. That said, for specialization reasons it may well just be a wrapper around a converter<From, To> class that'd make a great functor. I'm glad to see a use case that actually has context, though. All the rest have just been syntax examples, as you mention.
I've not seen much discussions on how to provide formatters, or how to extend with user-defined types. Isn't that important for such a library?
I think it should be. I'd say the base specification is essential for integral <-> string conversions. The main thrust of this particular library has been getting rid of the default-constructability requirement and providing an interface that allows failure without throwing, though.

On Wednesday, February 18, 2009 11:40 AM Christian Holmquist wrote:
Isn't it so that string to_string(T const&, Format) is about string generation, such as Spirit::Karma and boost::optional<T> from_string<T>(String) is about parsing, such as Spirit::Qi. and StringT convert_string<StringT>(String) about character conversion.
The latter is better expressed as "transcode" if you wish to use separate names. That aside, your statements are accurate.
The name 'convert' doesn't tell me anything about strings,
Good! My suggestion was to consider a type-to-type conversion facility for which converting to and from strings were special cases.
for all I know the following could be valid: convert<std::vector<int> >(std::list<float> >()) ;
It could be made valid, though I doubt it would be supported.
boost::to_string/boost::from_string would be very useful if made right, but seems this discussion is mostly about nifty expressions such as convert("5").to<int>(), which is close to unusable to me.
That isn't the right characterization of the discussion. It's about figuring out what should be done and what interface best captures it. The latter has consumed a great deal of discussion, but I'm hoping to spend more time on the former.
How would the following trivial case be written? vector<int> v; std::vector<std::string> s; std::transform(v.begin(), v.end(), boost::bind(convert, _1, ????), std::back_inserter(s));
That's a curious "trivial case" but it adds a requirement if it should be supported because you've specified no template parameters for convert(), thus implying it should be a non-template function, unless I'm mistaken about some means whereby the compiler can deduce the template parameters. It is things like this suggestion that must be considered for inclusion in the list of requirements for which to design the facility. Many requirements will likely be rejected as enlarging the scope excessively while others will be considered paramount. That is why I've avoided committing to any interface thus far.
I've not seen much discussions on how to provide formatters, or how to extend with user-defined types. Isn't that important for such a library?
UDT extension is via the IOStreams insertion and extraction operators as mentioned in another post. Handling formatters was suggested to be by returning a proxy that accumulates formatting information prior to converting to the output type. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Wed Feb 18 2009, "Vladimir Batov" <batov-AT-people.net.au> wrote:
convert::to_string<wstring>, convert::to_integral<int, rounding::down>, convert::transcode_string<wstring, native_mbcs>, ...
How about
convert::to<wstring> convert::to<int, rounding::down> convert::to<wstring, native_mbcs>
I am serious. I actually like it. I understand you do not like my to/from but you are almost there. By eliminating the repetition (as for _string<wstring) we get a laconic and expressive (IMHO of course) interface. No need for various to_string, to_integral, transcode_string, etc. We get rid of the string namespace as well (it should be a plus isn't it?). So, it'd be
int i = boost::convert::to<int>(str); // explicit 'int' type int i = boost::convert::to(str, -1); // deduced 'int' string s = boost::convert::to<string>(-1); // explicit std::string type string s = boost::convert::to(-1, "failed to convert"); // deduced std::string wstring s = boost::convert::to<wstring>(-1); // explicit std::wstring type wstring s = boost::convert::to(-1, L"failed to convert"); // deduced std::wstring
This looks pretty nice to me at first glance. -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Tue, Feb 17, 2009 at 14:39, Emil Dotchevski <emildotchevski@gmail.com> wrote:
My question is, what is the motivation for the convert function? What's the use case for it that doesn't work with to_string/from_string?
I said I can't stand prepositions (from, to) used as identifiers, and wanted the functions to be verbs. I don't think I said I like just plain "convert" though; I would certainly prefer to_string and from_string to a nebulous, domain-ambiguous "convert" function. The one use case that can see that doesn't "fit" with to_string and from_string would be string <=> wstring and such, but that would be better as transcode or something anyways.

Emil Dotchevski wrote:
The outcome was that to_string/from_string are not verbs, are slightly longer than convert and duplicate the namespace name; to/from are meaningless without the surrounding namespace name, which may be omitted or mangled with aliases.
Are you saying that
boost::string::to(x)
reads better than
boost::to_string(x)?
<sigh> Here we go again... They both are bad, IMO. I'm against polluting the boost namespace, so boost::some_namespace::to_string(x) is better, but the submission author and some others didn't like it either. The consensus was boost::string::convert, if I'm not missing anything.
The convert function will eventually convert different things to strings and vice versa.
You can convert different things to string using to_string. You can convert different things from strings using from_string.
My question is, what is the motivation for the convert function? What's the use case for it that doesn't work with to_string/from_string?
There isn't any particular case for using the "convert" naming. As there isn't one for "to_string/from_string".

On Tue, Feb 17, 2009 at 12:26 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
You can convert different things to string using to_string. You can convert different things from strings using from_string.
My question is, what is the motivation for the convert function? What's the use case for it that doesn't work with to_string/from_string?
There isn't any particular case for using the "convert" naming. As there isn't one for "to_string/from_string".
The issue is not just naming and syntax. The two approaches are: 1) Define a "to_string" interface and a separate, independent "from_string" interface 2) Define a single interface that can go to and from string The second approach introduces coupling between to_string and from_string. This coupling must be justified, you need to get something in return. The only "something" I see here is that it lets you write code which doesn't "know" if it's going "to" or "from" string. My problem is that I can't think of a case when I would be writing code that doesn't "know" if it is going "to" or "from" string. Can you? Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

AMDG Emil Dotchevski wrote:
The issue is not just naming and syntax.
The two approaches are:
1) Define a "to_string" interface and a separate, independent "from_string" interface
2) Define a single interface that can go to and from string
The second approach introduces coupling between to_string and from_string. This coupling must be justified, you need to get something in return. The only "something" I see here is that it lets you write code which doesn't "know" if it's going "to" or "from" string.
The only other benefit, is possible syntactic nicity. Note that this function can be in a very light weight header that forwards to the correct implementation, so the coupling would be minimal.
My problem is that I can't think of a case when I would be writing code that doesn't "know" if it is going "to" or "from" string. Can you?
IMO, a use case where exactly one of the arguments is known to be a string, but it is unknown which one, is unlikely. In Christ, Steven Watanabe

On Tue, Feb 17, 2009 at 2:34 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Emil Dotchevski wrote:
The issue is not just naming and syntax.
The two approaches are:
1) Define a "to_string" interface and a separate, independent "from_string" interface
2) Define a single interface that can go to and from string
The second approach introduces coupling between to_string and from_string. This coupling must be justified, you need to get something in return. The only "something" I see here is that it lets you write code which doesn't "know" if it's going "to" or "from" string.
The only other benefit, is possible syntactic nicity. Note that this function can be in a very light weight header that forwards to the correct implementation, so the coupling would be minimal.
Your description is identical to 1) as far as I'm concerned because there is no coupling between to_string and from_string (the coupling is between convert() and to_string/from_string). However, in this design it makes sense convert() to be a separate library altogether, assuming it's scope goes beyond string conversions alone. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Tuesday, February 17, 2009 5:43 PM Emil Dotchevski wrote:
Emil Dotchevski wrote:
The two approaches are:
1) Define a "to_string" interface and a separate, independent "from_string" interface
2) Define a single interface that can go to and from string
The second approach introduces coupling between to_string and from_string. This coupling must be justified, you need to get something in return. The only "something" I see here is
On Tue, Feb 17, 2009 at 2:34 PM, Steven Watanabe <watanabesj@gmail.com> wrote: that it lets
you write code which doesn't "know" if it's going "to" or "from" string.
The coupling is not of implementation but of interface. They are opposite sides of a single coin, so coupling them is not a terrible thing. The directionality you see is due to focusing on string with the other things converting to and from strings. If, instead, you view it as converting from one thing to another, where string can be the source or destination type, then all conversions are, effectively, one way.
The only other benefit, is possible syntactic nicity. Note that this function can be in a very light weight header that forwards to the correct implementation, so the coupling would be minimal.
Your description is identical to 1) as far as I'm concerned because there is no coupling between to_string and from_string (the coupling is between convert() and to_string/from_string). However, in this
Indeed, conversion to string is implemented apart from conversion from string, but that hardly necessitates total separation.
design it makes sense convert() to be a separate library altogether, assuming it's scope goes beyond string conversions alone.
It may well be, as I previously suggested, that there is an underlying set of functions for converting to strings and from strings to which convert defers. That would permit you to get your preferred interface while others could use a more generic convert() interface, provided both were documented. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Wed, Feb 18, 2009 at 5:52 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
On Tuesday, February 17, 2009 5:43 PM Emil Dotchevski wrote:
Emil Dotchevski wrote:
The two approaches are:
1) Define a "to_string" interface and a separate, independent "from_string" interface
2) Define a single interface that can go to and from string
The second approach introduces coupling between to_string and from_string. This coupling must be justified, you need to get something in return. The only "something" I see here is
On Tue, Feb 17, 2009 at 2:34 PM, Steven Watanabe <watanabesj@gmail.com> wrote: that it lets
you write code which doesn't "know" if it's going "to" or "from" string.
The coupling is not of implementation but of interface. They are opposite sides of a single coin, so coupling them is not a terrible thing.
Many times I've needed to_string without needing from_string. In my book, this is a strong indication that they shouldn't be coupled.
The directionality you see is due to focusing on string with the other things converting to and from strings. If, instead, you view it as converting from one thing to another, where string can be the source or destination type, then all conversions are, effectively, one way.
Yes, I agree that we can lead the discussion from this point of view. In this case we must forget about strings and talk about converting between all kinds of different types. You can't just say "it's not specifically about strings" and be done with it; we have to consider several different use cases in particular, as well as the issue in general; how the conversion works, how you configure it, etc. Instead, the whole thing even resides in a string namespace. :) Because nobody seems to be doing this, I don't see any evidence that the convert() function we could presumably end up with is any good for anything but converting to- and from- strings. And for that use case it's inferior to two independent to-string/from-string interfaces.
The only other benefit, is possible syntactic nicity. Note that this function can be in a very light weight header that forwards to the correct implementation, so the coupling would be minimal.
Your description is identical to 1) as far as I'm concerned because there is no coupling between to_string and from_string (the coupling is between convert() and to_string/from_string). However, in this
Indeed, conversion to string is implemented apart from conversion from string, but that hardly necessitates total separation.
What necessitates total separation then?
design it makes sense convert() to be a separate library altogether, assuming it's scope goes beyond string conversions alone.
It may well be, as I previously suggested, that there is an underlying set of functions for converting to strings and from strings to which convert defers. That would permit you to get your preferred interface while others could use a more generic convert() interface, provided both were documented.
OK here we agree then. Let's come up with good interface for to-string and from-string, and then feel free to propose a separate convert() library. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Wednesday, February 18, 2009 12:46 PM Emil Dotchevski wrote:
On Wed, Feb 18, 2009 at 5:52 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
Many times I've needed to_string without needing from_string. In my book, this is a strong indication that they shouldn't be coupled.
Your argument isn't compelling. Consider an arbitrary precision integer type. If many times one need only add such values, without also needing subtraction, should those operations be separated one from the other?
The directionality you see is due to focusing on string with the other things converting to and from strings. If, instead, you view it as converting from one thing to another, where string can be the source or destination type, then all conversions are, effectively, one way.
Yes, I agree that we can lead the discussion from this point of view. In this case we must forget about strings and talk about converting between all kinds of different types. You can't just say "it's not
That's what I've been doing almost from the start.
specifically about strings" and be done with it; we have to consider several different use cases in particular, as well as the issue in general; how the conversion works, how you configure it, etc. Instead, the whole thing even resides in a string namespace. :)
Gee, all of that sounds awfully familiar....
Because nobody seems to be doing this, I don't see any evidence that
Try again.
the convert() function we could presumably end up with is any good for anything but converting to- and from- strings. And for that use case it's inferior to two independent to-string/from-string interfaces.
lexical_cast is used for many type-to-type conversions, not just with strings. Why would this be any different?
Indeed, conversion to string is implemented apart from conversion from string, but that hardly necessitates total separation.
What necessitates total separation then?
Separate UDTs. Different domains. Many things.
It may well be, as I previously suggested, that there is an underlying set of functions for converting to strings and from strings to which convert defers. That would permit you to get your preferred interface while others could use a more generic convert() interface, provided both were documented.
OK here we agree then. Let's come up with good interface for to-string and from-string, and then feel free to propose a separate convert() library.
Why is that the necessary approach? Perhaps the end result will be something that satisfies all and there will be no need to document the underlying conversion logic. It's too early. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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.

AMDG Stewart, Robert wrote:
On Wednesday, February 18, 2009 12:46 PM Emil Dotchevski wrote:
On Wed, Feb 18, 2009 at 5:52 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
Many times I've needed to_string without needing from_string. In my book, this is a strong indication that they shouldn't be coupled.
Your argument isn't compelling. Consider an arbitrary precision integer type. If many times one need only add such values, without also needing subtraction, should those operations be separated one from the other?
It isn't necessary to separate them, but it is not unreasonable to do so either. For example, MPL has a separate header for each arithmetical metafunction. In Christ, Steven Watanabe

On Wednesday, February 18, 2009 1:15 PM Steven Watanabe wrote:
On Wednesday, February 18, 2009 12:46 PM Emil Dotchevski wrote:
Many times I've needed to_string without needing from_string. In my book, this is a strong indication that they shouldn't be coupled.
Your argument isn't compelling. Consider an arbitrary
Stewart, Robert wrote: precision integer type. If many times one need only add such values, without also needing subtraction, should those operations be separated one from the other?
It isn't necessary to separate them, but it is not unreasonable to do so either.
I won't argue that point, but it only applies if there are two such sets of functions. If there isn't "from_string" and "to_string," but only, for example, "convert," then there's no point in separate headers. It's a question of whether "string" should be at the center of the conversions as it is with "from_string" and "to_string." _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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 Wed, Feb 18, 2009 at 10:21 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
On Wednesday, February 18, 2009 1:15 PM Steven Watanabe wrote:
On Wednesday, February 18, 2009 12:46 PM Emil Dotchevski wrote:
Many times I've needed to_string without needing from_string. In my book, this is a strong indication that they shouldn't be coupled.
Your argument isn't compelling. Consider an arbitrary
Stewart, Robert wrote: precision integer type. If many times one need only add such values, without also needing subtraction, should those operations be separated one from the other?
It isn't necessary to separate them, but it is not unreasonable to do so either.
I won't argue that point, but it only applies if there are two such sets of functions. If there isn't "from_string" and "to_string," but only, for example, "convert," then there's no point in separate headers. It's a question of whether "string" should be at the center of the conversions as it is with "from_string" and "to_string."
"If you have two separate classes A and B, if instead you cram them both into a single class C, then there's no point in separating them." You're presuming that it makes sense to put converting to- and from- string into a single interface. For what it's worth, consider that sprintf/sscanf are separate interfaces too, despite the many similarities and analogies between them. Unlike addition and subtraction which are symmetrical, converting to- and from- string isn't. For example I searched our source code for to_string and from_string. We have 314 occurrences of to_string (in 112 source files), and only 33 calls to from_string (in 11 source files.) Only 2 files use both to_string and from_string. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Wednesday, February 18, 2009 2:18 PM Emil Dotchevski wrote:
On Wed, Feb 18, 2009 at 10:21 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
On Wednesday, February 18, 2009 1:15 PM Steven Watanabe wrote:
On Wednesday, February 18, 2009 12:46 PM Emil Dotchevski wrote:
Many times I've needed to_string without needing
from_string. In my
book, this is a strong indication that they shouldn't be coupled.
Your argument isn't compelling. Consider an arbitrary
Stewart, Robert wrote: precision integer type. If many times one need only add such values, without also needing subtraction, should those operations be separated one from the other?
It isn't necessary to separate them, but it is not unreasonable to do so either.
I won't argue that point, but it only applies if there are two such sets of functions. If there isn't "from_string" and "to_string," but only, for example, "convert," then there's no point in separate headers. It's a question of whether "string" should be at the center of the conversions as it is with "from_string" and "to_string."
"If you have two separate classes A and B, if instead you cram them both into a single class C, then there's no point in separating them."
The presumption there is that A and B are, reasonably, separate classes and that the functionality does not make more sense combined. They may be better separated or not, but there is insufficient information from which to judge.
You're presuming that it makes sense to put converting to- and from- string into a single interface. For what it's worth, consider that sprintf/sscanf are separate interfaces too, despite the many similarities and analogies between them.
I'm not convinced that convert() is the right interface, but neither am I convinced that the operations must be separated into distinct functions with distinct headers. My point was that using one of two operations frequently in a given context in no way implies the operations should be considered disjoint. C doesn't support overloading so sprintf() and sscanf() can hardly be valid justification for separate conversion function names in C++. As yet, I've seen no coherent set of requirements or use cases to bound the problem. I've seen no agreement on what this component must do. It is pointless to spend more time on the interface until we have that. From what I've observed, each person has some idea in mind and assumes most others agree with that idea. Until the goal is made concrete and considered as a clear and unambiguous whole, there's little point in debating these other aspects.
Unlike addition and subtraction which are symmetrical, converting to- and from- string isn't. For example I searched our source code for to_string and from_string. We have 314 occurrences of to_string (in 112 source files), and only 33 calls to from_string (in 11 source files.) Only 2 files use both to_string and from_string.
The operations are symmetrical, given a unique string encoding for a type. That's the basis of many forms of serialization after all. It doesn't matter how often one of the operations is used relative to the other when determining symmetry. Their *use* may not be symmetrical, but that's different from the symmetry of the operations themselves. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; 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.

Emil Dotchevski wrote:
You're presuming that it makes sense to put converting to- and from- string into a single interface. For what it's worth, consider that sprintf/sscanf are separate interfaces too, despite the many similarities and analogies between them.
Unlike addition and subtraction which are symmetrical, converting to- and from- string isn't. For example I searched our source code for to_string and from_string. We have 314 occurrences of to_string (in 112 source files), and only 33 calls to from_string (in 11 source files.) Only 2 files use both to_string and from_string.
I agree that the "from-string" conversion is used less often than "to-string". However, that doesn't seem to me as a reason to separate the interface. If we forget for a moment about strings, parsing and formatting, we have a value of type A and want to get the corresponding value of type B. Regardless of the types, we have a common process of value and type transformation here. As partial cases it may involve parsing, formatting, character transcoding, type promotion - you name it. There were good examples of such transformation kinds, such as string<->wstring conversion and transforms between containers and their elements. I assume there can be connection with other Boost libraries, like Boost.NumericConversion or Boost.Units. This library has potential to become a common framework for conversion facilities that are reimplemented here and there quite often. And I feel that a common and well recognizable interface is very important for such a framework. That is, I think it would be better to use a common name for conversions in either direction (well, the direction doesn't matter anyway, from perspective of such a framework).

On Wed, Feb 18, 2009 at 1:44 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote: I assume there can be connection with other Boost libraries, like Boost.NumericConversion or Boost.Units. This library has potential to become a common framework for conversion facilities that are reimplemented here and there quite often. And I feel that a common and well recognizable interface is very important for such a framework. That is, I think it would be better to use a common name for conversions in either direction (well, the direction doesn't matter anyway, from perspective of such a framework).
Agreed. The disagreement seems to be about the relationship between such conversion library and to- and from- string conversions. IMO, from the viewpoint of convert(), to- and from- string conversions should be treated as independent interface, much like Boost.NumericConversion or Boost.Units, etc. I'm strongly opposed to the approach of "convert() is great for strings, maybe we'll extend it later for other things." Maybe you will, maybe you'll find out that it can't be extended because nobody thought about convert()ing anything but strings. In fact, merely thinking about the other types isn't enough, we need practical experience with "the mother of all conversions" library before it is added to Boost. :) (Though as it is evident, you'll still have hard time convincing me that when all I need is to convert a foo to std::string, I have to use "the mother of all conversions" library instead of the straight forward to_string.) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
On Wed, Feb 18, 2009 at 1:44 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote: I assume there can be connection with other Boost libraries, like Boost.NumericConversion or Boost.Units. This library has potential to become a common framework for conversion facilities that are reimplemented here and there quite often. And I feel that a common and well recognizable interface is very important for such a framework. That is, I think it would be better to use a common name for conversions in either direction (well, the direction doesn't matter anyway, from perspective of such a framework).
Agreed.
The disagreement seems to be about the relationship between such conversion library and to- and from- string conversions.
IMO, from the viewpoint of convert(), to- and from- string conversions should be treated as independent interface, much like Boost.NumericConversion or Boost.Units, etc.
Why? Why not using, e.g., streaming operators for string-related conversions underneath the "convert" interface? This already is an established way of providing conversions to/from string, I don't see why it should be dropped.
I'm strongly opposed to the approach of "convert() is great for strings, maybe we'll extend it later for other things." Maybe you will, maybe you'll find out that it can't be extended because nobody thought about convert()ing anything but strings. In fact, merely thinking about the other types isn't enough, we need practical experience with "the mother of all conversions" library before it is added to Boost. :)
I agree that the "convert" function, or whatever name it will end up with, from the start should be targeted for generic conversions of arbitrary types between each other. Having that kind of function and an efficient library extension mechanism, I don't need any other conversion facilities whatsoever.
(Though as it is evident, you'll still have hard time convincing me that when all I need is to convert a foo to std::string, I have to use "the mother of all conversions" library instead of the straight forward to_string.)
Perhaps. I still don't understand why would you want to use specific functions, like to_string/to_wstring/to_whatever_string(foo) instead of a unified interface function convert< whatever >(foo).

On Wed, Feb 18, 2009 at 2:27 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote:
On Wed, Feb 18, 2009 at 1:44 PM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Emil Dotchevski wrote: I assume there can be connection with other Boost libraries, like Boost.NumericConversion or Boost.Units. This library has potential to become a common framework for conversion facilities that are reimplemented here and there quite often. And I feel that a common and well recognizable interface is very important for such a framework. That is, I think it would be better to use a common name for conversions in either direction (well, the direction doesn't matter anyway, from perspective of such a framework).
Agreed.
The disagreement seems to be about the relationship between such conversion library and to- and from- string conversions.
IMO, from the viewpoint of convert(), to- and from- string conversions should be treated as independent interface, much like Boost.NumericConversion or Boost.Units, etc.
Why?
For the same reason Boost.NumericConversion and Boost.Units are independent. You're not proposing to make Boost.NumericConversion and Boost.Units also parts of the convert() library, are you? Why do you want to do this for the to- and from-string conversions?
(Though as it is evident, you'll still have hard time convincing me that when all I need is to convert a foo to std::string, I have to use "the mother of all conversions" library instead of the straight forward to_string.)
Perhaps. I still don't understand why would you want to use specific functions, like to_string/to_wstring/to_whatever_string(foo) instead of a unified interface function convert< whatever >(foo).
The answer is the same as why I don't always use templates. I use templates when I need my code to be generic, otherwise I do not. If I want to convert to T I'll use convert<T> if I want to convert to string, I prefer the much lighter s=to_string(x). Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
The disagreement seems to be about the relationship between such conversion library and to- and from- string conversions.
IMO, from the viewpoint of convert(), to- and from- string conversions should be treated as independent interface, much like Boost.NumericConversion or Boost.Units, etc. Why?
For the same reason Boost.NumericConversion and Boost.Units are independent. You're not proposing to make Boost.NumericConversion and Boost.Units also parts of the convert() library, are you?
My current vision is that Boost.NumericConversion and Boost.Units will provide a support layer for Boost.Convert (let's call it that way for now). That support layer will be implemented as a regular extension for the Boost.Convert library. So, the "convert" function will eventually call numeric_cast or quantity_cast, or any other appropriate tool in these libraries to fulfill the conversion.
Why do you want to do this for the to- and from-string conversions?
There must be a misunderstanding between us. From my point of view, the Boost.Convert implementation with regard to the "to/from-string" conversions can rely directly on the streaming operators, that can be provided by users. This mechanism is well-established already, so there is no need in some intermediate layer, like to_string/from_string & co.

AMDG Andrey Semashev wrote:
My current vision is that Boost.NumericConversion and Boost.Units will provide a support layer for Boost.Convert (let's call it that way for now). That support layer will be implemented as a regular extension for the Boost.Convert library. So, the "convert" function will eventually call numeric_cast or quantity_cast, or any other appropriate tool in these libraries to fulfill the conversion.
There is no function called quantity_cast, in the released version of Boost.Units--it's spelled static_cast. The problem with a fully generic convert is that it's a different beast from string conversions. Converting to and from a string can require formatting information that is meaningless for other conversions and which cannot easily be provided by fully generic code. In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Andrey Semashev wrote:
My current vision is that Boost.NumericConversion and Boost.Units will provide a support layer for Boost.Convert (let's call it that way for now). That support layer will be implemented as a regular extension for the Boost.Convert library. So, the "convert" function will eventually call numeric_cast or quantity_cast, or any other appropriate tool in these libraries to fulfill the conversion.
There is no function called quantity_cast, in the released version of Boost.Units--it's spelled static_cast.
Huh? I can see it in the library docs: http://tinyurl.com/adkdd7
The problem with a fully generic convert is that it's a different beast from string conversions. Converting to and from a string can require formatting information that is meaningless for other conversions and which cannot easily be provided by fully generic code.
This is where tools like Boost.Parameter could come forward. String-related conversions may not be the only domain where passing arbitrary parameters to the conversion mechanism is desirable.

On Thu, Feb 19, 2009 at 10:21 AM, Andrey Semashev <andrey.semashev@gmail.com> wrote:
Steven Watanabe wrote:
The problem with a fully generic convert is that it's a different beast from string conversions. Converting to and from a string can require formatting information that is meaningless for other conversions and which cannot easily be provided by fully generic code.
This is where tools like Boost.Parameter could come forward. String-related conversions may not be the only domain where passing arbitrary parameters to the conversion mechanism is desirable.
An interface that can convert between anything and anything else has to be extremely flexible. Extremely flexible interfaces are usually deeply flawed. The process of design (not just in programming) is synonymous with selective removal of flexibility. IMO the "mother of all conversions" interface will end up like this: http://www.revergestudios.com/swiss_army_knife.jpg :) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

AMDG Andrey Semashev wrote:
My current vision is that Boost.NumericConversion and Boost.Units will provide a support layer for Boost.Convert (let's call it that way for now). That support layer will be implemented as a regular extension for the Boost.Convert library. So, the "convert" function will eventually call numeric_cast or quantity_cast, or any other appropriate tool in these libraries to fulfill the conversion.
There is no function called quantity_cast, in the released version of Boost.Units--it's spelled static_cast.
Huh? I can see it in the library docs:
Oh. Right. I was thinking of the conversion between units. Extracting the raw value, IMO, should never happen in a context where you don't know that this is exactly what you are doing. A generic conversion routine should never resolve to quantity_cast. It's clearer to have a specific function for the task. In Christ, Steven Watanabe

Emil Dotchevski wrote:
(Though as it is evident, you'll still have hard time convincing me that when all I need is to convert a foo to std::string, I have to use "the mother of all conversions" library instead of the straight forward to_string.) Perhaps. I still don't understand why would you want to use specific functions, like to_string/to_wstring/to_whatever_string(foo) instead of a unified interface function convert< whatever >(foo).
The answer is the same as why I don't always use templates. I use templates when I need my code to be generic, otherwise I do not.
That's an odd argument. You do use STL containers in a non-template code, don't you? And perhaps you use shared_ptr< T > in a non-template code, too? The lexical_cast< T > may be a closer example. How come convert< T > to be that special?
If I want to convert to T I'll use convert<T> if I want to convert to string, I prefer the much lighter s=to_string(x).
Well, at this point it's not obvious how much lighter it is (and even if it is lighter at all).

On 18 Feb 2009, at 23:30, Andrey Semashev wrote:
Emil Dotchevski wrote:
(Though as it is evident, you'll still have hard time convincing me that when all I need is to convert a foo to std::string, I have to use "the mother of all conversions" library instead of the straight forward to_string.) Perhaps. I still don't understand why would you want to use specific functions, like to_string/to_wstring/to_whatever_string(foo) instead of a unified interface function convert< whatever >(foo). The answer is the same as why I don't always use templates. I use templates when I need my code to be generic, otherwise I do not.
That's an odd argument. You do use STL containers in a non-template code, don't you? And perhaps you use shared_ptr< T > in a non- template code, too? The lexical_cast< T > may be a closer example. How come convert< T > to be that special?
Are you suggesting that convert should just do to and from strings? If so, then combining it into one box seems unnecessary. If you are suggesting it should do other things, then you are opening a big box I don't want to go into. I do not want a unifying single "convert" method, that turns anything into anything else, mainly because it will gets things wrong most of the time. Chris
If I want to convert to T I'll use convert<T> if I want to convert to string, I prefer the much lighter s=to_string(x).
Well, at this point it's not obvious how much lighter it is (and even if it is lighter at all).
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Wed, Feb 18, 2009 at 4:06 PM, Christopher Jefferson <chris@bubblescope.net> wrote:
If you are suggesting it should do other things, then you are opening a big box I don't want to go into. I do not want a unifying single "convert" method, that turns anything into anything else, mainly because it will gets things wrong most of the time.
The opinion that the mother of all convert functions that can convert anything into anything won't work can't be defended without delving into it in details. I would be satisfied if there is at least an acknowledgment that those details must be considered before such semantics are seriously proposed -OR- we argee that it's just for strings and focus on its pros and cons over to_string/from_string, in this limited domain. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Wed, Feb 18, 2009 at 13:02, Stewart, Robert <Robert.Stewart@sig.com> wrote:
lexical_cast is used for many type-to-type conversions, not just with strings. Why would this be any different?
Do you have some examples of uses where neither source nor target is string-like? I can't come up with any and there are no such examples in the documentation. (I understand that it's possible, but haven't seen where it's useful.) Looking at the lexical_cast documentation brought up an interesting point, actually. The FAQ[1] mentions that lexical_cast<std::string>(uint8_t(32)) doesn't do what people first expect, which may be a point in favour of separating the different kinds of casts. [1] http://www.boost.org/doc/libs/1_38_0/libs/conversion/lexical_cast.htm#faq

on Wed Feb 18 2009, "Stewart, Robert" <Robert.Stewart-AT-sig.com> wrote:
From: "Stewart, Robert" <Robert.Stewart@sig.com> Subject: Re: [boost] Formal Review Request: Boost.String.Convert To: "boost@lists.boost.org" <boost@lists.boost.org> Date: Wed, 18 Feb 2009 13:02:07 -0500 Reply-To: boost@lists.boost.org
On Wednesday, February 18, 2009 12:46 PM Emil Dotchevski wrote:
On Wed, Feb 18, 2009 at 5:52 AM, Stewart, Robert <Robert.Stewart@sig.com> wrote:
Many times I've needed to_string without needing from_string. In my book, this is a strong indication that they shouldn't be coupled.
Your argument isn't compelling. Consider an arbitrary precision integer type. If many times one need only add such values, without also needing subtraction, should those operations be separated one from the other?
Perhaps. Not every monoid is a group: http://en.wikipedia.org/wiki/Algebraic_structure -- Dave Abrahams BoostPro Computing http://www.boostpro.com

on Tue Feb 17 2009, Emil Dotchevski <emildotchevski-AT-gmail.com> wrote:
I like the idea of a library for converting to and from strings.
I have two comments:
1) I don't like the string namespace. I would prefer to use boost::to_string and boost::from_string:
std::string s=boost::to_string(x)
reads better than
std::string s=boost::string::to(x).
I think so too; much more straightforward. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (12)
-
Andrey Semashev
-
Christian Holmquist
-
Christopher Jefferson
-
David Abrahams
-
Emil Dotchevski
-
Michael Caisse
-
Paul A. Bristow
-
Scott McMurray
-
Steven Watanabe
-
Stewart, Robert
-
Vladimir Batov
-
Vladimir.Batov@wrsa.com.au