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>
89 assert(!hasOwnerHandle());
91 incrementHandleCount();
94 template <
class HANDLE,
class IMPL>
96 assert(hasOwnerHandle());
98 return decrementHandleCount();
101 template <
class HANDLE,
class IMPL>
103 assert(hasOwnerHandle());
107 template <
class HANDLE,
class IMPL>
109 return ownerHandle != 0;
112 template <
class HANDLE,
class IMPL>
114 return hasOwnerHandle() && ownerHandle==&p;
117 template <
class HANDLE,
class IMPL>
119 assert(hasOwnerHandle());
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>
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 clearHandle()
Make this an empty handle, deleting the implementation object if this handle is the owner of it...
Definition: PrivateImplementation_Defs.h:238
void setImpl(IMPL *p)
Set the implementation for this empty handle.
Definition: PrivateImplementation_Defs.h:226
void setOwnerHandle(HANDLE &p)
Provide an owner handle for an implementation which currently does not have one.
Definition: PrivateImplementation_Defs.h:88
int decrementHandleCount() const
Register the fact that one of the previously-referencing handles no longer references this implementa...
Definition: PrivateImplementation_Defs.h:67
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
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
void disown(HANDLE &newOwner)
Give up ownership of the implementation to an empty handle.
Definition: PrivateImplementation_Defs.h:178
This class provides some infrastructure useful in creating PIMPL Implementation classes (the ones ref...
Definition: PrivateImplementation.h:265
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 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 getImplHandleCount() const
Return the number of handles the implementation believes are referencing it.
Definition: PrivateImplementation_Defs.h:250
~PIMPLHandle()
Note that the destructor is non-virtual.
Definition: PrivateImplementation_Defs.h:136
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
~PIMPLImplementation()
Note that the base class destructor is non-virtual, although it is expected that derived classes will...
Definition: PrivateImplementation_Defs.h:72
bool hasOwnerHandle() const
Check whether this implementation currently has a reference to its owner handle.
Definition: PrivateImplementation_Defs.h:108
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
const HANDLE & getOwnerHandle() const
Return a reference to the owner handle of this implementation.
Definition: PrivateImplementation_Defs.h:118
bool isSameHandle(const HANDLE &other) const
Determine whether the supplied handle is the same object as "this" PIMPLHandle.
Definition: PrivateImplementation_Defs.h:164
void replaceOwnerHandle(HANDLE &p)
Replace the current owner handle with another one.
Definition: PrivateImplementation_Defs.h:102
PIMPLHandle & copyAssign(const HANDLE &source)
This is real copy assignment, with ordinary C++ object ("value") semantics.
Definition: PrivateImplementation_Defs.h:210
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 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
This header provides declarations of the user-visible portion of the PIMPLHandle template classes tha...
PIMPLHandle & referenceAssign(const HANDLE &source)
"Copy" assignment but with shallow (pointer) semantics.
Definition: PrivateImplementation_Defs.h:193
int getHandleCount() const
Get the number of handles known to be referencing this implementation.
Definition: PrivateImplementation_Defs.h:57