Boost logo

Boost :

From: Mattias Flodin (flodin_at_[hidden])
Date: 2002-03-21 13:07:30


I've been pondering over a way to solve this little problem every once in a
while. Because I don't want to leave the asian people out, I prefer to write
my Win32-based programs with unicode support, and I find the support for
Unicode in C++ poorer than it seems some people would like to think (e.g. no
Unicode filenames for fstream). I would love if the new things that Boost
adds do not remain blind to these things, especially considering how much it
seems to value genericity in other areas.

My favorite syntax, if possible, would be supporting lexical_cast<string>(x)
and lexical_cast<wstring>(x), both of which would convert to strings of the
respective types. This does not seem like an impossible task (given a a few
hours of spare time). One way would be with partial specialization; an
example follows (probably has a few syntax errors, can't check it at this
moment).

A problem with this approach is that it would make lexical_cast a little more
oriented toward usage with basic_string; on the other hand, even now the
documentation talks mostly about using this for basic_string. I cannot think
of any way to, given an arbitrary String class, determine the type of the
character elements. This would be required if one wants to know what value
type to use for basic_stringstream. If I have to choose between fully
supporting basic_string (and not just one specialization of it), and
supporting any kind of string that uses char as its value type and has
operator<< / operator>> overloaded, I would choose the former. After all,
both unicode and 8-bit character applications etc are fully valid, whereas as
far as strings go we want people to use std::basic_string, right? :)

Perhaps a middle-way would be to require all implementors of strings that are
to be compatible with lexical_cast to provide a value_type()-style function.

/Mattias

namespace detail {
    template<typename Target, typename Source>
    struct lexical_caster;

    // casts from arbitrary type to basic_string
    template<class CharType, class Traits, class Allocator, typename Source>
    struct lexical_caster<
        std::basic_string<CharType, Traits, Allocator>,
        Source>
    {
        std::basic_string<CharType, Traits, Allocator>
            operator()(const Source& arg)
        {
            std::basic_stringstream<CharType> interpreter;
            std::basic_string<CharType, Traits, Allocator> result;
            interpreter << arg; // need to do error check and throw here
            interpreter >> result;
            return result;
        }
    };

    // casts from basic_string to arbitrary type
    template<typename Target, class CharType, class Traits, class Allocator>
    struct lexical_caster<Target,
        std::basic_string<CharType, Traits, Allocator> >
    {
        Target operator()(
            const std::basic_string<CharType, Traits, Allocator>& arg)
        {
            std::basic_stringstream<CharType> interpreter;
            interpreter << arg; // need to do error check and throw here
            interpreter >> result;
            return result;
        }
    };
} // end namespace detail
            
template<typename Target, typename Source>
Target lexical_cast(Source arg)
{
    detail::lexical_caster<Target, Source> caster;
    return caster(arg);
}

On Thu, Mar 21, 2002 at 06:43:50PM +0200, Yitzhak Sapir wrote:
> I had recommended before implementing a wlexical_cast for this.
> Something along the lines of:
>
> template <typename Target, typename Source, typename Interpreter>
> Target basic_lexical_cast(const Source& a_Source, Interpreter
> a_Interpreter)
> {
> // use a_Interpreter for returning target
> }
>
> template <typename Target, typename Source>
> Target lexical_cast(const Source& a_Source)
> {
> return basic_lexical_cast(a_Source, std::stringstream());
> }
>
> template <typename Target, typename Source>
> Target wlexical_cast(const Source& a_Source)
> {
> return basic_lexical_cast(a_Source, std::wstringstream());
> }

-- 
Mattias Flodin <flodin_at_[hidden]>  -  http://www.cs.umu.se/~flodin/
Room L3.06.14
Department of Computing Science
Umeå University
S-901 87 Umeå, Sweden
--
If trees could scream, would we be so cavalier about cutting them down?  We
might, if they screamed all the time, for no good reason. -- Jack Handy

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