- Add extended support for casting between different types

of smart_ptr


git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@507 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
tchernobog 2006-03-08 12:49:14 +00:00
parent e0142149b0
commit 1388eeeac1
2 changed files with 35 additions and 21 deletions

View File

@ -44,6 +44,10 @@ namespace memory {
*/ */
template<typename T, bool isArray = false> template<typename T, bool isArray = false>
class smart_ptr { class smart_ptr {
template<typename T2, bool isArray2>
friend class smart_ptr;
public: public:
/** \brief An alias for the smart_ptr which contains null /** \brief An alias for the smart_ptr which contains null
@ -117,36 +121,38 @@ namespace memory {
* \return The number of references */ * \return The number of references */
inline unsigned int alive_refs() const throw(); inline unsigned int alive_refs() const throw();
/** \brief Dynamic cast the stored pointer /** \brief Dynamic cast the stored pointer
* to another type * to another type, returning a smart_ptr
* *
* This functions tries to cast the stored * This functions tries to cast the stored
* object to the given type. * object to the given type.
* *
* \param U The type to cast to. * \param U The type to cast the stored pointer to
* \return A reference of the casted type * \return A smart_ptr of the wanted type
* \exception bad_alloc Raise this exception if * \exception bad_alloc Raise this exception if
* the cast isn't successful. * the cast isn't successful or doable
*/ */
template<typename U> template<typename U>
inline U& cast_to() throw(std::bad_cast); inline smart_ptr<U,isArray> cast_to() throw(std::bad_cast);
/** \brief Dynamic cast the stored pointer /** \brief Dynamic cast the stored pointer
* to another type * to another type, returning a smart_ptr
* *
* This functions tries to cast the stored * This functions tries to cast the stored
* object to the given type. * object to the given type.
* *
* \param U The type to cast to. * \param U The type to cast the stored pointer to
* \return A const reference of the casted type * \return A smart_ptr of the wanted type
* \exception bad_alloc Raise this exception if * \exception bad_alloc Raise this exception if
* the cast isn't successful. * the cast isn't successful or doable
*/ */
template<typename U> template<typename U>
inline const U& cast_to() const throw(std::bad_cast); inline const smart_ptr<U,isArray> cast_to() const throw(std::bad_cast);
private: private:
template<typename U>
smart_ptr(const smart_ptr<U,isArray>& sptr) throw(std::bad_cast);
struct contents_type { struct contents_type {
T* ptr; T* ptr;
unsigned int rc; unsigned int rc;

View File

@ -143,25 +143,33 @@ namespace memory {
template<typename T, bool isArray> template<typename T, bool isArray>
template<typename U> template<typename U>
U& smart_ptr<U, isArray>
smart_ptr<T,isArray>::cast_to() throw(std::bad_cast) smart_ptr<T, isArray>::cast_to() throw(std::bad_cast)
{ {
if(_contents->ptr != 0) return smart_ptr<U, isArray>(*this);
return dynamic_cast<U&>(*_contents->ptr);
else
throw std::bad_cast();
} }
template<typename T, bool isArray> template<typename T, bool isArray>
template<typename U> template<typename U>
const U& const smart_ptr<U, isArray>
smart_ptr<T, isArray>::cast_to() const throw(std::bad_cast) smart_ptr<T, isArray>::cast_to() const throw(std::bad_cast)
{ {
if(_contents->ptr != 0) return smart_ptr<U, isArray>(*this);
return dynamic_cast<U&>(*_contents->ptr); }
else
template<typename T, bool isArray>
template<typename U>
smart_ptr<T,isArray>::smart_ptr(const smart_ptr<U,isArray>& sptr)
throw(std::bad_cast)
{
if(!sptr._contents->ptr || dynamic_cast<T*>(sptr._contents->ptr) == 0)
throw std::bad_cast(); throw std::bad_cast();
// I know, I know... this is Evil(TM):
_contents = reinterpret_cast<typename smart_ptr<T,isArray>::contents_type*>(sptr._contents);
(_contents->rc)++;
} }
} //~ namespace memory } //~ namespace memory