Boost logo

Boost :

Subject: Re: [boost] [review] string convert
From: Stewart, Robert (Robert.Stewart_at_[hidden])
Date: 2011-05-09 17:10:01


Matthew Chambers wrote:
> On 5/9/2011 9:08 AM, Stewart, Robert wrote:
>
> > 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.)
>
> 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?

No. I meant that all of the stream-based conversions are done via the stream_converter class. It is the customization point and, therefore, the common place in which to handle any special cases for the stream-based conversions.

Likewise, the converter class is the customization point and the common place in which to handle special cases for non-stream-based conversions.

That approach means that all conversions are handled by one class template for each of the two conversion styles. The various function templates are merely wrappers which provide type deduction and things like exception throwing and varying return types.

> 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 such logic can be added to provide conversions as if a stream was used but without using a stream, then it fits as a stream_converter specialization.

> 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.

My idea was that the convert_cast part of the interface was not stream-based and, therefore, incorporated Vicente's ideas, and that the "as" part was stream-based and, therefore, incorporated Vladimir's ideas.

> 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 think the issue is merely one of documentation, showing the difference in features. IOW, here's the code with result and here's the code with optional. See how nice result makes the code?

That may be moot now, given the get_value_or() epiphany. Nevertheless, Vladimir correctly noted that he can add the result interface for his own use if it isn't part of a Boost library.

> 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 ?

Do those apply to the insertion into or extraction from the stream?

> 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.

Quite.

_____
Rob Stewart robert.stewart_at_[hidden]
Software Engineer using std::disclaimer;
Dev Tools & Components
Susquehanna International Group, LLP http://www.sig.com

IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.


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