Boost logo

Boost :

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


Vladimir Batov wrote:
> > From: "Stewart, Robert" <Robert.Stewart_at_[hidden]>
> >> Vladimir Batov wrote:

There are several threads of discussion going on here and I'd like to avoid letting them fragment too much, so this reply includes thoughts that don't apply directly to what you've written.

> >> int i = boost::convert::to<int>(str);
> >
> > That's good.
>
> How about we simplify the API down to just:
>
> T convert::to<T>(S, boost::parameter-list);

Vicente has been discussing the issue of stream-based conversions WRT manipulators. In lexical_cast-style conversions, there's an insertion followed by an extraction. Are manipulators needed for both directions? If so, the interface must allow for them using, say, "in" and "out" keywords instead of "format_."

to<T>() seems a very nice name for stream-based conversions. It can be qualified by the namespace name, convert::to<T>(), or not and it is still readable. That function can, one way or another, provide support for manipulators while convert_cast<T>() can skip them. That means that to<T>() can be used for stream-based conversions and convert_cast<T>() for non-stream-based conversions. Whether the latter must provide any l10n support is for others to determine as I simply don't know enough to say.

> Then we specialize it for convert::result type so that
>
> convert::result<T> convert::to<result<T>>(S, boost::parameter-
> list);

That strikes me as a very nice compromise.

> // The predictable. Throws on failure
> int i = convert::to<int>("FF", (format_ = std::hex))

Good for stream-based formatting.

convert_cast<int>("FF") would be the non-streams-based equivalent.

> // The predictable. Returns fallback on failure
> int i = convert::to<int>("FF", (fallback_ = 255, locale_= ...,
> format_ = std::hex, throw_ = true))

Good for stream-based formatting. I presume you meant "throw_ = false." I think nothrow (or similar) is better than "throw_ = false," however.

try_converting_to<int>("FF", 255) would be the non-streams-based equivalent.

> // The predictable. Has fallback but is forced to throw on
> failure
> int i = convert::to<int>("FF", (fallback_ = 255, locale_= ...,
> format_ = std::hex, throw_ = true))

Good for stream-based formatting.

convert_cast<int>("FF", 255) would be the non-streams-based equivalent.

> // The 'try' version
> int v = 255;
> bool success = convert::try_to<int>("FF", v, (locale_= ...,
> format_ = std::hex))

I don't like that name. "to<int>" says the right thing. "try_to<int>" doesn't. It makes me think "int" is a verb, as in "try to jump."

If "to" were "as" instead, then this could be "try_as:"

   success = convert::try_as<int>("FF", v, ...);

> // My personal favorite (locally implemented or incorporated
> into the lib.)
> convert::result<int> res = convert::to<result<int>>("FF",
> (fallback_ = 255, locale_= ..., format_ = std::hex));

Good for stream-based formatting.

convert_cast<convert::result<int>>("FF") would work for non-streams-based conversions.

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

_____
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