Simbody
3.4 (development)
|
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_