Boost logo

Boost :

Subject: Re: [boost] [review] string convert
From: Matthew Chambers (matt.chambers42_at_[hidden])
Date: 2011-05-09 16:32:24


On 5/9/2011 9:08 AM, Stewart, Robert wrote:
> This leaves the fate of the converter function objects unclear. That functionality seems too useful to drop. Two sets are needed now? One set would be for non-streams-based conversions and the other set for streams-based conversions? The latter would support manipulators and the former would not.
>
> To summarize, here's the complete API as I see it now:
>
> 1. convert::default_value<T> customization point
> * Default value, if needed, when not otherwise supplied
>
> 2. convert::converter<T,S> customization point
> * Non-stream-based main logic
> * Functor interface
>
> 3. T convert::convert_cast<T,S>(S)
> * Throws on failure unless T is convert::result<T'>
> * Uses convert::converter<T,S> to do conversion
>
> 4. T convert::convert_cast<T,S>(S, T _fallback)
> * Returns _fallback on failure unless T is convert::result<T'>
> * Uses convert::converter<T,S> to do conversion
>
> 5. bool convert::try_converting_to<T,S>(S, T& _value)
> * Returns false and leaves _value unchanged on failure
> * Uses convert::converter<T,S> to do conversion
>
> 6. convert::stream_converter<T,S> customization point
> * Stream-based main logic
> * Functor interface
> * Supports manipulators
>
> 7. T convert::as<T,S>(S, options)
> * Throws on failure
> * Uses convert::stream_converter<T,S> to do conversion
>
> 8. T convert::as<T,S>(S, T _fallback, options)
> * Returns _fallback on failure
> * Uses convert::stream_converter<T,S> to do conversion
>
> 9. bool convert::try_as<T,S>(S, T& _value, options)
> * Returns false and leaves _value unchanged on failure
> * Uses convert::stream_converter<T,S> to do conversion
>
> Does that cover everything satisfactorily? Did I miss something? Except where I have suggested specific support for convert::result, I don't think it should be allowed. (That is, use SFINAE to ensure that convert::result isn't used with the other parts of the API.)
>
> If that's a decent API, and since it represents the combination of the functionality in both Vicente's and your library, perhaps the two of you could collaborate on it and produce a new Boost.Convert proposal. (I'd prefer Boost.Convert to Boost.Conversion because the namespace name is shorter and more useful when reading names like "convert::as.")

When you say "stream-based main logic" do you mean that it should appear to be using streams, but
that it doesn't matter if it really does? It's reasonable to develop optimized string<->numeric
converting code that respects locale and manipulators, so I don't think we should exclude the
possibility of such implementations. If we're going to create two APIs, I'd rather have one for
string<->numeric conversion and one for type<->type conversion. I also don't understand the shift
from "convert_cast" to "as". It isn't intuitive why one uses streams and the other doesn't.

The specialization for convert::result doesn't bother me, but I suspect it will garner the same
criticism as Vladimir's original proposal (i.e. why not optional<T>?).

I agree we need to support multiple manipulators, but yuck! The nicest way I can think of to do that
is with separate parameters for each manipulator category:

int i = convert::as<int>("+42", (_showpos=true, _base=ios::oct));
string s = convert::as<string>(123.456, (_scientific=true)); // or _float=ios::scientific ?

Passing them in as a vector would as bad or worse and we've already decided against having to store
them in a stateful converter.

-Matt


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk