Simbody 3.7
ClonePtr.h
Go to the documentation of this file.
1#ifndef SimTK_SimTKCOMMON_CLONE_PTR_H_
2#define SimTK_SimTKCOMMON_CLONE_PTR_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) 2005-15 Stanford University and the Authors. *
13 * Authors: Michael Sherman *
14 * Contributors: *
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
28
29#include <memory>
30#include <iosfwd>
31#include <cassert>
32#include <utility>
33
34namespace SimTK {
35
55template <class T> class ClonePtr {
56public:
57 typedef T element_type;
58 typedef T* pointer;
59 typedef T& reference;
60
67 ClonePtr() noexcept : p(nullptr) {}
68
72 ClonePtr(std::nullptr_t) noexcept : ClonePtr() {}
73
76 explicit ClonePtr(T* x) noexcept : p(x) {}
77
82 explicit ClonePtr(const T* x) : ClonePtr(cloneOrNull(x)) {}
83
88 explicit ClonePtr(const T& x) : ClonePtr(&x) {}
89
93 ClonePtr(const ClonePtr& src) : p(cloneOrNull(src.p)) {}
94
99 template <class U>
100 ClonePtr(const ClonePtr<U>& src) : p(cloneOrNull(src.p)) {}
101
105 ClonePtr(ClonePtr&& src) noexcept : p(src.release()) {}
106
111 template <class U>
112 ClonePtr(ClonePtr<U>&& src) noexcept : p(src.release()) {}
124 if (&src != this) {
125 assert((p != src.p) || !p); // can't be same ptr unless null
126 reset(cloneOrNull(src.p));
127 }
128 return *this;
129 }
130
137 template <class U>
139 // The source can't be the same container as this one since they are
140 // different types. The managed pointers should never be the same either
141 // since ClonePtrs represent unique ownership. (OK if both nullptr.)
142 assert((p != static_cast<const T*>(src.p)) || !p);
143
144 reset(cloneOrNull(src.p));
145 return *this;
146 }
147
152 ClonePtr& operator=(ClonePtr&& src) noexcept {
153 if (&src != this) {
154 assert((p != src.p) || !p); // can't be same ptr unless null
155 reset(src.p); src.p = nullptr;
156 }
157 return *this;
158 }
159
164 template <class U>
165 ClonePtr& operator=(ClonePtr<U>&& src) noexcept {
166 // The source can't be the same container as this one since they are
167 // different types. The managed pointers should never be the same either
168 // since ClonePtrs represent unique ownership. (OK if both nullptr.)
169 assert((p != static_cast<const T*>(src.p)) || !p);
170 reset(src.p); src.p = nullptr;
171 return *this;
172 }
173
177 ClonePtr& operator=(const T& x)
178 { reset(cloneOrNull(&x)); return *this; }
179
183 ClonePtr& operator=(T* x) noexcept
184 { reset(x); return *this; }
191 ~ClonePtr() noexcept {reset();}
202 const T* get() const noexcept {return p;}
203
208 T* upd() noexcept {return p;}
209
213 const T& getRef() const {
214 SimTK_ERRCHK(!empty(), "ClonePtr::getRef()",
215 "An attempt was made to dereference a null pointer.");
216 return *get();
217 }
218
221 T& updRef() {
222 SimTK_ERRCHK(!empty(), "ClonePtr::updRef()",
223 "An attempt was made to dereference a null pointer.");
224 return *upd();
225 }
226
229 const T* operator->() const { return &getRef(); }
230
233 T* operator->() { return &updRef(); }
234
237 const T& operator*() const {return getRef();}
238
241 T& operator*() {return updRef();}
251 void reset() noexcept {
252 delete p;
253 p = nullptr;
254 }
255
260 void reset(T* x) noexcept {
261 if (x != p) {
262 delete p;
263 p = x;
264 }
265 }
266
271 void swap(ClonePtr& other) noexcept {
272 std::swap(p, other.p);
273 }
274
278 bool empty() const noexcept {return !p;} // count should be null also
279
282 explicit operator bool() const noexcept {return !empty();}
283
287 T* release() noexcept {
288 T* save = p;
289 p = nullptr;
290 return save;
291 }
292
295 DEPRECATED_14("use get() instead")
296 const T* getPtr() const noexcept {return get();}
299 DEPRECATED_14("use upd() instead")
300 T* updPtr() noexcept {return upd();}
302 DEPRECATED_14("use reset() instead")
303 void clear() noexcept {reset();}
304
307private:
308template <class U> friend class ClonePtr;
309
310 // If src is non-null, clone it; otherwise return nullptr.
311 static T* cloneOrNull(const T* src) {
312 return src ? src->clone() : nullptr;
313 }
314
315 T* p; // this may be null
316};
317
318
319
320//==============================================================================
321// SimTK namespace-scope functions
322//==============================================================================
323// These namespace-scope functions will be resolved by the compiler using
324// "Koenig lookup" which examines the arguments' namespaces first.
325// See Herb Sutter's discussion here: http://www.gotw.ca/publications/mill08.htm.
326
331template <class T> inline void
332swap(ClonePtr<T>& p1, ClonePtr<T>& p2) noexcept {
333 p1.swap(p2);
334}
335
339template <class charT, class traits, class T>
340inline std::basic_ostream<charT,traits>&
341operator<<(std::basic_ostream<charT,traits>& os,
342 const ClonePtr<T>& p)
343{ os << p.get(); return os; }
344
350template <class T, class U>
351inline bool operator==(const ClonePtr<T>& lhs,
352 const ClonePtr<U>& rhs)
353{ return lhs.get() == rhs.get(); }
354
357template <class T>
358inline bool operator==(const ClonePtr<T>& lhs, std::nullptr_t)
359{ return lhs.empty(); }
360
363template <class T>
364inline bool operator==(std::nullptr_t, const ClonePtr<T>& rhs)
365{ return rhs.empty(); }
366
373template <class T, class U>
374inline bool operator<(const ClonePtr<T>& lhs,
375 const ClonePtr<U>& rhs)
376{ return lhs.get() < rhs.get(); }
377
382template <class T>
383inline bool operator<(const ClonePtr<T>& lhs, std::nullptr_t)
384{ return false; }
385
390template <class T>
391inline bool operator<(std::nullptr_t, const ClonePtr<T>& rhs)
392{ return !rhs.empty(); }
393
394
395// These functions are derived from operator== and operator<.
396
399template <class T, class U>
400inline bool operator!=(const ClonePtr<T>& lhs,
401 const ClonePtr<U>& rhs)
402{ return !(lhs==rhs); }
405template <class T>
406inline bool operator!=(const ClonePtr<T>& lhs, std::nullptr_t)
407{ return !(lhs==nullptr); }
410template <class T>
411inline bool operator!=(std::nullptr_t, const ClonePtr<T>& rhs)
412{ return !(nullptr==rhs); }
413
416template <class T, class U>
417inline bool operator>(const ClonePtr<T>& lhs,
418 const ClonePtr<U>& rhs)
419{ return rhs < lhs; }
422template <class T>
423inline bool operator>(const ClonePtr<T>& lhs, std::nullptr_t)
424{ return nullptr < lhs; }
425
428template <class T>
429inline bool operator>(std::nullptr_t, const ClonePtr<T>& rhs)
430{ return rhs < nullptr; }
431
432
435template <class T, class U>
436inline bool operator>=(const ClonePtr<T>& lhs,
437 const ClonePtr<U>& rhs)
438{ return !(lhs < rhs); }
441template <class T>
442inline bool operator>=(const ClonePtr<T>& lhs, std::nullptr_t)
443{ return !(lhs < nullptr); }
444
447template <class T>
448inline bool operator>=(std::nullptr_t, const ClonePtr<T>& rhs)
449{ return !(nullptr < rhs); }
450
451
455template <class T, class U>
456inline bool operator<=(const ClonePtr<T>& lhs,
457 const ClonePtr<U>& rhs)
458{ return !(rhs < lhs); }
462template <class T>
463inline bool operator<=(const ClonePtr<T>& lhs, std::nullptr_t)
464{ return !(nullptr < lhs); }
468template <class T>
469inline bool operator<=(std::nullptr_t, const ClonePtr<T>& rhs)
470{ return !(rhs < nullptr); }
471
472} // namespace SimTK
473
474#endif // SimTK_SimTKCOMMON_CLONE_PTR_H_
#define SimTK_ERRCHK(cond, whereChecked, msg)
Definition: ExceptionMacros.h:324
Mandatory first inclusion for any Simbody source or header file.
#define DEPRECATED_14(MSG)
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:289
Smart pointer with deep copy semantics.
Definition: ClonePtr.h:55
bool operator<=(const ClonePtr< T > &lhs, const ClonePtr< U > &rhs)
Pointer less-or-equal test defined as !(rhs < lhs) (note reversed arguments).
Definition: ClonePtr.h:456
ClonePtr & operator=(T *x) noexcept
This form of assignment replaces the currently-held object by the given source object and takes over ...
Definition: ClonePtr.h:183
T & operator*()
Return a writable reference to the contained object.
Definition: ClonePtr.h:241
bool operator>(const ClonePtr< T > &lhs, const ClonePtr< U > &rhs)
Pointer greater-than test defined as rhs < lhs.
Definition: ClonePtr.h:417
T element_type
Type of the contained object.
Definition: ClonePtr.h:57
ClonePtr & operator=(ClonePtr< U > &&src) noexcept
Move assignment from a compatible ClonePtr replaces the currently-held object by the source object,...
Definition: ClonePtr.h:165
T & reference
Type of a reference to the contained object.
Definition: ClonePtr.h:59
ClonePtr(const ClonePtr< U > &src)
Deep copy construction from a compatible ClonePtr.
Definition: ClonePtr.h:100
ClonePtr(T *x) noexcept
Given a pointer to a writable heap-allocated object, take over ownership of that object.
Definition: ClonePtr.h:76
ClonePtr & operator=(const ClonePtr &src)
Copy assignment replaces the currently-held object by a copy of the object held in the source contain...
Definition: ClonePtr.h:123
const T & operator*() const
This "dereference" operator returns a const reference to the contained object.
Definition: ClonePtr.h:237
ClonePtr() noexcept
Default constructor stores a nullptr.
Definition: ClonePtr.h:67
bool operator<=(const ClonePtr< T > &lhs, std::nullptr_t)
nullptr less-or-equal test defined as !(nullptr < lhs) (note reversed arguments).
Definition: ClonePtr.h:463
bool operator<(std::nullptr_t, const ClonePtr< T > &rhs)
Less-than comparison of a nullptr against this container.
Definition: ClonePtr.h:391
T * release() noexcept
Remove the contained object from management by this container and transfer ownership to the caller.
Definition: ClonePtr.h:287
bool operator==(const ClonePtr< T > &lhs, const ClonePtr< U > &rhs)
Compare for equality the managed pointers contained in two compatible ClonePtr containers.
Definition: ClonePtr.h:351
bool operator>=(const ClonePtr< T > &lhs, const ClonePtr< U > &rhs)
Pointer greater-or-equal test defined as !(lhs < rhs).
Definition: ClonePtr.h:436
ClonePtr(const ClonePtr &src)
Copy constructor is deep; the new ClonePtr object contains a new copy of the object in the source,...
Definition: ClonePtr.h:93
const T * getPtr() const noexcept
(Deprecated) Same as get().
Definition: ClonePtr.h:296
void clear() noexcept
(Deprecated) Use reset() instead.
Definition: ClonePtr.h:303
bool operator!=(const ClonePtr< T > &lhs, std::nullptr_t)
nullptr inequality test defined as !(lhs==nullptr).
Definition: ClonePtr.h:406
ClonePtr(ClonePtr &&src) noexcept
Move constructor is very fast and leaves the source empty.
Definition: ClonePtr.h:105
bool operator==(std::nullptr_t, const ClonePtr< T > &rhs)
Comparison against nullptr; same as rhs.empty().
Definition: ClonePtr.h:364
~ClonePtr() noexcept
Destructor deletes the contained object.
Definition: ClonePtr.h:191
ClonePtr & operator=(const T &x)
This form of assignment replaces the currently-held object by a heap-allocated copy of the source obj...
Definition: ClonePtr.h:177
void swap(ClonePtr &other) noexcept
Swap the contents of this ClonePtr with another one, with ownership changing hands but no copying per...
Definition: ClonePtr.h:271
ClonePtr(const T *x)
Given a pointer to a read-only object, create a new heap-allocated copy of that object via its clone(...
Definition: ClonePtr.h:82
const T * get() const noexcept
Return a const pointer to the contained object if any, or nullptr.
Definition: ClonePtr.h:202
bool operator>=(const ClonePtr< T > &lhs, std::nullptr_t)
nullptr greater-or-equal test defined as !(lhs < nullptr).
Definition: ClonePtr.h:442
bool operator>(std::nullptr_t, const ClonePtr< T > &rhs)
nullptr greater-than test defined as rhs < nullptr.
Definition: ClonePtr.h:429
const T & getRef() const
Return a const reference to the contained object.
Definition: ClonePtr.h:213
T * updPtr() noexcept
(Deprecated) Same as upd().
Definition: ClonePtr.h:300
bool empty() const noexcept
Return true if this container is empty, which is the state the container is in immediately after defa...
Definition: ClonePtr.h:278
ClonePtr(ClonePtr< U > &&src) noexcept
Move construction from a compatible ClonePtr.
Definition: ClonePtr.h:112
bool operator<(const ClonePtr< T > &lhs, const ClonePtr< U > &rhs)
Less-than operator for two compatible ClonePtr containers, comparing the pointers,...
Definition: ClonePtr.h:374
T & updRef()
Return a writable reference to the contained object.
Definition: ClonePtr.h:221
void reset() noexcept
Make this container empty if it isn't already, destructing the contained object if there is one.
Definition: ClonePtr.h:251
T * operator->()
Dereference a writable pointer to the contained object.
Definition: ClonePtr.h:233
T * upd() noexcept
Return a writable pointer to the contained object if any, or nullptr.
Definition: ClonePtr.h:208
bool operator==(const ClonePtr< T > &lhs, std::nullptr_t)
Comparison against nullptr; same as lhs.empty().
Definition: ClonePtr.h:358
bool operator!=(const ClonePtr< T > &lhs, const ClonePtr< U > &rhs)
Pointer inequality test defined as !(lhs==rhs).
Definition: ClonePtr.h:400
void reset(T *x) noexcept
Replace the contents of this container with the supplied heap-allocated object, taking over ownership...
Definition: ClonePtr.h:260
bool operator!=(std::nullptr_t, const ClonePtr< T > &rhs)
nullptr inequality test defined as !(nullptr==rhs).
Definition: ClonePtr.h:411
ClonePtr(std::nullptr_t) noexcept
Constructor from nullptr is the same as the default constructor.
Definition: ClonePtr.h:72
ClonePtr & operator=(ClonePtr &&src) noexcept
Move assignment replaces the currently-held object by the source object, leaving the source empty.
Definition: ClonePtr.h:152
bool operator>=(std::nullptr_t, const ClonePtr< T > &rhs)
nullptr greater-or-equal test defined as !(nullptr < rhs).
Definition: ClonePtr.h:448
bool operator>(const ClonePtr< T > &lhs, std::nullptr_t)
nullptr greater-than test defined as nullptr < lhs.
Definition: ClonePtr.h:423
bool operator<=(std::nullptr_t, const ClonePtr< T > &rhs)
nullptr less-or-equal test defined as !(rhs < nullptr) (note reversed arguments).
Definition: ClonePtr.h:469
bool operator<(const ClonePtr< T > &lhs, std::nullptr_t)
Less-than comparison against a nullptr.
Definition: ClonePtr.h:383
ClonePtr(const T &x)
Given a read-only reference to an object, create a new heap-allocated copy of that object via its clo...
Definition: ClonePtr.h:88
const T * operator->() const
Dereference a const pointer to the contained object.
Definition: ClonePtr.h:229
T * pointer
Type of a pointer to the contained object.
Definition: ClonePtr.h:58
ClonePtr & operator=(const ClonePtr< U > &src)
Copy assignment from a compatible ClonePtr.
Definition: ClonePtr.h:138
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