Search code examples
c++apiboostcompatibilityboost-exception

Boost: API changes between 1.46.1 and 1.58.0?


My application is on Boost version 1.46.1. I want to port my application on Boost version 1.58.0. However I am facing some problems.

I have noticed that boost 1.58 has different implementation of boost::exception_ptr from 1.46.1. In 1.46.1, boost::exception_ptr was implemented as shared pointer:

typedef shared_ptr<exception_detail::clone_base const> exception_ptr; 

where as in 1.58 all the implementation was encapsulated inside a class.

class exception_ptr {
    typedef boost::shared_ptr<exception_detail::clone_base const> impl;
    impl ptr_;
    friend void rethrow_exception(exception_ptr const &);
    typedef exception_detail::clone_base const *(impl::*unspecified_bool_type)() const;

public:
    exception_ptr() {}
    explicit exception_ptr(impl const &ptr) : ptr_(ptr) {}
    bool operator==(exception_ptr const &other) const { return ptr_ == other.ptr_; }
    bool operator!=(exception_ptr const &other) const { return ptr_ != other.ptr_; }
    operator unspecified_bool_type() const { return ptr_ ? &impl::get : 0; }
};

Due to this changes my code is breaking... :(


boost::exception_ptr ExceptionHelper::GetExceptionPtr(MyExceptionPtr_t exception) {
    boost::exception_ptr result =
        boost::dynamic_pointer_cast<boost::exception_detail::clone_base const>(exception); // This is giving build error
    return result;
}

MyExceptionPtr_t ExceptionHelper::TryGetMyExceptionPtr(boost::exception_ptr exception) {
    MyExceptionPtr_t result;

    boost::shared_ptr<const Exception> constPtr =
        boost::dynamic_pointer_cast<const Exception>(exception); // This is giving build error.
    if (constPtr) {
        result = boost::const_pointer_cast<Exception>(constPtr);
    }
    return result;
}

std::string ExceptionHelper::GetThrowFilename(const boost::exception_ptr exception) {
    std::string result;
    if (exception) {
        if (boost::get_error_info<boost::throw_file>(*exception)) // This is giving build error.
        {
            result = *boost::get_error_info<boost::throw_file>(*exception);
        }
    }
    return result;
}

Could you please suggest me, how to fix the above errors ??

Thanks


Solution

  • boost::exception_ptr is Default Constructible, Copy Constructible, Assignable and Equality Comparable. None of these operations allow you to extract the captured exception itself. No other operations are specified on the class itself. This hasn't changed from 1.46.1 to 1.58.0; the only difference is that the implementation has been changed so it is harder to accidentally use features of boost::exception_ptr that are not part of the specified interface (as your code does).

    The only other operations possible are:

    template <class T>
    exception_ptr copy_exception( T const & e );    
    
    exception_ptr current_exception();    
    
    void rethrow_exception( exception_ptr const & ep );
    

    rethrow_exception is the function that you want here. To extract the data from the exception_ptr, rethrow it, and then deal with the data in a catch block (this matches the model used for std::exception_ptr, so you won't have to make further changes when you eventually move to a compiler that supports C++11):

    std::string ExceptionHelper::GetThrowFilename(
        const boost::exception_ptr exception)
    {
        std::string result;
        if (!exception) return result;
        try {
            boost::rethrow_exception(exception);
        }
        catch (boost::exception const &e) {
            boost::throw_file::value_type const *throw_file_data =
                boost::get_error_info<boost::throw_file>(e)
            if (throw_file_data) {
                result = *throw_file_data;
            }
        }
        return result;
    }
    

    I don't know what MyExceptionPtr_t is for. It looks like it could be replaced by boost::exception_ptr (and so the conversion functions could be made unnecessary), but without all of the code it is hard for me to say for sure.