Boost logo

Boost Users :

From: Terje Slettebų (tslettebo_at_[hidden])
Date: 2005-01-30 06:30:40


>From: "Terje Slettebų" <tslettebo_at_[hidden]>

> >From: "Yuval Ronen" <ronen_yuval_at_[hidden]>
>
> > >>1. lexical_cast(Source arg) takes the source argument by value. Why
not
> > >>by const& ? Calling lexical_cast(some_basic_string) now makes a copy
of
> > >>the source argument for no reason.
>
> template<typename Target, typename Source>
> Target lexical_cast(const Source &arg)
> {
> // Array-to-pointer decay
>
> typedef typename mpl::if_<
> is_array<Source>,
> add_pointer<add_const<remove_bounds<Source>::type>::type>::type,
> Source
> >::type NewSource;
>
> detail::lexical_stream<Target, NewSource> interpreter;
> Target result;
>
> if(!(interpreter << arg && interpreter >> result))
> throw_exception(bad_lexical_cast(typeid(NewSource),
> typeid(Target)));
> return result;
> }
>
> The additional includes are:
>
> #include <boost/type_traits/is_array.hpp>
> #include <boost/type_traits/remove_bounds.hpp>
> #include <boost/type_traits/add_pointer.hpp>
> #include <boost/type_traits/add_const.hpp>
> #include <boost/mpl/if.hpp>

Come to think of it, it can be done simpler and clearer, and avoiding any
extra includes, like this:

    namespace detail
    {
        template<class T>
        struct array_to_pointer_decay
        {
            typedef T type;
        };

        template<class T, size_t N>
        struct array_to_pointer_decay<T[N]>
        {
            typedef const T * type;
        };
    }

    template<typename Target, typename Source>
    Target lexical_cast(const Source &arg)
    {
        typedef typename detail::array_to_pointer_decay<Source>::type
NewSource;

        detail::lexical_stream<Target, NewSource> interpreter;
        Target result;

        if(!(interpreter << arg && interpreter >> result))
            throw_exception(bad_lexical_cast(typeid(NewSource),
typeid(Target)));
        return result;
    }

This requires support for partial specialisation, but so does remove_bounds
used in the first suggestion, so it doesn't change the compiler
requirements. Besides, the current version of lexical_cast in CVS doesn't
work with MSVC 6, anyway. Of course, if this was very important, I guess it
would be possible to fall back to pass by value for MSVC 6, and possibly fix
other problems with it. I also see that MSVC 6 is no longer part of the
Boost regression test.

Regards,

Terje


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net