#ifndef __TOTIPTR_H__ #define __TOTIPTR_H__ #include #include namespace mars { // TODO: Synchronize? template class ptr { private: int * ref; T * p; public: typedef T Type; inline ptr () { this->ref = new int; *this->ref = 1; this->p = NULL; } inline ptr (T * fly) { this->ref = new int; *this->ref = 1; this->p = fly; } inline ptr (const ptr & copy) { this->ref = copy.ref; ++(*this->ref); this->p = copy.p; } inline ptr & operator = (const ptr & copy) { if (!--(*this->ref)) { delete this->ref; delete this->p; } this->ref = copy.ref; ++(*this->ref); this->p = copy.p; return *this; } inline ptr & operator = (T * const p) { if (!--(*this->ref)) { delete this->ref; delete this->p; } this->ref = new int; *this->ref = 1; this->p = p; return *this; } inline T * operator -> () { return this->p; } inline T & operator * () { return *this->p; } inline const T * operator -> () const { return this->p; } inline const T & operator * () const { return *this->p; } inline bool operator == (const T * p) const { return this->p == p; } inline bool operator == (const ptr< T > & other) const { return p == other.p; } inline bool operator != (const T * p) const { return this->p != p; } inline bool operator < (const ptr< T > & other) const { return this->p < other.p; } inline T * pointer () { return p; } inline const T * pointer () const { return p; } inline ~ptr () { if (!--(*this->ref)) { delete this->ref; delete this->p; } } }; template< typename Subclass, typename Baseclass > Subclass * ptr_dynamic_cast (ptr< Baseclass > & p, Baseclass * = NULL) { return dynamic_cast< Subclass * > (p.pointer()); } template< typename Subclass, typename Baseclass > const Subclass * ptr_dynamic_cast (const ptr< Baseclass > & p, Baseclass * = NULL) { return dynamic_cast< const Subclass * > (p.pointer()); } template< typename Otherclass, typename Inputclass > Otherclass * ptr_static_cast (ptr< Inputclass > & p, Otherclass * = NULL) { return static_cast< Otherclass * > (p.pointer()); } template< typename Otherclass, typename Inputclass > const Otherclass * ptr_static_cast (const ptr< Inputclass > & p, Otherclass * = NULL) { return static_cast< const Otherclass * > (p.pointer()); } template class WeakReference { public: class StateEx : public std::exception {}; enum State { Weak = 0, Bound = 1 }; private: union { mars::ptr< T > * ppT; mars::ptr< std::string > * ppName; } _ptr; State _state; public: WeakReference (const WeakReference & copy) : _state(copy._state) { if ((copy._state == Weak && copy._ptr.ppName != NULL) || (copy._state == Bound && copy._ptr.ppT != NULL)) if (copy._state == Weak) _ptr.ppName = new mars::ptr (*copy._ptr.ppName); else if (copy._state == Bound) _ptr.ppT = new mars::ptr (*copy._ptr.ppT); else { _ptr.ppName = NULL; _ptr.ppT = NULL; } else { _ptr.ppName = NULL; _ptr.ppT = NULL; } } WeakReference () : _state(Weak) { _ptr.ppName = NULL; _ptr.ppT = NULL; } WeakReference (const std::string & name) : _state(Weak) { _ptr.ppName = new mars::ptr< std::string > (new std::string (name)); } WeakReference (const mars::ptr< std::string > & pName) : _state(Weak) { _ptr.ppName = new mars::ptr< std::string > (pName); } WeakReference (const mars::ptr< T > & ptr) : _state(Bound) { _ptr.ppT = new mars::ptr< T > (ptr); } inline const mars::ptr< T > & operator * () const { if (_state == Bound) return *_ptr.ppT; else throw StateEx(); } inline const mars::ptr< T > & operator -> () const { if (_state == Bound) return *_ptr.ppT; else throw StateEx(); } inline mars::ptr< T > & operator * () { if (_state == Bound) return *_ptr.ppT; else throw StateEx(); } inline mars::ptr< T > & operator -> () { if (_state == Bound) return *_ptr.ppT; else throw StateEx(); } inline bool operator == (const WeakReference< T > & other) const { if (_state != other._state) { if (_state == Weak) return other == **_ptr.ppName; else return **_ptr.ppT == **other._ptr.ppName; } else { switch (_state) { case Weak: return **_ptr.ppName == **other._ptr.ppName; case Bound: return **_ptr.ppT == **other._ptr.ppT; } } throw StateEx(); } inline WeakReference & operator = (const std::string & name) { if (_state == Bound) throw StateEx(); else { if (_ptr.ppName == NULL) _ptr.ppName = new mars::ptr< std::string > (new std::string (name)); else **_ptr.ppName = name; } return *this; } inline WeakReference & operator = (const WeakReference & copy) { _state = copy._state; if ((copy._state == Weak && copy._ptr.ppName != NULL) || (copy._state == Bound && copy._ptr.ppT != NULL)) if (copy._state == Weak) _ptr.ppName = new mars::ptr (*copy._ptr.ppName); else if (copy._state == Bound) _ptr.ppT = new mars::ptr (*copy._ptr.ppT); else { _ptr.ppName = NULL; _ptr.ppT = NULL; } else { _ptr.ppName = NULL; _ptr.ppT = NULL; } return *this; } inline State getState () const { return _state; } inline bool isNull () const { return (_ptr.ppName == NULL && _state == Weak) || (_ptr.ppT == NULL && _state == Bound); } inline void makeNull () { switch (_state) { case Weak: delete _ptr.ppName; _ptr.ppName = NULL; break; case Bound: delete _ptr.ppT; _ptr.ppT = NULL; break; } } inline const std::string & getName () const { if (_state == Weak && _ptr.ppName != NULL) return **_ptr.ppName; else return static_cast< const std::string & > (**_ptr.ppT); // T must implement an operator for std::string } inline operator const std::string & () const { return getName(); } inline void resolve (const mars::ptr< T > & p) { if (_state == Weak && _ptr.ppName != NULL) { delete _ptr.ppName; _ptr.ppT = new mars::ptr< T > (p); _state = Bound; } else throw StateEx(); } inline bool operator < (const WeakReference< T > & other) const { return getName() < other.getName(); } inline ~WeakReference () { switch (_state) { case Weak: delete _ptr.ppName; break; case Bound: delete _ptr.ppT; break; } } }; } #endif