Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages

RRef.hh

Go to the documentation of this file.
00001 #ifndef NO_PTR_RREF_H
00002 #define NO_PTR_RREF_H
00003 
00023 #include "nullness.hh"  // use
00024 #include "RRefUsage.hh" // use
00025 #include "NoPtrFwd.hh"  // use
00026 
00027 namespace NoPtr
00028 {
00030     template <typename TT>
00031     inline bool 
00032     isNull(const RRef<TT>& p) {return p.isNull();}
00033 
00035     template <typename TT>
00036     inline bool 
00037     isNotNull(const RRef<TT>& p) {return p.isNotNull();}
00038     
00039     template <typename ObjType>
00040     class RRef
00041     {
00042         public:
00044             typedef ObjType ObjectType;
00045 
00046         public:
00048                 
00051             RRef() throw(): _obj(NullPtr) {}
00052         
00054             RRef(const RRef& rhs): _obj(rhs.getPtr()) 
00055             { 
00056                 if (_obj) _rrefUsage.shareFrom(rhs._rrefUsage);
00057             }
00058 
00063             template <typename ObjType2> 
00064             RRef(const RRef<ObjType2>& rhs): _obj(rhs.getPtr()) 
00065             { 
00066                 if (_obj) _rrefUsage.shareFrom(rhs._rrefUsage);
00067             }
00068             
00076             template <typename ObjType2, class Context> 
00077             RRef(const DynObj<ObjType2,Context>& rhs)
00078                 : _obj(rhs.getPtr()) 
00079             { 
00080                 if (_obj) 
00081                 {
00082                     rhs.getRRefUsage(_rrefUsage);
00083                     assert(_rrefUsage.isValid());
00084                 }
00085             }
00086             
00092             RRef(ObjType& rrefable): _obj(&rrefable)
00093             { 
00094                 rrefable.getRRefUsage(_rrefUsage);
00095                 assert(_rrefUsage.isValid());
00096             }
00097             
00099             
00100             // Just need to destroy our share of _rrefUsage
00101            ~RRef() { _rrefUsage.destroy(); }
00102 
00103         public:
00105                 
00109             void reset() 
00110             { 
00111                 _obj = NullPtr; 
00112                 _rrefUsage.reset();
00113             }
00114         
00121             template <typename ObjType2>
00122             void reset(const RRef<ObjType2>& rhs) 
00123             { 
00124                 ObjType2* const obj = rhs.getPtr();
00125                 if (obj == _obj) return;
00126                 
00127                 _rrefUsage.reset();
00128                 _obj = obj; 
00129                 if (_obj) _rrefUsage.shareFrom(rhs._rrefUsage);
00130             }
00131             
00136             template <typename ObjType2, class Context>
00137             void reset(const DynObj<ObjType2,Context>& rhs)
00138             { 
00139                 ObjType2* const obj = rhs.getPtr();
00140                 if (obj == _obj) return;
00141                 
00142                 _rrefUsage.reset();
00143                 _obj = obj; 
00144                 if (_obj) 
00145                 {
00146                     rhs.getRRefUsage(_rrefUsage);
00147                     assert(_rrefUsage.isValid());
00148                 }
00149             }
00158             void reset(ObjType& rrefable) 
00159             { 
00160                 if (_obj == &rrefable) return;
00161                 
00162                 _rrefUsage.reset();
00163                 _obj = &rrefable; 
00164                 rrefable.getRRefUsage(_rrefUsage);
00165                 assert(_rrefUsage.isValid());
00166             }
00167             
00169             
00171             
00173             void swap(RRef& rhs) throw() 
00174             {
00175                 std::swap(_obj, rhs._obj);
00176                 _rrefUsage.swap(rhs._rrefUsage);
00177             }
00178             
00180             bool isNotNull() const throw() {return getPtr() != NullPtr;}
00182             bool isNull()    const throw() {return getPtr() == NullPtr;}
00183 
00186             ObjType* getPtr() const throw() 
00187             { 
00188                 return _rrefUsage.isValid() ? _obj : NullPtr; 
00189             }
00191             
00192         public: // pointer access operators
00193 
00195                 
00203             ObjType& operator()() const
00204             {
00205                 return *(operator->());
00206             }
00207             
00212             ObjType& operator*() const
00213             {
00214                 return *(operator->());
00215             }
00216             
00218             RRef& operator=(const RRef& rhs) 
00219             { 
00220                 reset(rhs); 
00221                 return *this;
00222             }
00224             template <typename ObjType2>
00225             RRef& operator=(const RRef<ObjType2>& rhs)
00226             {
00227                 reset(rhs);
00228                 return *this;
00229             }
00231             template <typename ObjType2, class Context>
00232             RRef& operator=(const DynObj<ObjType2,Context>& rhs)
00233             {
00234                 reset(rhs);
00235                 return *this;
00236             }
00238             RRef& operator=(ObjType& rrefable) 
00239             { 
00240                 reset(rrefable);
00241                 return *this;
00242             }
00243             
00249             #include "opConstWarningOff.hpp"
00250             inline operator const RRef<const ObjType>&() const throw()
00251             {
00252                 return * static_cast<const RRef<const ObjType>*>(
00253                      static_cast<const void*>(this)
00254                 );
00255             }
00256             #include "opConstWarningOn.hpp"
00261             template <typename ObjType2>
00262             inline bool operator<(const RRef<ObjType2>& rhs) const throw()
00263             {
00264                 ObjType* const lhsp = getPtr();
00265                 ObjType2* const rhsp = rhs.getPtr();
00266                 if (lhsp && rhsp) // both non-null:
00267                     return (*lhsp) < *(rhsp);
00268                 
00269                 // at least one null, compare pointers
00270                 if (lhsp == NullPtr) return true;
00271                 // else rhs must be null, so result is false:
00272                 assert(rhsp == NullPtr);
00273                 return false;
00274             }
00280             template <typename ObjType2>
00281             bool operator==(const RRef<ObjType2>& rhs) const throw()
00282             {
00283                 ObjType* const lhsp = getPtr();
00284                 ObjType2* const rhsp = rhs.getPtr();
00285                 if (lhsp && rhsp) return (lhsp == rhsp) || (*lhsp == *rhsp);
00286                 return lhsp == rhsp;
00287             }
00289             template <typename ObjType2>
00290             bool operator!=(const RRef<ObjType2>& rhs) const throw()
00291             {
00292                 return ! (*this == rhs);
00293             }
00295             
00296         private:
00298             template <typename> friend class RRef;
00299             
00305             ObjType* operator->() const
00306             {
00307                 assert( _rrefUsage.isValid() );
00308                 return getPtr();
00309             }
00310             
00311         private:
00313             ObjType* _obj;
00315             NoPtrImpl::RRefUsageForUser _rrefUsage;
00316     };
00317 
00318     
00319 } // namespace
00320 
00401 #endif // NO_PTR_RREF_H

Generated on Mon Aug 4 18:51:23 2003 for NoPtr C++ Library by doxygen 1.3.2