Simbody 3.7
PrivateImplementation.h
Go to the documentation of this file.
1#ifndef SimTK_PRIVATE_IMPLEMENTATION_H_
2#define SimTK_PRIVATE_IMPLEMENTATION_H_
3
4/* -------------------------------------------------------------------------- *
5 * Simbody(tm): SimTKcommon *
6 * -------------------------------------------------------------------------- *
7 * This is part of the SimTK biosimulation toolkit originating from *
8 * Simbios, the NIH National Center for Physics-Based Simulation of *
9 * Biological Structures at Stanford, funded under the NIH Roadmap for *
10 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11 * *
12 * Portions copyright (c) 2007-12 Stanford University and the Authors. *
13 * Authors: Michael Sherman *
14 * Contributors: Christopher Bruns, Peter Eastman *
15 * *
16 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17 * not use this file except in compliance with the License. You may obtain a *
18 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19 * *
20 * Unless required by applicable law or agreed to in writing, software *
21 * distributed under the License is distributed on an "AS IS" BASIS, *
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23 * See the License for the specific language governing permissions and *
24 * limitations under the License. *
25 * -------------------------------------------------------------------------- */
26
47
48#include <cassert>
49#include <iosfwd>
50
51namespace SimTK {
52
53
105template <class HANDLE, class IMPL, bool PTR=false>
107private:
112 IMPL *impl;
113
114public:
117
120 bool isEmptyHandle() const {return impl==0;}
121
127 bool isOwnerHandle() const;
128
131 bool isSameHandle(const HANDLE& other) const;
132
137 void disown(HANDLE& newOwner);
138
139
153 PIMPLHandle& referenceAssign(const HANDLE& source);
154
163 PIMPLHandle& copyAssign(const HANDLE& source);
164
169 void clearHandle();
170
173 const IMPL& getImpl() const {assert(!isEmptyHandle()); return *impl;}
174
178 IMPL& updImpl() {assert(!isEmptyHandle()); return *impl;}
179
183 int getImplHandleCount() const;
184
185protected:
187 PIMPLHandle() : impl(0) {}
188
192 explicit PIMPLHandle(IMPL* p);
193
200 ~PIMPLHandle();
201
208 PIMPLHandle(const PIMPLHandle& source);
209
220 PIMPLHandle& operator=(const PIMPLHandle& source);
221
227 void setImpl(IMPL* p);
228
231 bool hasSameImplementation(const HANDLE& other) const;
232
233private:
234 const HANDLE& downcastToHandle() const {return static_cast<const HANDLE&>(*this);}
235 HANDLE& updDowncastToHandle() {return static_cast<HANDLE&>(*this);}
236};
237
264template <class HANDLE, class IMPL>
266 HANDLE* ownerHandle;
267 mutable int handleCount; // ref count determining when this is destructed
268public:
274 explicit PIMPLImplementation(HANDLE* h=0);
275
277 int getHandleCount() const;
278
281 void incrementHandleCount() const;
282
286 int decrementHandleCount() const;
287
294
302
308
312 void setOwnerHandle(HANDLE& p);
313
317 int removeOwnerHandle();
318
322 void replaceOwnerHandle(HANDLE& p);
323
326 bool hasOwnerHandle() const;
327
330 bool isOwnerHandle(const HANDLE& p) const;
331
335 const HANDLE& getOwnerHandle() const;
336};
337
338template <class H, class IMPL, bool PTR>
339std::ostream& operator<<(std::ostream& o, const PIMPLHandle<H,IMPL,PTR>& h);
340
341// This macro declares methods to be included in classes derived from a PIMPLHandle subclass.
342
343#define SimTK_INSERT_DERIVED_HANDLE_DECLARATIONS(DERIVED, DERIVED_IMPL, PARENT) \
344const DERIVED_IMPL& getImpl() const;\
345DERIVED_IMPL& updImpl();\
346const PARENT& upcast() const;\
347PARENT& updUpcast();\
348static bool isInstanceOf(const PARENT& p);\
349static const DERIVED& downcast(const PARENT& p);\
350static DERIVED& updDowncast(PARENT& p);
351
352// This macro provides the definitions for the above declarations.
353
354#define SimTK_INSERT_DERIVED_HANDLE_DEFINITIONS(DERIVED, DERIVED_IMPL, PARENT) \
355const DERIVED_IMPL& DERIVED::getImpl() const {\
356 return SimTK_DYNAMIC_CAST_DEBUG<const DERIVED_IMPL&>(PARENT::getImpl());\
357}\
358DERIVED_IMPL& DERIVED::updImpl() {\
359 return SimTK_DYNAMIC_CAST_DEBUG<DERIVED_IMPL&>(PARENT::updImpl());\
360}\
361const PARENT& DERIVED::upcast() const {\
362 return static_cast<const PARENT&>(*this);\
363}\
364PARENT& DERIVED::updUpcast() {\
365 return static_cast<PARENT&>(*this);\
366}\
367bool DERIVED::isInstanceOf(const PARENT& p) {\
368 return dynamic_cast<const DERIVED_IMPL*>(&p.getImpl()) != 0;\
369}\
370const DERIVED& DERIVED::downcast(const PARENT& p) {\
371 assert(isInstanceOf(p));\
372 return static_cast<const DERIVED&>(p);\
373}\
374DERIVED& DERIVED::updDowncast(PARENT& p) {\
375 assert(isInstanceOf(p));\
376 return static_cast<DERIVED&>(p);\
377}\
378
379} // namespace SimTK
380
381#endif // SimTK_PRIVATE_IMPLEMENTATION_H_
This file contains macros which are convenient to use for sprinkling error checking around liberally ...
Mandatory first inclusion for any Simbody source or header file.
This class provides some infrastructure useful in making SimTK Private Implementation (PIMPL) classes...
Definition: PrivateImplementation.h:106
const IMPL & getImpl() const
Get a const reference to the implementation associated with this Handle.
Definition: PrivateImplementation.h:173
PIMPLHandle & copyAssign(const HANDLE &source)
This is real copy assignment, with ordinary C++ object ("value") semantics.
Definition: PrivateImplementation_Defs.h:210
PIMPLHandle & operator=(const PIMPLHandle &source)
Copy assignment makes the current handle either a deep (value) or shallow (reference) copy of the sup...
Definition: PrivateImplementation_Defs.h:151
void clearHandle()
Make this an empty handle, deleting the implementation object if this handle is the owner of it.
Definition: PrivateImplementation_Defs.h:238
void disown(HANDLE &newOwner)
Give up ownership of the implementation to an empty handle.
Definition: PrivateImplementation_Defs.h:178
void setImpl(IMPL *p)
Set the implementation for this empty handle.
Definition: PrivateImplementation_Defs.h:226
~PIMPLHandle()
Note that the destructor is non-virtual.
Definition: PrivateImplementation_Defs.h:136
PIMPLHandle< HANDLE, IMPL, PTR > HandleBase
Definition: PrivateImplementation.h:115
PIMPLHandle & referenceAssign(const HANDLE &source)
"Copy" assignment but with shallow (pointer) semantics.
Definition: PrivateImplementation_Defs.h:193
bool isSameHandle(const HANDLE &other) const
Determine whether the supplied handle is the same object as "this" PIMPLHandle.
Definition: PrivateImplementation_Defs.h:164
bool isOwnerHandle() const
Returns true if this handle is the owner of the implementation object to which it refers.
Definition: PrivateImplementation_Defs.h:158
bool isEmptyHandle() const
Returns true if this handle is empty, that is, does not refer to any implementation object.
Definition: PrivateImplementation.h:120
IMPL & updImpl()
Get a writable reference to the implementation associated with this Handle.
Definition: PrivateImplementation.h:178
HandleBase ParentHandle
Definition: PrivateImplementation.h:116
PIMPLHandle()
The default constructor makes this an empty handle.
Definition: PrivateImplementation.h:187
bool hasSameImplementation(const HANDLE &other) const
Determine whether the supplied handle is a reference to the same implementation object as is referenc...
Definition: PrivateImplementation_Defs.h:170
int getImplHandleCount() const
Return the number of handles the implementation believes are referencing it.
Definition: PrivateImplementation_Defs.h:250
This class provides some infrastructure useful in creating PIMPL Implementation classes (the ones ref...
Definition: PrivateImplementation.h:265
void replaceOwnerHandle(HANDLE &p)
Replace the current owner handle with another one.
Definition: PrivateImplementation_Defs.h:102
void setOwnerHandle(HANDLE &p)
Provide an owner handle for an implementation which currently does not have one.
Definition: PrivateImplementation_Defs.h:88
int removeOwnerHandle()
Remove the owner reference from an implementation that currently has an owner.
Definition: PrivateImplementation_Defs.h:95
const HANDLE & getOwnerHandle() const
Return a reference to the owner handle of this implementation.
Definition: PrivateImplementation_Defs.h:118
bool isOwnerHandle(const HANDLE &p) const
Check whether a given Handle of the appropriate type is the owner of this implementation.
Definition: PrivateImplementation_Defs.h:113
int decrementHandleCount() const
Register the fact that one of the previously-referencing handles no longer references this implementa...
Definition: PrivateImplementation_Defs.h:67
int getHandleCount() const
Get the number of handles known to be referencing this implementation.
Definition: PrivateImplementation_Defs.h:57
PIMPLImplementation & operator=(const PIMPLImplementation &src)
Copy assignment for the base class just makes sure that the owner handle is not copied,...
Definition: PrivateImplementation_Defs.h:81
~PIMPLImplementation()
Note that the base class destructor is non-virtual, although it is expected that derived classes will...
Definition: PrivateImplementation_Defs.h:72
PIMPLImplementation(HANDLE *h=0)
This serves as a default constructor and as a way to construct an implementation class which already ...
Definition: PrivateImplementation_Defs.h:53
bool hasOwnerHandle() const
Check whether this implementation currently has a reference to its owner handle.
Definition: PrivateImplementation_Defs.h:108
void incrementHandleCount() const
Register that a new handle is referencing this implementation so we won't delete the implementation p...
Definition: PrivateImplementation_Defs.h:62
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
std::ostream & operator<<(std::ostream &o, const ContactForce &f)
Definition: CompliantContactSubsystem.h:387