|
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