diff --git a/src/templates/smartp.hh b/src/templates/smartp.hh index 9f249ff..d9e648b 100644 --- a/src/templates/smartp.hh +++ b/src/templates/smartp.hh @@ -44,6 +44,10 @@ namespace memory { */ template class smart_ptr { + + template + friend class smart_ptr; + public: /** \brief An alias for the smart_ptr which contains null @@ -117,36 +121,38 @@ namespace memory { * \return The number of references */ inline unsigned int alive_refs() const throw(); - /** \brief Dynamic cast the stored pointer - * to another type + * to another type, returning a smart_ptr * * This functions tries to cast the stored * object to the given type. * - * \param U The type to cast to. - * \return A reference of the casted type + * \param U The type to cast the stored pointer to + * \return A smart_ptr of the wanted type * \exception bad_alloc Raise this exception if - * the cast isn't successful. + * the cast isn't successful or doable */ template - inline U& cast_to() throw(std::bad_cast); + inline smart_ptr cast_to() throw(std::bad_cast); /** \brief Dynamic cast the stored pointer - * to another type + * to another type, returning a smart_ptr * * This functions tries to cast the stored * object to the given type. * - * \param U The type to cast to. - * \return A const reference of the casted type + * \param U The type to cast the stored pointer to + * \return A smart_ptr of the wanted type * \exception bad_alloc Raise this exception if - * the cast isn't successful. + * the cast isn't successful or doable */ template - inline const U& cast_to() const throw(std::bad_cast); + inline const smart_ptr cast_to() const throw(std::bad_cast); private: + template + smart_ptr(const smart_ptr& sptr) throw(std::bad_cast); + struct contents_type { T* ptr; unsigned int rc; diff --git a/src/templates/smartp.tcc b/src/templates/smartp.tcc index 1e10500..a384236 100644 --- a/src/templates/smartp.tcc +++ b/src/templates/smartp.tcc @@ -143,25 +143,33 @@ namespace memory { template template - U& - smart_ptr::cast_to() throw(std::bad_cast) + smart_ptr + smart_ptr::cast_to() throw(std::bad_cast) { - if(_contents->ptr != 0) - return dynamic_cast(*_contents->ptr); - else - throw std::bad_cast(); + return smart_ptr(*this); } template template - const U& + const smart_ptr smart_ptr::cast_to() const throw(std::bad_cast) { - if(_contents->ptr != 0) - return dynamic_cast(*_contents->ptr); - else + return smart_ptr(*this); + } + + + template + template + smart_ptr::smart_ptr(const smart_ptr& sptr) + throw(std::bad_cast) + { + if(!sptr._contents->ptr || dynamic_cast(sptr._contents->ptr) == 0) throw std::bad_cast(); + + // I know, I know... this is Evil(TM): + _contents = reinterpret_cast::contents_type*>(sptr._contents); + (_contents->rc)++; } } //~ namespace memory