summaryrefslogtreecommitdiff
path: root/build/Bonmin/include/coin/CoinSmartPtr.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'build/Bonmin/include/coin/CoinSmartPtr.hpp')
-rw-r--r--build/Bonmin/include/coin/CoinSmartPtr.hpp528
1 files changed, 528 insertions, 0 deletions
diff --git a/build/Bonmin/include/coin/CoinSmartPtr.hpp b/build/Bonmin/include/coin/CoinSmartPtr.hpp
new file mode 100644
index 0000000..93366a2
--- /dev/null
+++ b/build/Bonmin/include/coin/CoinSmartPtr.hpp
@@ -0,0 +1,528 @@
+// Copyright (C) 2004, 2006 International Business Machines and others.
+// All Rights Reserved.
+// This code is published under the Eclipse Public License.
+//
+// $Id: CoinSmartPtr.hpp 1520 2012-01-29 00:43:31Z tkr $
+//
+// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13
+// Removed lots of debugging stuff and reformatted: Laszlo Ladanyi, IBM
+#ifndef CoinSmartPtr_hpp
+#define CoinSmartPtr_hpp
+
+#include <list>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+
+namespace Coin {
+
+ //#########################################################################
+
+ /** ReferencedObject class.
+ * This is part of the implementation of an intrusive smart pointer
+ * design. This class stores the reference count of all the smart
+ * pointers that currently reference it. See the documentation for
+ * the SmartPtr class for more details.
+ *
+ * A SmartPtr behaves much like a raw pointer, but manages the lifetime
+ * of an object, deleting the object automatically. This class implements
+ * a reference-counting, intrusive smart pointer design, where all
+ * objects pointed to must inherit off of ReferencedObject, which
+ * stores the reference count. Although this is intrusive (native types
+ * and externally authored classes require wrappers to be referenced
+ * by smart pointers), it is a safer design. A more detailed discussion of
+ * these issues follows after the usage information.
+ *
+ * Usage Example:
+ * Note: to use the SmartPtr, all objects to which you point MUST
+ * inherit off of ReferencedObject.
+ *
+ * \verbatim
+ *
+ * In MyClass.hpp...
+ *
+ * #include "CoinSmartPtr.hpp"
+
+ *
+ * class MyClass : public Coin::ReferencedObject // must derive from ReferencedObject
+ * {
+ * ...
+ * }
+ *
+ * In my_usage.cpp...
+ *
+ * #include "CoinSmartPtr.hpp"
+ * #include "MyClass.hpp"
+ *
+ * void func(AnyObject& obj)
+ * {
+ * Coin::SmartPtr<MyClass> ptr_to_myclass = new MyClass(...);
+ * // ptr_to_myclass now points to a new MyClass,
+ * // and the reference count is 1
+ *
+ * ...
+ *
+ * obj.SetMyClass(ptr_to_myclass);
+ * // Here, let's assume that AnyObject uses a
+ * // SmartPtr<MyClass> internally here.
+ * // Now, both ptr_to_myclass and the internal
+ * // SmartPtr in obj point to the same MyClass object
+ * // and its reference count is 2.
+ *
+ * ...
+ *
+ * // No need to delete ptr_to_myclass, this
+ * // will be done automatically when the
+ * // reference count drops to zero.
+ *
+ * }
+ *
+ * \endverbatim
+ *
+ * Other Notes:
+ * The SmartPtr implements both dereference operators -> & *.
+ * The SmartPtr does NOT implement a conversion operator to
+ * the raw pointer. Use the GetRawPtr() method when this
+ * is necessary. Make sure that the raw pointer is NOT
+ * deleted.
+ * The SmartPtr implements the comparison operators == & !=
+ * for a variety of types. Use these instead of
+ * \verbatim
+ * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this
+ * \endverbatim
+ * SmartPtr's, as currently implemented, do NOT handle circular references.
+ * For example: consider a higher level object using SmartPtrs to point
+ * to A and B, but A and B also point to each other (i.e. A has a
+ * SmartPtr to B and B has a SmartPtr to A). In this scenario, when the
+ * higher level object is finished with A and B, their reference counts
+ * will never drop to zero (since they reference each other) and they
+ * will not be deleted. This can be detected by memory leak tools like
+ * valgrind. If the circular reference is necessary, the problem can be
+ * overcome by a number of techniques:
+ *
+ * 1) A and B can have a method that "releases" each other, that is
+ * they set their internal SmartPtrs to NULL.
+ * \verbatim
+ * void AClass::ReleaseCircularReferences()
+ * {
+ * smart_ptr_to_B = NULL;
+ * }
+ * \endverbatim
+ * Then, the higher level class can call these methods before
+ * it is done using A & B.
+ *
+ * 2) Raw pointers can be used in A and B to reference each other.
+ * Here, an implicit assumption is made that the lifetime is
+ * controlled by the higher level object and that A and B will
+ * both exist in a controlled manner. Although this seems
+ * dangerous, in many situations, this type of referencing
+ * is very controlled and this is reasonably safe.
+ *
+ * 3) This SmartPtr class could be redesigned with the Weak/Strong
+ * design concept. Here, the SmartPtr is identified as being
+ * Strong (controls lifetime of the object) or Weak (merely
+ * referencing the object). The Strong SmartPtr increments
+ * (and decrements) the reference count in ReferencedObject
+ * but the Weak SmartPtr does not. In the example above,
+ * the higher level object would have Strong SmartPtrs to
+ * A and B, but A and B would have Weak SmartPtrs to each
+ * other. Then, when the higher level object was done with
+ * A and B, they would be deleted. The Weak SmartPtrs in A
+ * and B would not decrement the reference count and would,
+ * of course, not delete the object. This idea is very similar
+ * to item (2), where it is implied that the sequence of events
+ * is controlled such that A and B will not call anything using
+ * their pointers following the higher level delete (i.e. in
+ * their destructors!). This is somehow safer, however, because
+ * code can be written (however expensive) to perform run-time
+ * detection of this situation. For example, the ReferencedObject
+ * could store pointers to all Weak SmartPtrs that are referencing
+ * it and, in its destructor, tell these pointers that it is
+ * dying. They could then set themselves to NULL, or set an
+ * internal flag to detect usage past this point.
+ *
+ * Comments on Non-Intrusive Design:
+ * In a non-intrusive design, the reference count is stored somewhere other
+ * than the object being referenced. This means, unless the reference
+ * counting pointer is the first referencer, it must get a pointer to the
+ * referenced object from another smart pointer (so it has access to the
+ * reference count location). In this non-intrusive design, if we are
+ * pointing to an object with a smart pointer (or a number of smart
+ * pointers), and we then give another smart pointer the address through
+ * a RAW pointer, we will have two independent, AND INCORRECT, reference
+ * counts. To avoid this pitfall, we use an intrusive reference counting
+ * technique where the reference count is stored in the object being
+ * referenced.
+ */
+ class ReferencedObject {
+ public:
+ ReferencedObject() : reference_count_(0) {}
+ virtual ~ReferencedObject() { assert(reference_count_ == 0); }
+ inline int ReferenceCount() const { return reference_count_; }
+ inline void AddRef() const { ++reference_count_; }
+ inline void ReleaseRef() const { --reference_count_; }
+
+ private:
+ mutable int reference_count_;
+ };
+
+ //#########################################################################
+
+
+//#define IP_DEBUG_SMARTPTR
+#if COIN_IPOPT_CHECKLEVEL > 2
+# define IP_DEBUG_SMARTPTR
+#endif
+#ifdef IP_DEBUG_SMARTPTR
+# include "IpDebug.hpp"
+#endif
+
+ /** Template class for Smart Pointers.
+ * A SmartPtr behaves much like a raw pointer, but manages the lifetime
+ * of an object, deleting the object automatically. This class implements
+ * a reference-counting, intrusive smart pointer design, where all
+ * objects pointed to must inherit off of ReferencedObject, which
+ * stores the reference count. Although this is intrusive (native types
+ * and externally authored classes require wrappers to be referenced
+ * by smart pointers), it is a safer design. A more detailed discussion of
+ * these issues follows after the usage information.
+ *
+ * Usage Example:
+ * Note: to use the SmartPtr, all objects to which you point MUST
+ * inherit off of ReferencedObject.
+ *
+ * \verbatim
+ *
+ * In MyClass.hpp...
+ *
+ * #include "CoinSmartPtr.hpp"
+ *
+ * class MyClass : public Coin::ReferencedObject // must derive from ReferencedObject
+ * {
+ * ...
+ * }
+ *
+ * In my_usage.cpp...
+ *
+ * #include "CoinSmartPtr.hpp"
+ * #include "MyClass.hpp"
+ *
+ * void func(AnyObject& obj)
+ * {
+ * SmartPtr<MyClass> ptr_to_myclass = new MyClass(...);
+ * // ptr_to_myclass now points to a new MyClass,
+ * // and the reference count is 1
+ *
+ * ...
+ *
+ * obj.SetMyClass(ptr_to_myclass);
+ * // Here, let's assume that AnyObject uses a
+ * // SmartPtr<MyClass> internally here.
+ * // Now, both ptr_to_myclass and the internal
+ * // SmartPtr in obj point to the same MyClass object
+ * // and its reference count is 2.
+ *
+ * ...
+ *
+ * // No need to delete ptr_to_myclass, this
+ * // will be done automatically when the
+ * // reference count drops to zero.
+ *
+ * }
+ *
+ * \endverbatim
+ *
+ * It is not necessary to use SmartPtr's in all cases where an
+ * object is used that has been allocated "into" a SmartPtr. It is
+ * possible to just pass objects by reference or regular pointers,
+ * even if lower down in the stack a SmartPtr is to be held on to.
+ * Everything should work fine as long as a pointer created by "new"
+ * is immediately passed into a SmartPtr, and if SmartPtr's are used
+ * to hold on to objects.
+ *
+ * Other Notes:
+ * The SmartPtr implements both dereference operators -> & *.
+ * The SmartPtr does NOT implement a conversion operator to
+ * the raw pointer. Use the GetRawPtr() method when this
+ * is necessary. Make sure that the raw pointer is NOT
+ * deleted.
+ * The SmartPtr implements the comparison operators == & !=
+ * for a variety of types. Use these instead of
+ * \verbatim
+ * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this
+ * \endverbatim
+ * SmartPtr's, as currently implemented, do NOT handle circular references.
+ * For example: consider a higher level object using SmartPtrs to point to
+ * A and B, but A and B also point to each other (i.e. A has a SmartPtr
+ * to B and B has a SmartPtr to A). In this scenario, when the higher
+ * level object is finished with A and B, their reference counts will
+ * never drop to zero (since they reference each other) and they
+ * will not be deleted. This can be detected by memory leak tools like
+ * valgrind. If the circular reference is necessary, the problem can be
+ * overcome by a number of techniques:
+ *
+ * 1) A and B can have a method that "releases" each other, that is
+ * they set their internal SmartPtrs to NULL.
+ * \verbatim
+ * void AClass::ReleaseCircularReferences()
+ * {
+ * smart_ptr_to_B = NULL;
+ * }
+ * \endverbatim
+ * Then, the higher level class can call these methods before
+ * it is done using A & B.
+ *
+ * 2) Raw pointers can be used in A and B to reference each other.
+ * Here, an implicit assumption is made that the lifetime is
+ * controlled by the higher level object and that A and B will
+ * both exist in a controlled manner. Although this seems
+ * dangerous, in many situations, this type of referencing
+ * is very controlled and this is reasonably safe.
+ *
+ * 3) This SmartPtr class could be redesigned with the Weak/Strong
+ * design concept. Here, the SmartPtr is identified as being
+ * Strong (controls lifetime of the object) or Weak (merely
+ * referencing the object). The Strong SmartPtr increments
+ * (and decrements) the reference count in ReferencedObject
+ * but the Weak SmartPtr does not. In the example above,
+ * the higher level object would have Strong SmartPtrs to
+ * A and B, but A and B would have Weak SmartPtrs to each
+ * other. Then, when the higher level object was done with
+ * A and B, they would be deleted. The Weak SmartPtrs in A
+ * and B would not decrement the reference count and would,
+ * of course, not delete the object. This idea is very similar
+ * to item (2), where it is implied that the sequence of events
+ * is controlled such that A and B will not call anything using
+ * their pointers following the higher level delete (i.e. in
+ * their destructors!). This is somehow safer, however, because
+ * code can be written (however expensive) to perform run-time
+ * detection of this situation. For example, the ReferencedObject
+ * could store pointers to all Weak SmartPtrs that are referencing
+ * it and, in its destructor, tell these pointers that it is
+ * dying. They could then set themselves to NULL, or set an
+ * internal flag to detect usage past this point.
+ *
+ * Comments on Non-Intrusive Design:
+ * In a non-intrusive design, the reference count is stored somewhere other
+ * than the object being referenced. This means, unless the reference
+ * counting pointer is the first referencer, it must get a pointer to the
+ * referenced object from another smart pointer (so it has access to the
+ * reference count location). In this non-intrusive design, if we are
+ * pointing to an object with a smart pointer (or a number of smart
+ * pointers), and we then give another smart pointer the address through
+ * a RAW pointer, we will have two independent, AND INCORRECT, reference
+ * counts. To avoid this pitfall, we use an intrusive reference counting
+ * technique where the reference count is stored in the object being
+ * referenced.
+ */
+ template <class T>
+ class SmartPtr {
+ public:
+ /** Returns the raw pointer contained. Use to get the value of the
+ * raw ptr (i.e. to pass to other methods/functions, etc.) Note: This
+ * method does NOT copy, therefore, modifications using this value
+ * modify the underlying object contained by the SmartPtr, NEVER
+ * delete this returned value.
+ */
+ T* GetRawPtr() const { return ptr_; }
+
+ /** Returns true if the SmartPtr is NOT NULL.
+ * Use this to check if the SmartPtr is not null
+ * This is preferred to if(GetRawPtr(sp) != NULL)
+ */
+ bool IsValid() const { return ptr_ != NULL; }
+
+ /** Returns true if the SmartPtr is NULL.
+ * Use this to check if the SmartPtr IsNull.
+ * This is preferred to if(GetRawPtr(sp) == NULL)
+ */
+ bool IsNull() const { return ptr_ == NULL; }
+
+ private:
+ /**@name Private Data/Methods */
+ //@{
+ /** Actual raw pointer to the object. */
+ T* ptr_;
+
+ /** Release the currently referenced object. */
+ void ReleasePointer_() {
+ if (ptr_) {
+ ptr_->ReleaseRef();
+ if (ptr_->ReferenceCount() == 0) {
+ delete ptr_;
+ }
+ ptr_ = NULL;
+ }
+ }
+
+ /** Set the value of the internal raw pointer from another raw
+ * pointer, releasing the previously referenced object if necessary. */
+ SmartPtr<T>& SetFromRawPtr_(T* rhs){
+ ReleasePointer_(); // Release any old pointer
+ if (rhs != NULL) {
+ rhs->AddRef();
+ ptr_ = rhs;
+ }
+ return *this;
+ }
+
+ /** Set the value of the internal raw pointer from a SmartPtr,
+ * releasing the previously referenced object if necessary. */
+ inline SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs) {
+ SetFromRawPtr_(rhs.GetRawPtr());
+ return (*this);
+ }
+
+ //@}
+
+ public:
+#define dbg_smartptr_verbosity 0
+
+ /**@name Constructors/Destructors */
+ //@{
+ /** Default constructor, initialized to NULL */
+ SmartPtr() : ptr_(NULL) {}
+
+ /** Copy constructor, initialized from copy */
+ SmartPtr(const SmartPtr<T>& copy) : ptr_(NULL) {
+ (void) SetFromSmartPtr_(copy);
+ }
+
+ /** Constructor, initialized from T* ptr */
+ SmartPtr(T* ptr) : ptr_(NULL) {
+ (void) SetFromRawPtr_(ptr);
+ }
+
+ /** Destructor, automatically decrements the reference count, deletes
+ * the object if necessary.*/
+ ~SmartPtr() {
+ ReleasePointer_();
+ }
+ //@}
+
+ /**@name Overloaded operators. */
+ //@{
+ /** Overloaded arrow operator, allows the user to call
+ * methods using the contained pointer. */
+ T* operator->() const {
+#if COIN_COINUTILS_CHECKLEVEL > 0
+ assert(ptr_);
+#endif
+ return ptr_;
+ }
+
+ /** Overloaded dereference operator, allows the user
+ * to dereference the contained pointer. */
+ T& operator*() const {
+#if COIN_IPOPT_CHECKLEVEL > 0
+ assert(ptr_);
+#endif
+ return *ptr_;
+ }
+
+ /** Overloaded equals operator, allows the user to
+ * set the value of the SmartPtr from a raw pointer */
+ SmartPtr<T>& operator=(T* rhs) {
+ return SetFromRawPtr_(rhs);
+ }
+
+ /** Overloaded equals operator, allows the user to
+ * set the value of the SmartPtr from another
+ * SmartPtr */
+ SmartPtr<T>& operator=(const SmartPtr<T>& rhs) {
+ return SetFromSmartPtr_(rhs);
+ }
+
+ /** Overloaded equality comparison operator, allows the
+ * user to compare the value of two SmartPtrs */
+ template <class U1, class U2>
+ friend
+ bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
+
+ /** Overloaded equality comparison operator, allows the
+ * user to compare the value of a SmartPtr with a raw pointer. */
+ template <class U1, class U2>
+ friend
+ bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs);
+
+ /** Overloaded equality comparison operator, allows the
+ * user to compare the value of a raw pointer with a SmartPtr. */
+ template <class U1, class U2>
+ friend
+ bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs);
+
+ /** Overloaded in-equality comparison operator, allows the
+ * user to compare the value of two SmartPtrs */
+ template <class U1, class U2>
+ friend
+ bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs);
+
+ /** Overloaded in-equality comparison operator, allows the
+ * user to compare the value of a SmartPtr with a raw pointer. */
+ template <class U1, class U2>
+ friend
+ bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs);
+
+ /** Overloaded in-equality comparison operator, allows the
+ * user to compare the value of a SmartPtr with a raw pointer. */
+ template <class U1, class U2>
+ friend
+ bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs);
+ //@}
+
+ };
+
+ template <class U1, class U2>
+ bool ComparePointers(const U1* lhs, const U2* rhs) {
+ if (lhs == rhs) {
+ return true;
+ }
+ // If lhs and rhs point to the same object with different interfaces
+ // U1 and U2, we cannot guarantee that the value of the pointers will
+ // be equivalent. We can guarantee this if we convert to void*.
+ return static_cast<const void*>(lhs) == static_cast<const void*>(rhs);
+ }
+
+} // namespace Coin
+
+//#############################################################################
+
+/**@name SmartPtr friends that are overloaded operators, so they are not in
+ the Coin namespace. */
+//@{
+template <class U1, class U2>
+bool operator==(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) {
+ return Coin::ComparePointers(lhs.GetRawPtr(), rhs.GetRawPtr());
+}
+
+template <class U1, class U2>
+bool operator==(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) {
+ return Coin::ComparePointers(lhs.GetRawPtr(), raw_rhs);
+}
+
+template <class U1, class U2>
+bool operator==(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) {
+ return Coin::ComparePointers(raw_lhs, rhs.GetRawPtr());
+}
+
+template <class U1, class U2>
+bool operator!=(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) {
+ return ! operator==(lhs, rhs);
+}
+
+template <class U1, class U2>
+bool operator!=(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) {
+ return ! operator==(lhs, raw_rhs);
+}
+
+template <class U1, class U2>
+bool operator!=(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) {
+ return ! operator==(raw_lhs, rhs);
+}
+//@}
+
+#define CoinReferencedObject Coin::ReferencedObject
+#define CoinSmartPtr Coin::SmartPtr
+#define CoinComparePointers Coin::ComparePointers
+
+#endif