
On 02/17/2014 08:10 PM, Andrzej Krzemienski wrote: Now, I can definitely find all my answers in the Introduction. What I would like to suggest ... is to put a very very short code snippet that will show me how I will be using the library.
Done.
Comparison with lexical_cast, and (even more importantly) answering the questions "why would I use Boost.Convert library instead of lexical_cast" and "why did you not extend lexical_cast instead" and "why would I need lexical_cast anymore" are very important for your library's documentation -- I agree. It is just that I am not sure these explanations belong to the Introduction page. But I leave it open. I am satisfied with the improved introduction as it is (except for the one tiny suggestion below).
Understood. Given that in the Intro lexical_cast is only mentioned once in passing it should not pose a problem, right?
Again, I am far from sure about that. I do currently have to have OS-native MBCS (MSWin and Solaris) to UCS-2 and UCS-4 string conversions. They are a separate lib. Can't immediately see anything wrong in incorporating it into the 'convert' framework. Then I remember Vicente having a 'conversion' proposal to address that T-to-U conversion in a generic way. So, he must have had a need for it also. I am not saying you are wrong. I just do not know. Consider the templates example. Stroustrup purposefully designed them in a generic way. Their deployment exploded often in surprising ways. I am certainly no Stroustrup but you get the idea. So, you say, it could be used to convert between two different string encodings? I didn't think of it but it looks really useful. So useful that it deserves a bullet in the Introduction. Can it be used to convert from string to wstring?
The thing is that the 'convert' API facade (the convert<T>::from) does embarrassingly very little. Still, it ensures the uniformity of interface and lays out the rules for the converters. So, if one has a "callable", say, an old-fashioned function bool my_converter(std::string const& value_in, std::wstring& result_out); then it can be plugged into the 'convert' framework and used as std::wstring res = convertstd::wstring::from(std_string, my_converter).value(); Still, I am far from sure that this particular application of 'convert' will take off. I just do not know. The reason is that TypeIn and TypeOut are known in advance, i.e. I know that I want std::string converted to std::wstring. So, there is seemingly very little gain from calling std::wstring res = convertstd::wstring::from(std_string, my_converter).value(); instead of direct std::string value_in = ...; std::wstring result_out; bool success = my_converter(value_in, result_out); When I, myself, look at convert<T>::from in isolation, I think why on Earth I need convert<T>::from to begin with? But convert<T>::from appears to be quite important (IMO) to build modular extendible system as convert<T>::from API allows me to write code without knowing all the types/conversions that will be used by that system. More so, from maintenance point of view I find it much easier to see (and recognize) a familiar API instead of guessing what " bool success = my_converter(value_in, result_out)" might *actually* do. So, the short answer to your "Can it be used to convert from string to wstring?" question is "yes". Will it be useful? I am not sure. I've not used "convert" it that fashion so I have no strong feelings one way or another. So, I added a section about potentially doing that but tucked it to the end. :-) I just to not want to get in to trouble bragging about it too much. :-)
Uhm, I would not be that quick saying that T-to-string conversion can never fail. It depends on complexity of the conversion and the used character set, etc. What if T is a complex class which in its conversion depends on other classes to behave and they don't? What if the conversion depends on, say, formatting specification and it is not met or is invalid? This is an interesting point. If a conversion fails because it required to acquire some resources and it failed to get them, or because the object was in a disallowed state (some assertion-like thing failed), do you want to return an empty result, or just throw?
I am not sure I can answer that question definitively. I suspect it depends on how a particular failure is interpreted/seen. If that's something disastrous/exceptional, then throw; otherwise return failure... not exactly a precise answer, is it? :-) When I said "a complex class which in its conversion depends on other classes to behave" I had more "modest" conversion failures in mind. For example, I write scheduling s/w for airlines and there there is the concept of a leg or a sector -- a chunk of uninterrupted flight from A to B. Quite often I want a leg/sector's string representation printed out. So, std::string info = convert<string>::from(leg, cnv).value_or("bad"); The problem is that there are many parameters in that leg/sector structure. So, the call above can easily fail. Say, I forgot to set the destination port! So, in this example conversion to string can fail. If I had the "conversion to string can never fail" rule I could return "", "invalid", etc. but I think the code above is far better -- I immediately see what string represents conversion failure. V.