Simbody
|
00001 #ifndef SimTK_PRIVATE_IMPLEMENTATION_H_ 00002 #define SimTK_PRIVATE_IMPLEMENTATION_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core 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. * 00011 * * 00012 * Portions copyright (c) 2007 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: Chris Bruns and Peter Eastman * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00035 00054 #include "SimTKcommon/internal/common.h" 00055 #include "SimTKcommon/internal/ExceptionMacros.h" 00056 00057 #include <cassert> 00058 #include <iosfwd> 00059 00060 namespace SimTK { 00061 00062 00114 template <class HANDLE, class IMPL, bool PTR=false> 00115 class PIMPLHandle { 00116 private: 00121 IMPL *impl; 00122 00123 public: 00124 typedef PIMPLHandle<HANDLE, IMPL, PTR> HandleBase; 00125 typedef HandleBase ParentHandle; 00126 00129 bool isEmptyHandle() const {return impl==0;} 00130 00136 bool isOwnerHandle() const; 00137 00140 bool isSameHandle(const HANDLE& other) const; 00141 00146 void disown(HANDLE& newOwner); 00147 00148 00162 PIMPLHandle& referenceAssign(const HANDLE& source); 00163 00172 PIMPLHandle& copyAssign(const HANDLE& source); 00173 00178 void clearHandle(); 00179 00182 const IMPL& getImpl() const {assert(!isEmptyHandle()); return *impl;} 00183 00187 IMPL& updImpl() {assert(!isEmptyHandle()); return *impl;} 00188 00192 int getImplHandleCount() const; 00193 00194 protected: 00198 explicit PIMPLHandle(IMPL* p=0); 00199 00206 ~PIMPLHandle(); 00207 00214 PIMPLHandle(const PIMPLHandle& source); 00215 00226 PIMPLHandle& operator=(const PIMPLHandle& source); 00227 00233 void setImpl(IMPL* p); 00234 00237 bool hasSameImplementation(const HANDLE& other) const; 00238 00239 private: 00240 const HANDLE& downcastToHandle() const {return static_cast<const HANDLE&>(*this);} 00241 HANDLE& updDowncastToHandle() {return static_cast<HANDLE&>(*this);} 00242 }; 00243 00270 template <class HANDLE, class IMPL> 00271 class PIMPLImplementation { 00272 HANDLE* ownerHandle; 00273 mutable int handleCount; // ref count determining when this is destructed 00274 public: 00280 explicit PIMPLImplementation(HANDLE* h=0); 00281 00283 int getHandleCount() const; 00284 00287 void incrementHandleCount() const; 00288 00292 int decrementHandleCount() const; 00293 00299 ~PIMPLImplementation(); 00300 00307 PIMPLImplementation(const PIMPLImplementation&); 00308 00313 PIMPLImplementation& operator=(const PIMPLImplementation& src); 00314 00318 void setOwnerHandle(HANDLE& p); 00319 00323 int removeOwnerHandle(); 00324 00328 void replaceOwnerHandle(HANDLE& p); 00329 00332 bool hasOwnerHandle() const; 00333 00336 bool isOwnerHandle(const HANDLE& p) const; 00337 00341 const HANDLE& getOwnerHandle() const; 00342 }; 00343 00344 template <class H, class IMPL, bool PTR> 00345 std::ostream& operator<<(std::ostream& o, const PIMPLHandle<H,IMPL,PTR>& h); 00346 00347 // This macro declares methods to be included in classes derived from a PIMPLHandle subclass. 00348 00349 #define SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(DERIVED, DERIVED_IMPL, PARENT) \ 00350 const DERIVED_IMPL& getImpl() const;\ 00351 DERIVED_IMPL& updImpl();\ 00352 const PARENT& upcast() const;\ 00353 PARENT& updUpcast();\ 00354 static bool isInstanceOf(const PARENT& p);\ 00355 static const DERIVED& downcast(const PARENT& p);\ 00356 static DERIVED& updDowncast(PARENT& p); 00357 00358 // This macro provides the definitions for the above declarations. 00359 00360 #define SimTK_INSERT_DERIVED_HANDLE_DEFINITIONS(DERIVED, DERIVED_IMPL, PARENT) \ 00361 const DERIVED_IMPL& DERIVED::getImpl() const {\ 00362 return dynamic_cast<const DERIVED_IMPL&>(PARENT::getImpl());\ 00363 }\ 00364 DERIVED_IMPL& DERIVED::updImpl() {\ 00365 return dynamic_cast<DERIVED_IMPL&>(PARENT::updImpl());\ 00366 }\ 00367 const PARENT& DERIVED::upcast() const {\ 00368 return static_cast<const PARENT&>(*this);\ 00369 }\ 00370 PARENT& DERIVED::updUpcast() {\ 00371 return static_cast<PARENT&>(*this);\ 00372 }\ 00373 bool DERIVED::isInstanceOf(const PARENT& p) {\ 00374 return dynamic_cast<const DERIVED_IMPL*>(&p.getImpl()) != 0;\ 00375 }\ 00376 const DERIVED& DERIVED::downcast(const PARENT& p) {\ 00377 assert(isInstanceOf(p));\ 00378 return static_cast<const DERIVED&>(p);\ 00379 }\ 00380 DERIVED& DERIVED::updDowncast(PARENT& p) {\ 00381 assert(isInstanceOf(p));\ 00382 return static_cast<DERIVED&>(p);\ 00383 }\ 00384 00385 } // namespace SimTK 00386 00387 #endif // SimTK_PRIVATE_IMPLEMENTATION_H_