Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2000-10-27 11:42:19


I was looking at the updated "lexical_cast.hpp," and I have some questions
and suggestions.

1. We usually reserve the "SAME_BASE_AS_HEADER.cpp" file for mandatory
items that the final programmer has to link in to use the header. You gave
that name ("lexical_cast.cpp") to a test file. You should change the name,
in case you later need an implementation file, and so new users don't assume
to add it in and get their programs to choke (since they'll have two 'main'
functions).

2. For "lexical_cast.hpp," it eventually needs a Boost-style header, and
could get a Boost-like guard-#include (like 'BOOST_LEXICAL_CAST_HPP'). I
don't think the "<new>" #include is needed any longer. (I was going to say
the same thing for "<typeinfo>," but I remembered that 'std::bad_cast' comes
from that header.)

3. You could use partial specialization to make certain cases of
lexical_cast:

a. The source and target types are the same

    template<typename SameType>
    SameType
    lexical_cast (SameType arg)
    {
        return arg;
    }

b. Both the source and target types are std::basic_string's (different
versions, though, to not be covered by [a])

    template< typename Ch1, typename Ch2, typename Tr1,
     typename Tr2, typename A1, typename A2 >
    std::basic_string< Ch2, Tr2, A2 >
    lexical_cast (std::basic_string< Ch1, Tr1, A1 > arg)
    {
        // Have to do some sort of cross-conversion,
        // maybe by (static) casting,
        // maybe by (locale) code conversion stuff
    }

c. A specialization of [b], where Ch1 and Ch2 are the same (you can do an
iterator copy in this case)

    template< typename Ch, typename Tr1, typename Tr2,
     typename A1, typename A2 >
    std::basic_string< Ch, Tr2, A2 >
    lexical_cast (std::basic_string< Ch, T1, A1 > arg)
    {
        return std::basic_string< Ch, Tr2, A2 >( arg.begin(), arg.end() );
    }

d. Either the source type or the target type is a std::basic_string (but
not both, to not be covered by [a]-[c])

    template< typename Target, typename Ch, typename Tr, typename A >
    Target
    lexical_cast (std::basic_string< Ch, Tr, A > arg)
    {
        std::basic_istringstream<Ch, Tr, A> interpreter( arg );
        Target result;

        if ( !(interpreter >> result) || !(interpreter >> std::ws).eof() )
            throw bad_lexical_cast();

        return result;
    }

    template< typename Ch, typename Tr, typename A, typename Source >
    std::basic_string< Ch, Tr, A >
    lexical_cast (Source arg)
    {
        std::basic_ostringstream<Ch, Tr, A> interpreter;

        if ( !(interpreter << arg) )
            throw bad_lexical_cast();

        return interpreter.str();
    }

I guess [b] would be the hardest, since I couldn't give you a quick
implementation of it.

-- 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

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