Boost logo

Boost :

Subject: Re: [boost] [review] string convert
From: Vicente BOTET (vicente.botet_at_[hidden])
Date: 2011-05-03 12:24:45


> Message du 03/05/11 11:11
> De : "Vladimir Batov"
> A : boost_at_[hidden]
> Copie à :
> Objet : Re: [boost] [review] string convert
>
> > Vladimir Batov people.net.au> writes:
> > > Vicente BOTET wanadoo.fr> writes:
> > > The library provides a convert_to function that adds the specific dummy
> > parameter. I recognize this is
> > > tricky and that the overloading seems not natural from the user perspective
> > but it works at least for the
> > > cases I have tested.
> >
> > Vicente, Gordon,
> >
> > Thank you for the pointer, I had a quick look and indeed it seems to solve the
> > specialization problem I was facing. Should we cancel/postpone this review and
> > review Vicente's and mine together or something of that sort? If Vicente's is
> > better as a starting point, it's fine by me. I am happy either way a s long as
> > things are moving.
>
> Vicente,
>
> I had a quick look and your proposal. Conceptually it seems to be an extension
> of lexical_cast philosophy on to type-to-type conversions. It does not seem to
> provide any of the functionality that I (as a user) care about, i.e., fallback
> value, throwing/non-throwing, formatting, locales, etc. Given convert_to
> actually returns a Target value, I suspect, formatting, locales, etc. are simply
> not possible as I believe we have to have an intermediary object (converter) to
> apply additional formatting, etc. Am I correct in my reading?
>
> If so, then you and I are trying to address totally unrelated issues. I needed
> 'convert' as lexical_cast not not doing what I needed it to do. I do not think I
> immediately have a need for type-to-type extension of lexical_cast.

Vladimir,

you are right. My library is not designed to take care of yours needs, and never was. I could do my best trying to update my library if there is enough interest and agreement in the interface. Next follows how I see the interface that could respond to the Boost.Convert features:

In order to take care of types without default constructor I see several options:

* Add an overloading having a default parameter

template
Target convert_to(Source const& s, Target const& t);

and use it as follows

Target t = convert_to(s, t1);

* Use the existing assign_to function

template
Target& assign_to(Target& t, Source const& s);

as follows

Target t (x);
assign_to(t, s);

* Add a meta-function that returns a default value for a type

template
struct default_value
{
T apply() { return T(); }
};

The user will need to specialize this function for types that are not default constructible.

This meta-function will be used instead of declaring a defaulted variable in the string conversion function.

T v(default_value::apply());

As a user I would prefer the second one and then the last one it is transparent except when the specialization is needed. The first option is not appealing for my taste.

In order to take care of no throwing semantics, I will choose to add a convert_to overloading with a error code parameter, not throwing without not knowing why fails seems too specific to me.

template
Target convert_to(Source const& s, err_code& ec);

Target t = convert_to(s, ec);
if (ec ....

But I could understand there are some cases where the single reason is a bad format. We could also use the no_throw_t as additional parameter, but in this case the return type should allow to know if the operation has succeed or not. If we follow the C++ standard interface the use of pair seems to be the more appropriated.

template
pair convert_to(Source const& s, no_thow_t const&);

pair p = convert_to(s, no_thow);
if (p.second)

Note also that there could be some conversions that could transport whether the conversion succeeds or not

optional t = convert_to >(s);

This conversion could be overloaded and never throw.

or a Robert suggested overload the pointer to a source

template
optional convert_to(Source const* s);

Both mechanism can be mixed

template
Target convert_to(Source const& s, Target const& t, err_code& ec);

Target t = convert_to(s, Target(x), ec);
if (ec ...

template
Target& assign_to(Target& t, Source const& s, err_code& ec);

Target t (x);
assign_to(t, s, ec);
if (ec ...

I think these could be added to Boost.Conversion without not to much trouble.
I could do my best for the Boost.Conversion part, if there is enough interest and agreement in the interface.

Respect to the stream manipulators, what do we want? output an output streameable type and extract another type after some manipulations.

Source s;
a_iostream ios;
Target t;

ios << s;
ios >> m1 >> m2 >> t;

But you want to hide the intermediary iostream. As I stated on one of my post it will be great if we can define a specific input stream that is built from an output stremable type that allows to extract the value stating whatever format is needed. What about

as_istream(s) >> m1 >> m2 >> t;

Respect to the functor I think that we need to use Phoenix syntax and overload the functions with a Phoenix placeholder to create the functor. So

convert_to(_1)

will return a functor that can be called with one Source parameter and return a Target. The same applies to each one of the other functions.

In this way each feature is separated and compassable, avoiding a bloated class that do everything.

The generic part of Boost.Conversion will not take care are the string conversions and the input stream view. Boost.StringConvert could take care of the string specializations.

I don't know if there are some features I have miss. Please let me know.

Best,
Vicente


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