Boost.Conversion - pre review request

Hi, I've been reworking the Boost.Conversion library Documentation: http://svn.boost.org/svn/boost/sandbox/conversion/libs/conversion_ext/doc/ht... Sandbox :http://svn.boost.org/svn/boost/sandbox/conversion/ Description: Boost.Conversion manages with generic extrinsic conversion between unrelated types. These conversion can be seen as implicit or explicit conversions. The conversion operator can not be overloaded with a free function on C++. In the past, there were some request to been able to overload the @c static_cast operator []. The author thinks that the language would be more uniform if this extrinsic overload would be possible. The new operators could take the following form operator Target(const Source& val); explicit operator Target(const Source& val); The assignment operator could also be overloaded by a free function with some limitations as described in [] Target& operator=(Target&, Source const&); Boost.Conversion tries to provide a library emulation for this missing feature and shows some needed workarounds that are needed to take care of the current C++ semantics. In order to provide the needed functionality, two type traits are mandatory is_constructible and is_assignable. The library provide a first implementation of these type traits that works on compilers providing some specific features. The idea is that these type traits should be added to Boost.TypeTraits. John, Joel I would like we work together to have these traits available in as many compilers as we can. When we don't have an automatic way to detect these traits, the library provide specialization for some std and boost types. If you agree the library could provide the specializations for all the standard types and optionally for some Boost types. User working with compilers not supporting the definition of these traits, or users that need to make their code portable, will need to specialize these traits by hand for his types. The review dates are 20th to 29th August. I would like to have some feedback before the review so I can have some time to make the library review ready. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hi Vicente, all,
I am excited to manage the Conversion review at the end of August. It may be simple enough for us to say "extrinsic type-to-type conversion" since we both participated in the Boost.Convert review and have all those distinctions in mind... But it might be confusing to potential reviewers and followers of Boost that in other "little c" conversion news this year: * lexical_cast has received a new maintainer who is adding optimizations for type-to-type which overlap with Conversion * Vladimir Batov's Boost.Convert was withdrawn. I think it's fair to Ed Diener's excellent review report [1] to say that the library was not acceptable in its current form not because it didn't have the right features, but mostly because of syntax problems. And because of confusion that its scope overlapped with lexical_cast, which I'm trying to avoid in the upcoming review! * Jeroen Habraken is working on a Boost.Coerce library [2] which does more runtime-efficient string-to-type and type-to-string conversion using Spirit. One clear distinction is that the proposed Boost.Conversion is not concerned with the special cases of string-to-type and type-to-string. It provides a general framework for type-to-type conversion and will defer string conversions to lexical_cast or coerce depending how it is configured. IMHO lexical_cast is not the appropriate generic function to use for type-to-type conversion (when there is no text involved), and I am managing the review to evaluate whether Boost.Conversion is the right solution. Boost.Conversion learns from the use cases that were presented by Vladimir Batov in Boost.Convert and its review, and IIUC it now provides all the behaviors that were not string-specific, without the syntax problems. Obviously, that also means no operator<<, so there's no way to specify formatting options if text is involved. (Jeroen, if you're reading this, can you convert to/from e.g. hexadecimal with Coerce?) So, Vicente, let's go over the Scope section of the documentation, quoted in your message. This helps a lot, but it should also include comparisons and interactions with the libraries listed above, as well as Boost.NumericConversion.
Okay, so it is a library demonstrating the usefulness of a possible language feature. However, your intro should also argue the library's usefulness up until C++20. :-)
Are they needed simply to enable/disable the corresponding function in Conversion, or does it also affect the behavior?
All good, but it probably doesn't belong in the intro. As a library user I presume you will provide support for a good number of compilers in the best way you see fit.
The review dates are 20th to 29th August. I would like to have some feedback before the review so I can have some time to make the library review ready.
I hope this is helpful and I'll provide more detailed feedback soon. Cheers, Gordon

Hi, On 9 July 2011 04:10, Gordon Woodhull <gordon@woodhull.com> wrote:
It isn't possible at the moment but it is to be re-added during the Google Summer of Code. The syntax will probably look something like coerce::as<int>("0x17", tag::hex());
If there are any questions regarding Coerce, please don't hesitate to contact me either on- or off-list. Regards, Jeroen

On Jul 9, 2011, at 2:52 AM, Jeroen Habraken wrote:
Aha, that's why I asked. Not currently compatible with Boost.Conversion: just as there's no way to supply iostream manipulators for Convert-style formatting, there's no way to supply tags for Coerce-style. Vicente, do you have any thoughts on whether extra parameters could be added generically? Cheers, Gordon

Gordon Woodhull wrote:
Hi, I don't think that these kind of specific conversions could be added to simple type-to-type conversions. As I signaled during the Boost.Convert review I will use instead an auxiliary string stream and output and input the types we want to convert using as many manipulators as the user wants. I have added an example here http://svn.boost.org/svn/boost/sandbox/conversion/libs/conversion_ext/exampl... that shows how I will apply these kind of conversions. As you can see this example doesn't make use of the Boost.Conversion generic functions when manipulators are needed. Instead it uses either a template io stream (extractor_stream) that is able to extract the type given as parameter when the extract manipulator is used or a io stream ( via_stream) that is able to extract any type given as parameter of the manipulator extract_to. As you can see the user can define is not too many lines of code these kind of io streams. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

This might be off topic and purely esthetical (i.e. personal taste), but I find the mix of operator>>() and operator<<() in the same expression to be more than confusing. That's (for me) clearly not a viable solution. Regards Hartmut --------------- http://boost-spirit.com

Hartmut Kaiser wrote:
I agree with you that the mix of i/o operators could be confusing. Maybe it could be less confusing if we write them as follows std::string si2 = ii =>> std::uppercase =>> std::hex =>> via_stream() >> extract_to(*std::string*)(); If I'm not wrong =>> is left to right associative, so the preceding is equivalent to (ii =>> (std::uppercase =>> (std::hex =>> via_stream()))) >> extract_to(*std::string*)(); Note that I'm not proposing to include this on Boost.Conversion. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

FWIW, =>> is not a valid operator at all. Did you mean >>=? If yes, I don't think it will work as it has the wrong precedence. In any case, this kind of expressions scare me. They can't be understood without having a copy of the docs open all the time. Regards Hartmut --------------- http://boost-spirit.com

On Jul 9, 2011, at 10:37 AM, "Hartmut Kaiser" <hartmut.kaiser@gmail.com> wrote:
Although this is interesting work, I expect it may be wise not to try to cover lexical casts in this library, especially considering that lexical_cast and Coerce necessarily must have different interfaces. What I was wondering was instead whether it'd be possible to pass extra arguments through convert_to. I'd be satisfied with "no, if you need non-default formatting/parsing, use one of the string conversion libraries directly." I'd just like to firm up these sorts of scope issues well before the review so the ground isn't shifting under it. Thanks, good discussion so far, Gordon

Jeroen Habraken wrote:
Hi, I don't see why we need to specify that the format is hexadecimal. I would expect that the spirit grammar associated to the coerce library will take care of all the formats without any specific additional tag. I see only a need for tags/manipulators when you want to convert an int to a string as you can have only one default behavior. Do you expect to have best performances with coerce than using an string stream for type to string conversions? Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

Doing implicit conversion from 0x17 to 'int' without explicit guidance from the user (i.e. by telling to convert from hex) is not a good idea, IMHO. I'd suggest to make the conversion explicit as much as possible, which usually amounts to the least surprised user. Regards Hartmut --------------- http://boost-spirit.com

Gordon Woodhull wrote:
On the current implementation if you try to convert "700" to an int you will get 700. If you want to take it as the representation of other than a decimal number you will need to use explicitly a specific library that provide it, as Boost.Coerce could do. If the Boost community consider that there is no good default behavior fro string to int conversion I will remove this specializations. Anyway, what is the result of coerce::as(*int*)("700"); ? Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hi, On 9 July 2011 17:08, Vicente Botet <vicente.botet@wanadoo.fr> wrote:
The result is 700, however when one takes "3.14" as input things start to become less obvious. boost.coerce will always parse "3.14" to 3.14 and will always fail on "3,14", boost.lexical_cast however will parse one and fail on the other depending on the locale. Jeroen

Hi, On 9 July 2011 15:51, Vicente Botet <vicente.botet@wanadoo.fr> wrote:
I believe the API of boost.coerce should not try to outsmart the user. "0x23" is not a valid integer unless he/she explicitly states to accept hexadecimal numbers, which can be done via tag::hex() or something akin to tag::detect_base(). Regards, Jeroen

Gordon Woodhull wrote:
Youa are right Gordon. I will update the introduction to state clearly these facts.
:). Yes, again you are right. Even if the library design is guided by these possible/missing language features and I try to be as close as possible of how they could behave, I expect the library would be useful by itself. I will try to make this more evident.
When we are not able to use these traits we are not able to define the correct default behavior. The library could work without these traits and don't using SFINAE but some features can not be provided.
OK. I raised the issue here also to signal that if the library is accepted, these traits should be moved to the TypeTraits library and that I'm ready to work on this if John agree on the the fact that we should need to provide specific specializations for a lot of types on the standard and Boost for those non-conforming compilers.
As a library user I presume you will provide support for a good number of compilers in the best way you see fit.
With the specialization of the is_constructible and is_assignable on compilers that doesn't allow to detect them the library should work correctly on compilers supporting SFINAE. I would like to know about how the library is working on Intel, Sun and IBM compilers to which I have no access.
Thanks, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hi, Colour me curious, but what's the advantage of wrapping boost.coerce in boost.conversion? We're trying to create a sensible API for boost.coerce (which, as we've seen, is quite a challenge for a conversion library) and I personally do not see the benefit of it being wrapped with a different API in a different library. Kind regards, Jeroen

Jeroen Habraken wrote:
The scope of Boost.Conversion is not to define specific conversions but allow to put all the basic type-to-type conversion using a generic interface. If Boost.Coerce provide an string to type efficient conversion Boost.Conversion can provide a specialization for string to types conversion that will delegate to Boost.Coerce. At the end std::string is a type as others. Boost.Conversion provides currently and optional (specific file) a specialization for string-to-type and type-to-string that uses lexical_cast. It will try to make this specialization available only if the used expression is valid, but I have no taken the needed time yet. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hi, On 9 July 2011 16:20, Vicente Botet <vicente.botet@wanadoo.fr> wrote:
It is important to note there is no generic way of implementing type-to-string and string-to-type which is the reason that boost::lexical_cast and boost::coerce can co-exist. Whilst there is definitely an overlap in the problems both libraries solve the approach is significantly different. If one must support locale than lexical_cast is the way to go, if one prefers runtime speed than coerce is the way to go. Since these libraries obviously aren't drop-in replacements of each other the user must make an informed decision and pick one based on his/her requirements. This also means, in my opinion anyways, that boost.conversion can't generically wrap both in a meaningful way since they operate differently and one can't switch between them without consequences. Jeroen

Jeroen Habraken wrote:
You are right and the same applies to any type-to-type conversion. And maybe this is the MAJOR flaw of Boost.Conversion: to think that we can define extrinsically THE conversion between two types. Every body admit that if a class T defines a constructor from a std::string THE conversion from std::string to T is the one defined by this constructor. Boost.Conversion pretend to provide a specialization point to state what is THE conversion from one type to another extrinsically. Of course, the fact that this is done outside both classes allows to have two different points of view that will be ambiguous if the two view are visible from the same compilation unit or will violate the ODR if both views are present on the same program. Note that this issue is not only limited to Boost.Conversion but to any function that could be overloaded by the user or any template class that can be specialized by the user. Two different parts of a program could make the same overloading or the same specialization. This doesn't implies that we should avoid overloading or specializations. It seems clear to me that if we don't have a consensus on the default type-to-type conversion extrinsically Boost.Conversion mustn't not provide it, neither the user. Does it means that Boost.Conversion has no sens? I don't know. Coming back to the string to int conversion, if we can not have a default string-to-type or type-to-string, Boost.Conversion must remove these specializations. Thanks Jeroen and Harmut for raising this issue before the review, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Jul 9, 2011, at 11:39 AM, Vicente Botet wrote:
Yes, this is a problem with all global customization points. I would expect than any one developer would want to use either lexical_cast or coerce. However, does the ODR mean that the exact same conversions would have to be defined in a library and in any code that uses the library? That sounds tricky! Just document it as a known limitation and reviewers can decide
Right.
IIUC it's providing the conversions and the user chooses them by #including the headers of interest.
neither the user.
? Really?
Seems to me there are still defaults: decimal provided by either lexical_cast or coerce depending on user preferences. And the user has to be careful. Or are you saying that since all libraries linked into a program must agree on which conversions to use, Conversion should only define ones that everyone agrees on? That sounds rather extreme. Why not just stipulate that the set must be the same throughout the program? Libraries would document or allow customization of which converters they use.

Gordon Woodhull wrote:
Yes. we can not have two customizations that conflict within the same program.
Well, we have two kind of users. Final users and library author users. The final users can choose to include the header of their interest as far as there is no conflict in the whole program, but library author users can use only consensual type-to-type conversions if they want its library to be reusable in a large context.
Yes, this is exactly the point. There couldn't be a conflict in the whole program. Library authors could document the conversions choices they have taken, but the use of a non-consensual conversion will make the library less usable. I don't think that Boost.Conversion can provide a string-to-type conversion that is configurable. It could provide one if there is a consensus of a default. We should see Boost.Conversion customization as if we were adding some methods to one of the classes. For the string to float conversions, it is as if we were adding explicit operator float() const; to the std::string class. Best, Vicente -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Conversion-pre-review-request-tp365... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Jul 11, 2011, at 12:59 PM, Vicente Botet wrote:
Why not provide the functionality in mutually-exclusive headers, e.g. #error out in conversion/boost/coerce-strings.hpp if you see that lexical_cast-strings.hpp has already been included? This wouldn't prevent all ODR violations but it would catch any in the same compilation unit. I suppose there is a fancier metaprogramming way to detect conflicts in general (within a TU), but this is cheap. And then define none by default. That seems to be harmonious with the rest of the design, where one #includes exactly the functionality one needs. Cheers, Gordon

On Jul 9, 2011, at 10:20 AM, Vicente Botet <vicente.botet@wanadoo.fr> wrote:
If you know that one of your types is string, then there would be no reason to use something more generic than Coerce or lexical_cast. However in generic programming it sometimes comes up that you need to convert from type X to type Y and you don't care whether either is a string.
Another interesting example of using Conversion along with Coerce is e.g. convert pair<string, string> to pair<int, int> If formatting options are required, I don't think there is any good way to convert between pair<int, string> and pair<string, int>. But that's got to be pretty rare.
participants (5)
-
Gordon Woodhull
-
Hartmut Kaiser
-
Jeroen Habraken
-
Nathan Ridge
-
Vicente Botet