Boost logo

Boost :

Subject: Re: [boost] [lexical_cast] char types and UDTs
From: Antony Polukhin (antoshkka_at_[hidden])
Date: 2012-04-11 13:57:02


2012/4/11 Eric Niebler <eric_at_[hidden]>:
> Calling m.str() creates a temporary std::wstring object, which incurs a
> dynamic allocation and is slow. Speaking for my own library (xpressive),
> sub_match has an optimized stream insertion operator. It should be used.

sub_match ostream operator is defined as:
std::ostream_iterator<char_type, Char, Traits> iout(sout); // where
sout is std::basic_ostream<Char, Traits>
std::copy(sub.first, sub.second, iout);

std::basic_ostream<Char, Traits> on uses std::basic_string, so copying
ddata to it can incur a multiple
dynamic allocations and multiple copings of data.

2012/4/11 Eric Niebler <eric_at_[hidden]>:
> Olaf van der Spek wrote:
>> How could it automatically determine the necessary character type?
>
> It can't be done automatically, but lexical_cast can expose the
> stream_char trait and make it a documented part of the interface. Users
> can specialize it for their types.

I`ll try to restore boost::detail::stream_char functionality, but I
won't try hard. That is not a nice solution.

I`ll also remove notes about adding lexical_cast specializations.,
because it can break some code, that uses &boost::lexical_cast<Dst,
Src>;

But that is not an optimal solution.
Optimal solution would look like (not tested, required just to get the idea):

template <class Target, class Source>

Target lexical_cast_ext(Source&& s) {

    Target t;

    if (!::boost::try_lexical_cast(t, std::forward<Source>(s)))
// No ADL
        BOOST_LCAST_THROW_BAD_CAST(Source, Target);

    return t; // RVO must be applied by compiler

}

template <class Target, class Source>

bool try_lexical_cast_ext(Target& t, Source&& s) noexcept {

    using namespace boost::detail; // For getting default
`construct_lexical_cast_in_trait' and
`construct_lexical_cast_out_trait'

    const auto& in =
construct_lexical_cast_in_trait(std::forward<Source>(s)); // ADL

    if (in.fail()) return false;

    typedef boost::mpl::identity<Target> target_tag;

    // Must have up to 4 construct_lexical_cast_out_trait
    // {with parameters const char*, const wchar_t*, const char16_t*,
const char32_t*}

    return construct_lexical_cast_out_trait(target_tag(), in.begin(),
in.end()) // ADL

        .assign_value(t);
         // returns true if conversion is OK

}

User will need to add one `construct_lexical_cast_in_trait' and up to
four `construct_lexical_cast_out_trait' functions to the namespace of
user-defined class.

This will allow us to :

* get correct function pointers via &lexical_cast<Source, Target>;
(lexical_cast overloading solution breaks that)

* use stream operators << and >> in default lexical_cast traits

* tune lexical_cast for fast conversions to string
types(deduce_char_traits<> specializing solution does not solve that)

* tune lexical_cast for fast conversions from string types(both
solutions do not solve that)

* convert from any type to any type through usage of any character
type (both solutions do not solve that)

* relax all the type requirements (current implementation does not allow that)

* have a noexcept version (current implementation does not allow that)

Any objections? Did I miss something except conversion tags for specifying base?

But this looks more like a NEW lexical_cast library. It must be
implemented and reviewed.

I remember all the unsuccessful attempts to implement new conversion
libraries, so until there is no huge interest in new lexical_cast
library I will not give it a try.

All other solutions have drawbacks and there will be always someone
who needs more.

Conclusion: If a higher degree of control is required over conversions
std::stringstream and std::wstringstream must be used.
 Or find lots of people, interested in NEW lexical_cast library.

-- 
Best regards,
Antony Polukhin

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