Simbody  3.4 (development)
ReferencePtr.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_REFERENCE_PTR_H_
00002 #define SimTK_SimTKCOMMON_REFERENCE_PTR_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                       Simbody(tm): SimTKcommon                             *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK biosimulation toolkit originating from           *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2012 Stanford University and the Authors.           *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00027 namespace SimTK {
00028 
00052 template <class T> class ReferencePtr {
00053 public:
00054     typedef T  element_type;
00055     typedef T* pointer;
00056     typedef T& reference;
00057 
00059     ReferencePtr() : p(0) { }
00061     explicit ReferencePtr(T* tp) : p(tp) { }
00064     explicit ReferencePtr(T& t) : p(&t) { }
00067     ReferencePtr(const ReferencePtr&) : p(0) { }
00070     ReferencePtr& operator=(const ReferencePtr& r) 
00071     {   if (&r != this) clear(); return *this; }
00074     ReferencePtr& operator=(T& t)          
00075     {  reset(&t); return *this; }
00078     ReferencePtr& operator=(T* tp)               
00079     {   reset(tp); return *this; }
00080     
00082     ~ReferencePtr() {clear();} // just being tidy
00083 
00086     T* operator->() const { return &getRef(); }
00087 
00090     T& operator*() const { return getRef(); }
00091 
00093     operator T*() const { return p; }
00094 
00097     operator bool() const { return !empty(); }
00098 
00100     T* get()  const  { return p; }
00101 
00104     T& getRef() const { 
00105         SimTK_ERRCHK(p!=0, "ReferencePtr::getRef()", 
00106                     "An attempt was made to dereference a null pointer."); 
00107         return *p; 
00108     }
00109 
00111     bool     empty() const    { return p==0; }
00113     void     clear()          { p=0; }
00116     T*       release()        { T* x=p; p=0; return x; }
00119     void     reset(T* tp)     { p=tp;}
00120 
00122     void swap(ReferencePtr& other) {
00123         T* otherp = other.release();
00124         other.reset(p);
00125         reset(otherp);
00126     }
00127      
00128 private:
00129     // Warning: ReferencePtr must be exactly the same size as type T*. That way
00130     // one can reinterpret_cast a T* to a ReferencePtr<T> when needed.
00131     T*  p;  
00132 };  
00133     
00134 } // namespace SimTK
00135 
00136 namespace std {
00140 template <class T> inline void
00141 swap(SimTK::ReferencePtr<T>& p1, SimTK::ReferencePtr<T>& p2) {
00142     p1.swap(p2);
00143 }
00144 
00145 } // namespace std
00146 
00147 #endif // SimTK_SimTKCOMMON_REFERENCE_PTR_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines