1 #ifndef SimTK_PRIVATE_IMPLEMENTATION_DEFS_H_ 2 #define SimTK_PRIVATE_IMPLEMENTATION_DEFS_H_ 52 template <
class HANDLE,
class IMPL>
56 template <
class HANDLE,
class IMPL>
61 template <
class HANDLE,
class IMPL>
66 template <
class HANDLE,
class IMPL>
68 assert(handleCount>=1);
return --handleCount;
71 template <
class HANDLE,
class IMPL>
73 assert(handleCount==0); ownerHandle=0;
76 template <
class HANDLE,
class IMPL>
80 template <
class HANDLE,
class IMPL>
83 ownerHandle=0, handleCount=0;
87 template <
class HANDLE,
class IMPL>
94 template <
class HANDLE,
class IMPL>
101 template <
class HANDLE,
class IMPL>
107 template <
class HANDLE,
class IMPL>
109 return ownerHandle != 0;
112 template <
class HANDLE,
class IMPL>
117 template <
class HANDLE,
class IMPL>
127 template <
class HANDLE,
class IMPL,
bool PTR>
131 if (impl) impl->setOwnerHandle(updDowncastToHandle());
135 template <
class HANDLE,
class IMPL,
bool PTR>
142 template <
class HANDLE,
class IMPL,
bool PTR>
144 if (PTR) referenceAssign(src.downcastToHandle());
145 else copyAssign(src.downcastToHandle());
149 template <
class HANDLE,
class IMPL,
bool PTR>
152 if (PTR) referenceAssign(src.downcastToHandle());
153 else copyAssign(src.downcastToHandle());
157 template <
class HANDLE,
class IMPL,
bool PTR>
159 return impl && impl->hasOwnerHandle() &&
160 static_cast<const PIMPLHandle*
>(&impl->getOwnerHandle()) ==
this;
163 template <
class HANDLE,
class IMPL,
bool PTR>
165 return static_cast<const PIMPLHandle*
>(&other) ==
this;
169 template <
class HANDLE,
class IMPL,
bool PTR>
171 return impl && (impl==other.impl);
176 template <
class HANDLE,
class IMPL,
bool PTR>
179 assert(!isSameHandle(newOwner));
180 assert(!this->isEmptyHandle() && newOwner.isEmptyHandle());
181 newOwner.impl = impl;
182 impl->replaceOwnerHandle(newOwner);
184 impl->incrementHandleCount();
191 template <
class HANDLE,
class IMPL,
bool PTR>
194 assert(!isOwnerHandle());
195 if (!hasSameImplementation(src)) {
199 impl->incrementHandleCount();
208 template <
class HANDLE,
class IMPL,
bool PTR>
211 if (isSameHandle(src))
return *
this;
214 impl = src.impl->clone();
215 impl->setOwnerHandle(updDowncastToHandle());
216 assert(impl->getHandleCount() == 1);
224 template <
class HANDLE,
class IMPL,
bool PTR>
227 assert(isEmptyHandle());
229 impl->incrementHandleCount();
236 template <
class HANDLE,
class IMPL,
bool PTR>
239 if (isEmptyHandle())
return;
240 const int nHandlesLeft =
241 isOwnerHandle() ? impl->removeOwnerHandle()
242 : impl->decrementHandleCount();
243 if (nHandlesLeft == 0)
248 template <
class HANDLE,
class IMPL,
bool PTR>
251 assert(!isEmptyHandle());
252 return impl->getHandleCount();
259 template <
class HANDLE,
class IMPL,
bool PTR>
260 std::ostream& operator<<(std::ostream& o, const PIMPLHandle<HANDLE,IMPL,PTR>& h) {
261 o <<
"PIMPLHandle<" <<
typeid(HANDLE).name() <<
"," <<
typeid(IMPL).name() <<
"> @" << &h;
262 if (h.isEmptyHandle())
263 return o <<
" is EMPTY." << std::endl;
265 if (h.isOwnerHandle()) o <<
" is OWNER of";
266 else o <<
" is REFERENCE to";
268 return o <<
" Implementation @" << &h.getImpl() <<
" (handle count=" << h.getImpl().getHandleCount() <<
")" << std::endl;
274 #endif // SimTK_PRIVATE_IMPLEMENTATION_DEFS_H_ void setOwnerHandle(HANDLE &p)
Provide an owner handle for an implementation which currently does not have one.
Definition: PrivateImplementation_Defs.h:88
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
PIMPLHandle()
The default constructor makes this an empty handle.
Definition: PrivateImplementation.h:187
int removeOwnerHandle()
Remove the owner reference from an implementation that currently has an owner.
Definition: PrivateImplementation_Defs.h:95
This class provides some infrastructure useful in making SimTK Private Implementation (PIMPL) classes...
Definition: PrivateImplementation.h:106
This class provides some infrastructure useful in creating PIMPL Implementation classes (the ones ref...
Definition: PrivateImplementation.h:265
int decrementHandleCount() const
Register the fact that one of the previously-referencing handles no longer references this implementa...
Definition: PrivateImplementation_Defs.h:67
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
PIMPLImplementation & operator=(const PIMPLImplementation &src)
Copy assignment for the base class just makes sure that the owner handle is not copied, and that the handle count is zero for the copy.
Definition: PrivateImplementation_Defs.h:81
bool hasOwnerHandle() const
Check whether this implementation currently has a reference to its owner handle.
Definition: PrivateImplementation_Defs.h:108
~PIMPLImplementation()
Note that the base class destructor is non-virtual, although it is expected that derived classes will...
Definition: PrivateImplementation_Defs.h:72
const HANDLE & getOwnerHandle() const
Return a reference to the owner handle of this implementation.
Definition: PrivateImplementation_Defs.h:118
void replaceOwnerHandle(HANDLE &p)
Replace the current owner handle with another one.
Definition: PrivateImplementation_Defs.h:102
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
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 header provides declarations of the user-visible portion of the PIMPLHandle template classes tha...
int getHandleCount() const
Get the number of handles known to be referencing this implementation.
Definition: PrivateImplementation_Defs.h:57