Boost logo

Boost :

Subject: [boost] [exception] ostringstream like
From: fabien (fabien.castan_at_[hidden])
Date: 2010-08-15 08:04:39


Hi,

I would like to propose an "error_info_sstream" class, allowing to do:

Point3D p;
int id;
boost::filesystem::path path;
...
BOOST_THROW_EXCEPTION( exception::Logic()
     << exception::user( "Foo failed." )
     << exception::dev() + "Foo failed at index " + id + " at position "
+ p + "."
     << exception::filename( path->filename() ) );

With a declaration, like that:

namespace MyProject {
namespace exception {
typedef ::boost::error_info<struct
tag_userMessage,::boost::error_info_sstream> user;
typedef ::boost::error_info<struct
tag_devMessage,::boost::error_info_sstream> dev;
typedef ::boost::errinfo_file_name filename;

struct Logic : virtual public ::std::exception, virtual public
::boost::exception {};
}
}

The idea is to remove such things:

BOOST_THROW_EXCEPTION( exception::Logic()
     << exception::user( "Foo failed." )
     << exception::dev( std::string("Foo failed at index ") +
boost::lexical_cast<std::string>(id) + " at position [x:" +
boost::lexical_cast<std::string>(p.x) + ",y:" +
boost::lexical_cast<std::string>(p.y) + ",z:" +
boost::lexical_cast<std::string>(p.z) + "]." )
     << exception::filename( path->filename() ) );

or

std::ostringstream msg;
msg << "Foo failed at index " << id << " at position " << p << ".";
BOOST_THROW_EXCEPTION( exception::Logic()
     << exception::user( "Foo failed." )
     << exception::dev(msg)
     << exception::filename( path->filename() ) );

The proposed solution is to have an error_info with an operator+, doing
the same thing as an operator<< on an ostringstream.

1) Are you agree with this idea ?
2) Are you agree with this implementation ? I write this without
understanding all internal things inside boost::exception.
3) Are you interested to add something like that in boost::exception ?

Best regards,
Fabien Castan

namespace boost {

        struct error_info_sstream
        {
         typedef std::ostringstream value_type;
         value_type _v;
        };

     inline
     std::string
     to_string( const error_info_sstream& x )
        {
                return x._v.str();
        }

     template<class Tag>
     class error_info<Tag, error_info_sstream>: public
exception_detail::error_info_base
        {
        public:
         typedef error_info_sstream T;
         typedef error_info<Tag,T> This;
         typedef T value_type;

                error_info(){}
                error_info( const This& v )
                {
                        _value._v << v._value._v.str();
                }
                template<typename V>
         error_info( const V& value )
                {
                        _value._v << value;
                }
         ~error_info() throw() {}

                template<typename V>
                This& operator+( const V& v )
                {
                        _value._v << v;
                        return *this;
                }
                
         const value_type& value() const { return _value; }
         value_type& value() { return _value; }
        private:
         std::string tag_typeid_name() const { return
tag_type_name<Tag>(); }
         std::string value_as_string() const { return _value._v.str(); }

         value_type _value;
        };
}


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