/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkWeakPointer_h #define itkWeakPointer_h #include "itkMacro.h" #include namespace itk { /** \class WeakPointer * \brief Implements a weak reference to an object. * * WeakPointer implements a weak reference to an object. A natural * interface to the class is defined by operator -> (and *) among others. * WeakPointer is really nothing more than a standard pointer. It is used * to call attention to the fact that it does not adjust the reference * count of an object like SmartPointer does. WeakPointer is used internally * to Insight to manage (break) reference counting loops. At some point, * an object may keep track of how many objects hold weak references to * itself. In all cases, however, an outstanding weak reference will not * keep an object from destructing. * * \ingroup ITKSystemObjects * \ingroup DataAccess * \ingroup ITKCommon */ template class WeakPointer { public: /** Extract information from template parameter. */ using ObjectType = TObjectType; /** Explicitly-defaulted default-constructor. * \note The other five "special member functions" (copy-constructor, * copy-assignment operator, move-constructor, move-assignment operator, * and destructor) are defaulted implicitly, following the C++ "Rule of Zero". */ WeakPointer() = default; /** Constructor, converting from `nullptr`. */ WeakPointer(std::nullptr_t) {} /** Constructor to pointer p. */ WeakPointer(ObjectType * p) : m_Pointer(p) {} /** Overload operator ->. */ ObjectType * operator->() const { return m_Pointer; } /** Return pointer to object. */ operator ObjectType *() const { return m_Pointer; } /** Template comparison operators. */ template bool operator==(R r) const { return (m_Pointer == (ObjectType *)r); } #ifndef ITK_EXPERIMENTAL_CXX20_REWRITTEN_UNEQUAL_OPERATOR template bool operator!=(R r) const { return !(this->operator==(r)); } #endif /** Access function to pointer. */ ObjectType * GetPointer() const { return m_Pointer; } /** Test if the pointer is not NULL. */ bool IsNotNull() const { return m_Pointer != nullptr; } /** Test if the pointer is NULL. */ bool IsNull() const { return m_Pointer == nullptr; } /** Comparison of pointers. Less than comparison. */ bool operator<(const WeakPointer & r) const { return (void *)m_Pointer < (void *)r.m_Pointer; } /** Comparison of pointers. Greater than comparison. */ bool operator>(const WeakPointer & r) const { return (void *)m_Pointer > (void *)r.m_Pointer; } /** Comparison of pointers. Less than or equal to comparison. */ bool operator<=(const WeakPointer & r) const { return (void *)m_Pointer <= (void *)r.m_Pointer; } /** Comparison of pointers. Greater than or equal to comparison. */ bool operator>=(const WeakPointer & r) const { return (void *)m_Pointer >= (void *)r.m_Pointer; } /** Function to print object pointed to. */ ObjectType * Print(std::ostream & os) const { if (this->IsNull()) { os << "(null)"; } else { // This prints the object pointed to by the pointer m_Pointer->Print(os); } return m_Pointer; } private: /** The pointer to the object referred to by this smart pointer. */ ObjectType * m_Pointer{ nullptr }; }; template std::ostream & operator<<(std::ostream & os, const WeakPointer p) { p.Print(os); return os; } } // end namespace itk #endif