Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2003-03-22 11:19:45


>From: "Kevlin Henney" <kevlin_at_[hidden]>

> In message <u8yv7tv6e.fsf_at_[hidden]>, David Abrahams
> <dave_at_[hidden]> writes
> >
> >There's no guarantee you have readable names anyway.
>
> That's a purely theoretical rather than practical consideration. In
> practice, I believe that all of the compilers that lexical_cast works
> under offer something relatively meaningful. The original version of
> lexical_cast simply stated, with a string literal, that the conversion
> had failed. There was some user demand for supplementary information,
> which Terje's version provided.
>
> However, the decision as to whether this should be in the 'what' string
> is perhaps one that can be revisited.

Indeed. :)

I wasn't sure what kind of interface to use for this, so I just made it part
of the what() string.

> It would be feasible to avoid any
> allocation issues at all by leaving the human readable string as general
> as it was before and adding type_info members that described the source
> and target types.

Yes. Since type_info objects can't be copied, one might instead store
pointers or references to them. This appears to need yet another inheritance
layer, though, unless the virtual functions for accessing the type_info
objects are made part of bad_lexical_cast. For example:

    // exception used to indicate runtime lexical_cast failure
    class bad_lexical_cast : public std::bad_cast
    {
    public:
        virtual const std::type_info &source_type() const throw() = 0;
        virtual const std::type_info &target_type() const throw() = 0;

        virtual ~bad_lexical_cast() throw()
        {
        }
    };

    namespace detail // actual underlying concrete exception type
    {
        template<typename Target, typename Source>
        class no_lexical_conversion : public bad_lexical_cast
        {
        public:
            virtual const std::type_info &source_type() const throw() {
return typeid(Source); }
            virtual const std::type_info &target_type() const throw() {
return typeid(Target); }

            virtual ~no_lexical_conversion() throw()
            {
            }
            virtual const char *what() const throw()
            {
                return "bad lexical cast: "
                           "source type value could not be interpreted as
target"
            }
        };
    }

This also addresses the concern of readable type names, and leaves the
what() string as it was.

> This leads to a number of possible options:
>
> (1) Use the static solution, as Terje originally intended, and use the
> current solution only for VC6.
> (2) Rollback the design to something closer to the original, ie a fixed-
> string literal message as the result of calling 'what', and provide
> supplementary information for handlers that care enough to catch a
> bad_lexical_cast.

I think this is a good solution, and it eliminates any throws from the
exception. This may also be a more flexible solution, as the type_info
objects may be used directly, in any custom error message.

> (3) Play around with C-style memory management and allocate arrays on
> demand, being sure to trap any bad outcome.
> (4) Leave as is.

Regards,

Terje


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