NCBI C++ ToolKit
ncbiobj.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef CORELIB___NCBIOBJ__HPP
2 #define CORELIB___NCBIOBJ__HPP
3 
4 /* $Id: ncbiobj.hpp 99781 2023-05-10 17:44:44Z vasilche $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software/database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software/database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author: Eugene Vasilchenko, Pavel Ivanov
30  *
31  *
32  */
33 
34 /// @file ncbiobj.hpp
35 /// Portable reference counted smart and weak pointers using
36 /// CWeakRef, CRef, CObject and CObjectEx.
37 
38 
39 #include <corelib/ncbicntr.hpp>
40 #include <corelib/ncbiatomic.hpp>
41 #include <corelib/ddumpable.hpp>
42 
43 /// this relieves us of some nastiness with Win32's version of GetObject(),
44 /// which prevents us from using CRef<>::GetObject in lots of places
45 #if defined(NCBI_OS_MSWIN)
46 # include <corelib/ncbi_os_mswin.hpp>
47 #endif
48 
49 
50 /** @addtogroup Object
51  *
52  * @{
53  */
54 
55 
56 
58 
59 class CObjectMemoryPool;
60 class CObject;
61 class CObjectEx;
62 
63 
64 /////////////////////////////////////////////////////////////////////////////
65 ///
66 /// CObjectException --
67 ///
68 /// Define exceptions generated by CObject.
69 ///
70 /// CObjectException inherits its basic functionality from CCoreException
71 /// and defines additional error codes.
72 
74 {
75 public:
76  /// Error types that an application can generate.
77  enum EErrCode {
78  eRefDelete, ///< Attempt to delete valid reference
79  eDeleted, ///< Attempt to delete a deleted object
80  eCorrupted, ///< Object corrupted error
81  eRefOverflow, ///< Reference overflow error
82  eNoRef, ///< Attempt to access an object that is unreferenced
83  eRefUnref, ///< Attempt to make a referenced object an
84  ///< unreferenced one
85  eHeapState ///< Attempt to make incorrect in-heap state
86  };
87 
88  /// Translate from the error code value to its string representation.
89  virtual const char* GetErrCodeString(void) const override;
90 
91  // Standard exception boilerplate code.
93 
94 protected:
95  void x_InitErrCode(CException::EErrCode err_code) override;
96 };
97 
98 
99 ////////////////////////////////////////////////////////////////////////////
100 /// CObjectCounterLocker --
101 /// Default locker class for CRef/CConstRef templates,
102 /// all other locker classes should be subclasses of CObjectCounterLocker
103 /// and use its locking methods.
104 /// The CObjectCounterLocker in Debug mode allows to monitor locking/unlocking
105 /// of some object class. The locking methods are non-inlined for this purpose.
106 /// Monitored class is controlled by static methods MonitorObjectType() and
107 /// StopMonitoring(). Currently locked objects and CRef<> pointers to them
108 /// can be printed by calling static method ReportLockedObjects().
109 ////////////////////////////////////////////////////////////////////////////
110 
111 #ifdef _DEBUG
112 # define NCBI_OBJECT_LOCKER_EXPORT NCBI_XNCBI_EXPORT
113 #else
114 # define NCBI_OBJECT_LOCKER_EXPORT
115 # define NCBI_OBJECT_LOCKER_INLINE
116 #endif
117 
119 {
120 public:
121  // Mark object as "locked" from deletion.
122  void NCBI_OBJECT_LOCKER_EXPORT Lock(const CObject* object) const;
123 
124  // Mark object as "locked" from deletion if it was already locked by
125  // another locker object.
126  // Preconditions: this locker was assigned from the another locker object.
127  void NCBI_OBJECT_LOCKER_EXPORT Relock(const CObject* object) const;
128 
129  // Mark object as "unlocked" for deletion,
130  // delete it if last lock was removed.
131  void NCBI_OBJECT_LOCKER_EXPORT Unlock(const CObject* object) const;
132 
133  // Mark object as "unlocked" for deletion, but do not delete it.
134  void NCBI_OBJECT_LOCKER_EXPORT UnlockRelease(const CObject* object) const;
135 
136  // Transfer lock from other locker
138  const CObjectCounterLocker& old_locker) const;
139 
140  NCBI_NORETURN static
141  void NCBI_XNCBI_EXPORT ReportIncompatibleType(const type_info& type);
142 
143  /// Set monitored object type, e.g. typeid(CScope)
144  /// The method has no effect in Release mode.
145  static
146  void NCBI_XNCBI_EXPORT MonitorObjectType(const type_info& type);
147  /// Stop lock/unlock monitoring.
148  /// The method has no effect in Release mode.
149  static
151  /// Print all currently locked objects of monitored type.
152  /// The method has no effect in Release mode.
153  static
154  void NCBI_XNCBI_EXPORT ReportLockedObjects(bool clear = false);
155 };
156 
157 
158 /////////////////////////////////////////////////////////////////////////////
159 // Traits for default locker parameter
160 /////////////////////////////////////////////////////////////////////////////
161 
162 template <class C>
164 {
165 public:
167 };
168 
169 
170 /////////////////////////////////////////////////////////////////////////////
171 ///
172 /// CObject --
173 ///
174 /// Define the CObject which stores the reference count and the object.
175 ///
176 /// CObject inherits from CDebugDumpable the ability to "dump" diagnostic
177 /// information useful for debugging.
178 
179 class CObject : public CDebugDumpable
180 {
181 public:
182  /// Default locker type for CRef
184  /// Constructor.
186  CObject(void);
187 
188  /// Copy constructor.
190  CObject(const CObject& src);
191 
192  /// Destructor.
194  virtual ~CObject(void);
195 
196  /// Assignment operator.
197  CObject& operator=(const CObject& src) THROWS_NONE;
198 
199  /// Check if object can be deleted.
200  bool CanBeDeleted(void) const THROWS_NONE;
201 
202  /// Check if object is allocated in memory pool (not system heap)
203  bool IsAllocatedInPool(void) const THROWS_NONE;
204 
205  /// Check if object is referenced.
206  bool Referenced(void) const THROWS_NONE;
207 
208  /// Check if object is referenced only once.
209  bool ReferencedOnlyOnce(void) const THROWS_NONE;
210 
211  /// Add reference to object.
212  void AddReference(void) const;
213 
214  /// Remove reference to object.
215  void RemoveReference(void) const;
216 
217  /// Remove reference without deleting object.
219  void ReleaseReference(void) const;
220 
221  /// Mark this object as not allocated in heap -- do not delete this
222  /// object.
224  virtual void DoNotDeleteThisObject(void);
225 
226  /// Mark this object as allocated in heap -- object can be deleted.
228  virtual void DoDeleteThisObject(void);
229 
230  // operators new/delete for additional checking in debug mode
231 
232  /// Define new operator for memory allocation.
234  void* operator new(size_t size);
235 
236  /// Define new[] operator for 'array' memory allocation.
238  void* operator new[](size_t size);
239 
240  /// Define delete operator for memory deallocation.
242  void operator delete(void* ptr);
243 
244  /// Define delete[] operator for memory deallocation.
246  void operator delete[](void* ptr);
247 
248  /// Define new operator.
250  void* operator new(size_t size, void* place);
251 
252  /// Define delete operator.
254  void operator delete(void* ptr, void* place);
255 
256  /// Define new operator using memory pool.
258  void* operator new(size_t size, CObjectMemoryPool* place);
259 
260  /// Define delete operator.
262  void operator delete(void* ptr, CObjectMemoryPool* place);
263 
264  /// Define method for dumping debug information.
266  virtual void DebugDump(CDebugDumpContext ddc, unsigned int depth) const;
267 
268  /// Define method to throw null pointer exception.
269  ///
270  /// Static method through which all CRef<> / CConstRef<> null pointer
271  /// throws travel. This is done to avoid an inline throw.
272  NCBI_NORETURN NCBI_XNCBI_EXPORT
273  static void ThrowNullPointerException(void);
274  NCBI_NORETURN NCBI_XNCBI_EXPORT
275  static void ThrowNullPointerException(const type_info& type);
276 
277 
278  /// Control filling of newly allocated memory
279  ///
280  /// Default mode is eAllocFillNone if not changed by configuration.
281  /// eAllocFillNone - do not fill at all
282  /// this mode is faster and is necessary to avoid interference with
283  /// memory checker programs like Valgrind.
284  /// eAllocFillZero - fill new memory with zeros (old default mode)
285  /// eAllocFillPattern - fill with non-zero pattern
290  };
291  static EAllocFillMode GetAllocFillMode(void);
292  static void SetAllocFillMode(EAllocFillMode mode);
293  /// Set mode from configuration parameter value.
294  static void SetAllocFillMode(const string& value);
295 
296 protected:
297  /// Virtual method "deleting" this object.
298  /// Method is called whenever by all other indicators this object should
299  /// be deleted. These indicators are: last reference to the object is
300  /// removed, object created on heap and method DoNotDeleteThisObject()
301  /// was not called. Default implementation actually deletes the object,
302  /// but derived classes are free to do whatever they want (e.g. if they
303  /// know that they are allocated at some pool they should return
304  /// themselves to this pool).
306  virtual void DeleteThis(void);
307 
308 public:
309  typedef atomic<Uint8> TCounter; ///< Counter type is CAtomiCounter
310  typedef Uint8 TCount; ///< Alias for value type of counter
311 
312  /// Define possible object states.
313  ///
314  /// When TCounter is signed, all valid values start with 01;
315  /// when it is unsigned, they start with 1. In other words, when
316  /// TCounter is signed, the msb (most significant bit) is 0, and the bit
317  /// after that is a 1; and if the counter is unsigned, then the msb is 1.
318  ///
319  /// Least significant bits are the "memory" bits and the most
320  /// significant bit (or the one after it) is the "valid" bit.
321  ///
322  /// The following bit positions have special significance:
323  /// - Least significant bit = 0 means object not in heap.
324  /// - Least significant bit = 1 means object in heap.
325  /// - Most significant bit (or one after it) = 0 means object not valid
326  /// - Most significant bit (or one after it) = 1 means object is valid
327  ///
328  /// Possible bit patterns:
329  /// - [0]0x...xxxx : non valid object -> cannot be referenced.
330  /// - [0]1c...ccx0 : object not in heap -> cannot be deleted.
331  /// - [0]1c...cc01 : object in heap pool -> can be deleted via CMemoryPool
332  /// - [0]1c...cc11 : object in heap -> can be deleted.
333 
334  /// Detected as in heap
335  static const TCount eCounterBitsCanBeDeleted = 1 << 0;
336  /// Heap signature was found
337  static const TCount eCounterBitsInPlainHeap = 1 << 1;
338  /// Mask for 'in heap' state flags
341  /// Skip over the "in heap" bits
342  static const int eCounterStep = 1 << 2;
343 
344  /// Minimal value for valid objects (reference counter is zero)
345  /// Must be a single bit value.
346  /// All counter values less than this value are invalid.
347 #ifdef NCBI_COUNTER_UNSIGNED
348  /// 1 in the left most of the valid bits -- unsigned case
349  static const TCount eCounterValid = TCount(1) << (sizeof(TCount) * 8 - 1);
350 #else
351  /// 1 in the left most of the valid bits -- signed case
352  static const TCount eCounterValid = TCount(1) << (sizeof(TCount) * 8 - 2);
353 #endif
354  /// Valid object, and object in heap.
355  static const TCount eCounterStateMask =
357 
358 private:
359  friend class CObjectMemoryPool;
360  friend class CWeakObject;
361 
362  // special methods for parsing object state number
363 
364  /// Check if object state is valid.
365  static bool ObjectStateValid(TCount count);
366 
367  /// Check if object can be deleted.
368  static bool ObjectStateCanBeDeleted(TCount count);
369 
370  /// Check if object is allocated in memory pool.
371  static bool ObjectStateIsAllocatedInPool(TCount count);
372 
373  /// Check if object can be referenced.
374  static bool ObjectStateUnreferenced(TCount count);
375 
376  /// Check if object can be referenced.
377  static bool ObjectStateReferenced(TCount count);
378 
379  /// Check if object can be referenced only once.
380  static bool ObjectStateReferencedOnlyOnce(TCount count);
381 
382  /// Initialize counter.
383  void InitCounter(void);
384 
385  /// Remove the last reference.
387  void RemoveLastReference(TCount count) const;
388 
389  // report different kinds of error
390 
391  /// Report object is invalid.
392  ///
393  /// Example: Attempt to use a deleted object.
394  void InvalidObject(void) const;
395 
396  /// Report that counter has overflowed.
397  NCBI_NORETURN NCBI_XNCBI_EXPORT
398  void CheckReferenceOverflow(TCount count) const;
399 
400  mutable TCounter m_Counter; ///< The actual reference counter
401 };
402 
403 
404 ////////////////////////////////////////////////////////////////////////////
405 // Inline methods of CObject
406 ////////////////////////////////////////////////////////////////////////////
407 
408 
409 inline
411 {
412  // check only 'CanBeDeleted' bit, include both plain heap and memory pool
413  return (count & eCounterBitsCanBeDeleted) != 0;
414 }
415 
416 
417 inline
419 {
420  // check if 'CanBeDeleted' is set and InPlainHeap is not set
422 }
423 
424 
425 inline
427 {
428  return count >= eCounterValid;
429 }
430 
431 
432 inline
434 {
435  return count >= eCounterValid + eCounterStep;
436 }
437 
438 
439 inline
441 {
442  return (count & ~eCounterBitsPlaceMask) == eCounterValid;
443 }
444 
445 
446 inline
448 {
449  return (count & ~eCounterBitsPlaceMask) == eCounterValid + eCounterStep;
450 }
451 
452 
453 inline
455 {
456  return ObjectStateCanBeDeleted(m_Counter);
457 }
458 
459 
460 inline
462 {
463  return ObjectStateIsAllocatedInPool(m_Counter);
464 }
465 
466 
467 inline
469 {
470  return ObjectStateReferenced(m_Counter);
471 }
472 
473 
474 inline
476 {
477  return ObjectStateReferencedOnlyOnce(m_Counter);
478 }
479 
480 
481 inline
483 {
484  return *this;
485 }
486 
487 
488 inline
489 void CObject::AddReference(void) const
490 {
491  TCount newCount = (m_Counter += eCounterStep);
492  if ( !ObjectStateReferenced(newCount) ) {
493  m_Counter -= eCounterStep; // undo
495  }
496 }
497 
498 
499 inline
500 void CObject::RemoveReference(void) const
501 {
502  TCount newCount = (m_Counter -= eCounterStep);
503  if ( !ObjectStateReferenced(newCount) ) {
504  RemoveLastReference(newCount);
505  }
506 }
507 
508 
509 ////////////////////////////////////////////////////////////////////////////
510 // CObjectCounterLocker inline methods
511 ////////////////////////////////////////////////////////////////////////////
512 
513 #ifdef NCBI_OBJECT_LOCKER_INLINE
514 // debug version of CObjectCounterLocker allows monitoring some object type
515 inline
516 void CObjectCounterLocker::Lock(const CObject* object) const
517 {
518  object->AddReference();
519 }
520 
521 
522 inline
523 void CObjectCounterLocker::Relock(const CObject* object) const
524 {
525  Lock(object);
526 }
527 
528 
529 inline
530 void CObjectCounterLocker::Unlock(const CObject* object) const
531 {
532  object->RemoveReference();
533 }
534 
535 
536 inline
537 void CObjectCounterLocker::UnlockRelease(const CObject* object) const
538 {
539  object->ReleaseReference();
540 }
541 
542 
543 inline
544 void CObjectCounterLocker::TransferLock(const CObject* /*object*/,
545  const CObjectCounterLocker& /*old_locker*/) const
546 {
547 }
548 #endif
549 
550 
551 ////////////////////////////////////////////////////////////////////////////
552 // Locker class for interfaces, later derived from CObject
553 ////////////////////////////////////////////////////////////////////////////
554 
555 template<class Interface>
557 {
558 public:
559  void Lock(const Interface* object) const
560  {
561  const CObject* cobject = dynamic_cast<const CObject*>(object);
562  if ( !cobject ) {
564  }
566  }
567 
568  void Relock(const Interface* object) const
569  {
570  const CObject* cobject = dynamic_cast<const CObject*>(object);
571  _ASSERT(cobject);
573  }
574 
575  void Unlock(const Interface* object) const
576  {
577  const CObject* cobject = dynamic_cast<const CObject*>(object);
578  _ASSERT(cobject);
580  }
581 
582  void UnlockRelease(const Interface* object) const
583  {
584  const CObject* cobject = dynamic_cast<const CObject*>(object);
585  _ASSERT(cobject);
587  }
588 
589 #ifdef NCBI_OBJECT_LOCKER_INLINE
590  void TransferLock(const Interface* /*object*/,
591  const CInterfaceObjectLocker<Interface>& /*old_locker*/) const
592  {
593  }
594 #else
595  // only non-inline method does something
596  void TransferLock(const Interface* object,
597  const CInterfaceObjectLocker<Interface>& old_locker) const
598  {
599  const CObject* cobject = dynamic_cast<const CObject*>(object);
600  _ASSERT(cobject);
601  CObjectCounterLocker::TransferLock(cobject, old_locker);
602  }
603 #endif
604 };
605 
606 
607 /////////////////////////////////////////////////////////////////////////////
608 ///
609 /// CRef --
610 ///
611 /// Define a template class that stores a pointer to an object and defines
612 /// methods for referencing that object.
613 
614 template<class C, class Locker = typename CLockerTraits<C>::TLockerType> class CRef;
615 template<class C, class Locker = typename CLockerTraits<C>::TLockerType> class CConstRef;
616 
617 template<class C, class Locker>
618 class CRef {
619 public:
620  typedef C element_type; ///< Define alias element_type
621  typedef element_type TObjectType; ///< Define alias TObjectType
622  typedef Locker locker_type; ///< Define alias for locking type
623  typedef CRef<C, Locker> TThisType; ///< Alias for this template type
624 
625  /// Helper template to template enable methods only for derived types
626  template<class T>
629  template<class TDerived, class TLocker> friend class CRef;
630  template<class TDerived, class TLocker> friend class CConstRef;
631 
632  /// Constructor for null pointer.
633  inline
635  {
636  }
637 
638  /// Constructor for ENull pointer.
639  inline
641  {
642  }
643 
644  /// Constructor for explicit type conversion from pointer to object.
645  explicit CRef(TObjectType* ptr)
646  : m_Data(locker_type(), ptr)
647  {
648  x_LockFromPtr();
649  }
650 
651  /// Constructor for explicit type conversion from pointer to object.
652  CRef(TObjectType* ptr, const locker_type& locker_value)
653  : m_Data(locker_value, ptr)
654  {
655  x_LockFromPtr();
656  }
657 
658  /// Copy constructor from an existing CRef object
659  CRef(const TThisType& ref)
660  : m_Data(ref.m_Data)
661  {
662  x_LockFromRef();
663  }
664 
665  /// Copy constructor from an existing CRef object of derived type
666  template<class TDerived,
667  class = typename enable_if_derived<TDerived>::type>
669  : m_Data(ref.GetLocker(), ref.GetNCPointerOrNull())
670  {
671  x_LockFromRef();
672  }
673 
674  /// Move constructor from an existing CRef object
676  : m_Data(ref.m_Data)
677  {
678  x_LockFromMoveConstructor(ref.m_Data.first());
679  ref.m_Data.second() = 0;
680  }
681 
682  /// Move constructor from an existing CRef object of derived type
683  template<class TDerived,
684  class = typename enable_if_derived<TDerived>::type>
686  : m_Data(ref.GetLocker(), ref.GetNCPointerOrNull())
687  {
688  x_LockFromMoveConstructor(ref.m_Data.first());
689  ref.m_Data.second() = 0;
690  }
691 
692  /// Destructor.
693  ~CRef(void)
694  {
695  Reset();
696  }
697 
698  /// Get reference to locker object
699  const locker_type& GetLocker(void) const
700  {
701  return m_Data.first();
702  }
703 
704  /// Check if CRef is empty -- not pointing to any object, which means
705  /// having a null value.
706  ///
707  /// @sa
708  /// Empty(), IsNull()
709  bool operator!(void) const THROWS_NONE
710  {
711  return m_Data.second() == 0;
712  }
713 
714  /// Check if CRef is empty -- not pointing to any object, which means
715  /// having a null value.
716  ///
717  /// @sa
718  /// IsNull(), operator!()
719  bool Empty(void) const THROWS_NONE
720  {
721  return m_Data.second() == 0;
722  }
723 
724  /// Check if CRef is not empty -- pointing to an object and has
725  /// a non-null value.
726  bool NotEmpty(void) const THROWS_NONE
727  {
728  return m_Data.second() != 0;
729  }
730 
731  /// Check if pointer is null -- same effect as Empty().
732  ///
733  /// @sa
734  /// Empty(), operator!()
735  bool IsNull(void) const THROWS_NONE
736  {
737  return m_Data.second() == 0;
738  }
739 
740  /// Check if pointer is not null -- same effect as NotEmpty().
741  ///
742  /// @sa
743  /// NotEmpty()
744  bool NotNull(void) const THROWS_NONE
745  {
746  return m_Data.second() != 0;
747  }
748 
749  /// Swaps the pointer with another reference
750  ///
751  /// @sa
752  /// Swap(CRef<>&)
753  inline
754  void Swap(TThisType& ref)
755  {
756  swap(m_Data, ref.m_Data);
757  if ( TObjectType* ptr = m_Data.second() ) {
758  m_Data.first().TransferLock(ptr, ref.m_Data.first());
759  }
760  if ( TObjectType* ptr = ref.m_Data.second() ) {
761  ref.m_Data.first().TransferLock(ptr, m_Data.first());
762  }
763  }
764 
765  /// Reset reference object.
766  ///
767  /// This sets the pointer to object to null, and removes reference
768  /// count to object and deletes the object if this is the last reference
769  /// to the object.
770  /// @sa
771  /// Reset(TObjectType*)
772  inline
773  void Reset(void)
774  {
775  TObjectType* ptr = m_Data.second();
776  if ( ptr ) {
777  m_Data.second() = 0;
778  m_Data.first().Unlock(ptr);
779  }
780  }
781 
782  /// Reset reference object to new pointer.
783  ///
784  /// This sets the pointer to object to the new pointer, and removes
785  /// reference count to old object and deletes the old object if this is
786  /// the last reference to the old object.
787  /// @sa
788  /// Reset()
789  inline
790  void Reset(TObjectType* newPtr)
791  {
792  TObjectType* oldPtr = m_Data.second();
793  if ( newPtr != oldPtr ) {
794  if ( newPtr ) {
795  m_Data.first().Lock(newPtr);
796  }
797  m_Data.second() = newPtr;
798  if ( oldPtr ) {
799  m_Data.first().Unlock(oldPtr);
800  }
801  }
802  }
803 
804  /// Release a reference to the object and return a pointer to the object.
805  ///
806  /// Releasing a reference means decreasing the reference count by "1". A
807  /// pointer to the existing object is returned, unless this pointer is
808  /// already null(0), in which case a null(0) is returned.
809  ///
810  /// Similar to Release(), except that this method returns a null,
811  /// whereas Release() throws a null pointer exception.
812  ///
813  /// @sa
814  /// Release()
815  inline
817  {
818  TObjectType* ptr = m_Data.second();
819  if ( !ptr ) {
820  return 0;
821  }
822  m_Data.second() = 0;
823  m_Data.first().UnlockRelease(ptr);
824  return ptr;
825  }
826 
827  NCBI_NORETURN
828  static void ThrowNullPointerException(void)
829  {
830  CObject::ThrowNullPointerException(/*typeid(TObjectType*)*/);
831  }
832 
833  /// Release a reference to the object and return a pointer to the object.
834  ///
835  /// Releasing a reference means decreasing the reference count by "1". A
836  /// pointer to the existing object is returned, unless this pointer is
837  /// already null(0), in which the null pointer exception (eNullPtr) is
838  /// thrown.
839  ///
840  /// Similar to ReleaseOrNull(), except that this method throws an exception
841  /// whereas ReleaseOrNull() does not.
842  ///
843  /// @sa
844  /// ReleaseOrNull()
845  inline
847  {
848  TObjectType* ptr = m_Data.second();
849  if ( !ptr ) {
851  }
852  m_Data.second() = 0;
853  m_Data.first().UnlockRelease(ptr);
854  return ptr;
855  }
856 
857  /// Reset reference object to new pointer.
858  ///
859  /// This sets the pointer to object to the new pointer, and removes
860  /// reference count to old object and deletes the old object if this is
861  /// the last reference to the old object.
862  /// The new pointer is got from ref argument.
863  /// Operation is atomic on this object, so that AtomicResetFrom() and
864  /// AtomicReleaseTo() called from different threads will work properly.
865  /// Operation is not atomic on ref argument.
866  /// @sa
867  /// AtomicReleaseTo(CRef& ref);
868  inline
869  void AtomicResetFrom(const TThisType& ref)
870  {
871  TObjectType* ptr = ref.m_Data.second();
872  if ( ptr )
873  m_Data.first().Lock(ptr); // for this
874  TObjectType* old_ptr = AtomicSwap(ptr);
875  if ( old_ptr )
876  m_Data.first().Unlock(old_ptr);
877  }
878  /// Release referenced object to another CRef<> object.
879  ///
880  /// This copies the pointer to object to the argument ref,
881  /// and release reference from this object.
882  /// Old reference object held by argument ref is released and deleted if
883  /// necessary.
884  /// Operation is atomic on this object, so that AtomicResetFrom() and
885  /// AtomicReleaseTo() called from different threads will work properly.
886  /// Operation is not atomic on ref argument.
887  /// @sa
888  /// AtomicResetFrom(const CRef& ref);
889  inline
891  {
892  TObjectType* old_ptr = AtomicSwap(0);
893  if ( old_ptr ) {
894  ref.Reset(old_ptr);
895  m_Data.first().Unlock(old_ptr);
896  }
897  else {
898  ref.Reset();
899  }
900  }
901 
902  /// Assignment operator for references.
904  {
906  return *this;
907  }
908 
909  /// Assignment operator for references of derived types
910  template<class TDerived,
911  class = typename enable_if_derived<TDerived>::type>
913  {
915  return *this;
916  }
917 
918  /// Move assignment operator for references.
920  {
921 #ifdef NCBI_COMPILER_MSVC
922  // extra check on MSVC
923  if (this == &ref) {
924  // no-op
925  return *this;
926  }
927 #endif
928  x_MoveAssign(ref.m_Data.first(), ref.m_Data.second());
929  ref.m_Data.second() = 0;
930  return *this;
931  }
932 
933  /// Move assignment operator for references of derived types
934  template<class TDerived,
935  class = typename enable_if_derived<TDerived>::type>
937  {
938  x_MoveAssign(ref.m_Data.first(), ref.m_Data.second());
939  ref.m_Data.second() = 0;
940  return *this;
941  }
942 
943  /// Assignment operator for references with right hand side set to
944  /// a pointer.
946  {
947  Reset(ptr);
948  return *this;
949  }
950 
951  /// Assignment operator with right hand side set to ENull.
953  {
954  Reset();
955  return *this;
956  }
957 
958  /// Get pointer value and throw a null pointer exception if pointer
959  /// is null.
960  ///
961  /// Similar to GetPointerOrNull() except that this method throws a null
962  /// pointer exception if pointer is null, whereas GetPointerOrNull()
963  /// returns a null value.
964  ///
965  /// @sa
966  /// GetPointerOrNull(), GetPointer(), GetObject()
967  inline
969  {
970  TObjectType* ptr = m_Data.second();
971  if ( !ptr ) {
973  }
974  return ptr;
975  }
976 
977  /// Get pointer value.
978  ///
979  /// Similar to GetNonNullPointer() except that this method returns a null
980  /// if the pointer is null, whereas GetNonNullPointer() throws a null
981  /// pointer exception.
982  ///
983  /// @sa
984  /// GetNonNullPointer()
985  inline
987  {
988  return m_Data.second();
989  }
990 
991  /// Get pointer,
992  ///
993  /// Same as GetPointerOrNull().
994  ///
995  /// @sa
996  /// GetPointerOrNull()
997  inline
999  {
1000  return GetPointerOrNull();
1001  }
1002 
1003  /// Get object.
1004  ///
1005  /// Similar to GetNonNullPointer(), except that this method returns the
1006  /// object whereas GetNonNullPointer() returns a pointer to the object.
1007  ///
1008  /// @sa
1009  /// GetNonNullPointer()
1010  inline
1012  {
1013  return *GetNonNullPointer();
1014  }
1015 
1016  /// Dereference operator returning object.
1017  ///
1018  /// @sa
1019  /// GetObject()
1020  inline
1022  {
1023  return *GetNonNullPointer();
1024  }
1025 
1026  /// Reference operator.
1027  ///
1028  /// @sa
1029  /// GetPointer()
1030  inline
1032  {
1033  return GetNonNullPointer();
1034  }
1035 
1036  // Const getters.
1037 
1038  /// Get pointer value and throw a null pointer exception if pointer
1039  /// is null -- constant version.
1040  ///
1041  /// Similar to GetPointerOrNull() except that this method throws a null
1042  /// pointer exception if pointer is null, whereas GetPointerOrNull()
1043  /// returns a null value.
1044  ///
1045  /// @sa
1046  /// GetPointerOrNull(), GetPointer(), GetObject()
1047  const TObjectType* GetNonNullPointer(void) const
1048  {
1049  const TObjectType* ptr = m_Data.second();
1050  if ( !ptr ) {
1052  }
1053  return ptr;
1054  }
1055 
1056  /// Get pointer value -- constant version.
1057  ///
1058  /// Similar to GetNonNullPointer() except that this method returns a null
1059  /// if the pointer is null, whereas GetNonNullPointer() throws a null
1060  /// pointer exception.
1061  ///
1062  /// @sa
1063  /// GetNonNullPointer()
1065  {
1066  return m_Data.second();
1067  }
1068 
1069  /// Get pointer -- constant version,
1070  ///
1071  /// Same as GetPointerOrNull().
1072  ///
1073  /// @sa
1074  /// GetPointerOrNull()
1075  inline
1077  {
1078  return GetPointerOrNull();
1079  }
1080 
1081  /// Get object -- constant version.
1082  ///
1083  /// Similar to GetNonNullPointer(), except that this method returns the
1084  /// object whereas GetNonNullPointer() returns a pointer to the object.
1085  ///
1086  /// @sa
1087  /// GetNonNullPointer()
1088  inline
1089  const TObjectType& GetObject(void) const
1090  {
1091  return *GetNonNullPointer();
1092  }
1093 
1094  /// Dereference operator returning object -- constant version.
1095  ///
1096  /// @sa
1097  /// GetObject()
1098  inline
1099  const TObjectType& operator*(void) const
1100  {
1101  return *GetNonNullPointer();
1102  }
1103 
1104  /// Reference operator -- constant version.
1105  ///
1106  /// @sa
1107  /// GetPointer()
1108  inline
1109  const TObjectType* operator->(void) const
1110  {
1111  return GetNonNullPointer();
1112  }
1113 
1114  /// Dereference operator returning pointer.
1115  ///
1116  /// @sa
1117  /// GetPointer()
1118  inline
1119  operator TObjectType*(void)
1120  {
1121  return GetPointerOrNull();
1122  }
1123 
1124  /// Dereference operator returning pointer -- constant version.
1125  ///
1126  /// @sa
1127  /// GetPointer()
1128  inline
1129  operator const TObjectType*(void) const
1130  {
1131  return GetPointerOrNull();
1132  }
1133 
1134  /// Get pointer value and throw a null pointer exception if pointer
1135  /// is null.
1136  ///
1137  /// Similar to GetPointerOrNull() except that this method throws a null
1138  /// pointer exception if pointer is null, whereas GetPointerOrNull()
1139  /// returns a null value.
1140  ///
1141  /// @sa
1142  /// GetPointerOrNull(), GetPointer(), GetObject()
1143  inline
1145  {
1146  TObjectType* ptr = m_Data.second();
1147  if ( !ptr ) {
1149  }
1150  return ptr;
1151  }
1152 
1153  /// Get pointer value.
1154  ///
1155  /// Similar to GetNonNullPointer() except that this method returns a null
1156  /// if the pointer is null, whereas GetNonNullPointer() throws a null
1157  /// pointer exception.
1158  ///
1159  /// @sa
1160  /// GetNonNullPointer()
1161  inline
1163  {
1164  return m_Data.second();
1165  }
1166 
1167  /// Get pointer,
1168  ///
1169  /// Same as GetPointerOrNull().
1170  ///
1171  /// @sa
1172  /// GetPointerOrNull()
1173  inline
1175  {
1176  return GetNCPointerOrNull();
1177  }
1178 
1179  /// Get object.
1180  ///
1181  /// Similar to GetNonNullPointer(), except that this method returns the
1182  /// object whereas GetNonNullPointer() returns a pointer to the object.
1183  ///
1184  /// @sa
1185  /// GetNonNullPointer()
1186  inline
1188  {
1189  return *GetNonNullNCPointer();
1190  }
1191 
1192 private:
1193  // lock after construction from ptr
1195  {
1196  if ( TObjectType* ptr = m_Data.second() ) {
1197  m_Data.first().Lock(ptr);
1198  }
1199  }
1200  // lock after construction from another ref
1202  {
1203  if ( TObjectType* ptr = m_Data.second() ) {
1204  m_Data.first().Relock(ptr);
1205  }
1206  }
1207  // lock after move construction from another ref
1208  void x_LockFromMoveConstructor(const Locker& src_locker)
1209  {
1210  if ( TObjectType* ptr = m_Data.second() ) {
1211  m_Data.first().TransferLock(ptr, src_locker);
1212  }
1213  }
1214  // assign from another ref
1216  {
1217  TObjectType* oldPtr = m_Data.second();
1218  if ( newPtr ) {
1219  m_Data.first().Relock(newPtr);
1220  }
1221  m_Data.second() = newPtr;
1222  if ( oldPtr ) {
1223  m_Data.first().Unlock(oldPtr);
1224  }
1225  }
1226  // move-assign from another ref
1227  void x_MoveAssign(const Locker& src_locker, TObjectType* newPtr)
1228  {
1229  TObjectType* oldPtr = m_Data.second();
1230  if ( newPtr ) {
1231  m_Data.first().TransferLock(newPtr, src_locker);
1232  }
1233  m_Data.second() = newPtr;
1234  if ( oldPtr ) {
1235  m_Data.first().Unlock(oldPtr);
1236  }
1237  }
1238 
1240  {
1241  // MIPSpro won't accept static_cast for some reason.
1242  return reinterpret_cast<TObjectType*>
1243  (SwapPointers(const_cast<void*volatile*>(
1244  reinterpret_cast<void**>(&m_Data.second())),
1245  ptr));
1246  }
1247 
1249 
1250 private:
1251 // Hide incorrect operators
1252  void operator-(TObjectType*) const;
1253  void operator-(int) const;
1254  void operator+(int) const;
1255 };
1256 
1257 
1258 /////////////////////////////////////////////////////////////////////////////
1259 ///
1260 /// CConstRef --
1261 ///
1262 /// Define a template class that stores a pointer to an object and defines
1263 /// methods for constant referencing of object.
1264 
1265 template<class C, class Locker>
1266 class CConstRef {
1267 public:
1268  typedef C element_type; ///< Define alias element_type
1269  typedef const element_type TObjectType; ///< Define alias TObjectType
1270  typedef Locker locker_type; ///< Define alias for locking type
1271  typedef CConstRef<C, Locker> TThisType; ///< Alias for this template type
1272 
1273  /// Helper template to template enable methods only for derived types
1274  template<class T>
1277  template<class TDerived, class TLocker> friend class CConstRef;
1278 
1279  /// Constructor for null pointer.
1280  inline
1282  {
1283  }
1284 
1285  /// Constructor for ENull pointer.
1286  inline
1288  {
1289  }
1290 
1291  /// Constructor for explicit type conversion from pointer to object.
1292  explicit CConstRef(TObjectType* ptr)
1293  : m_Data(locker_type(), ptr)
1294  {
1295  x_LockFromPtr();
1296  }
1297 
1298  /// Constructor for explicit type conversion from pointer to object.
1299  CConstRef(TObjectType* ptr, const locker_type& locker_value)
1300  : m_Data(locker_value, ptr)
1301  {
1302  x_LockFromPtr();
1303  }
1304 
1305  /// Constructor from an existing CConstRef object
1306  CConstRef(const TThisType& ref)
1307  : m_Data(ref.m_Data)
1308  {
1309  x_LockFromRef();
1310  }
1311 
1312  /// Constructor from an existing CConstRef object of derived type
1313  template<class TDerived,
1314  class = typename enable_if_derived<TDerived>::type>
1316  : m_Data(ref.GetLocker(), ref.GetPointerOrNull())
1317  {
1318  x_LockFromRef();
1319  }
1320 
1321  /// Move constructor from an existing CConstRef object
1323  : m_Data(ref.m_Data)
1324  {
1325  x_LockFromMoveConstructor(ref.m_Data.first());
1326  ref.m_Data.second() = 0;
1327  }
1328 
1329  /// Move constructor from an existing CConstRef object of derived type
1330  template<class TDerived,
1331  class = typename enable_if_derived<TDerived>::type>
1333  : m_Data(ref.GetLocker(), ref.GetPointerOrNull())
1334  {
1335  x_LockFromMoveConstructor(ref.m_Data.first());
1336  ref.m_Data.second() = 0;
1337  }
1338 
1339  /// Constructor from an existing CRef object of derived type
1340  template<class TDerived,
1341  class = typename enable_if_derived<TDerived>::type>
1343  : m_Data(ref.GetLocker(), ref.GetPointerOrNull())
1344  {
1345  x_LockFromRef();
1346  }
1347 
1348  /// Move constructor from an existing CRef object of derived type
1349  template<class TDerived,
1350  class = typename enable_if_derived<TDerived>::type>
1352  : m_Data(ref.GetLocker(), ref.GetPointerOrNull())
1353  {
1354  x_LockFromMoveConstructor(ref.m_Data.first());
1355  ref.m_Data.second() = 0;
1356  }
1357 
1358  /// Destructor.
1360  {
1361  Reset();
1362  }
1363 
1364  /// Get reference to locker object
1365  const locker_type& GetLocker(void) const
1366  {
1367  return m_Data.first();
1368  }
1369 
1370  /// Check if CConstRef is empty -- not pointing to any object, which means
1371  /// having a null value.
1372  ///
1373  /// @sa
1374  /// Empty(), IsNull()
1375  bool operator!(void) const THROWS_NONE
1376  {
1377  return m_Data.second() == 0;
1378  }
1379 
1380  /// Check if CConstRef is empty -- not pointing to any object which means
1381  /// having a null value.
1382  ///
1383  /// @sa
1384  /// IsNull(), operator!()
1385  bool Empty(void) const THROWS_NONE
1386  {
1387  return m_Data.second() == 0;
1388  }
1389 
1390  /// Check if CConstRef is not empty -- pointing to an object and has
1391  /// a non-null value.
1392  bool NotEmpty(void) const THROWS_NONE
1393  {
1394  return m_Data.second() != 0;
1395  }
1396 
1397  /// Check if pointer is null -- same effect as Empty().
1398  ///
1399  /// @sa
1400  /// Empty(), operator!()
1401  bool IsNull(void) const THROWS_NONE
1402  {
1403  return m_Data.second() == 0;
1404  }
1405 
1406  /// Check if pointer is not null -- same effect as NotEmpty().
1407  ///
1408  /// @sa
1409  /// NotEmpty()
1410  bool NotNull(void) const THROWS_NONE
1411  {
1412  return m_Data.second() != 0;
1413  }
1414 
1415  /// Swaps the pointer with another reference
1416  ///
1417  /// @sa
1418  /// Swap(ConstRef<>&)
1419  inline
1420  void Swap(TThisType& ref)
1421  {
1422  swap(m_Data, ref.m_Data);
1423  if ( TObjectType* ptr = m_Data.second() ) {
1424  m_Data.first().TransferLock(ptr, ref.m_Data.first());
1425  }
1426  if ( TObjectType* ptr = ref.m_Data.second() ) {
1427  ref.m_Data.first().TransferLock(ptr, m_Data.first());
1428  }
1429  }
1430 
1431  /// Reset reference object.
1432  ///
1433  /// This sets the pointer to object to null, and removes reference
1434  /// count to object and deletes the object if this is the last reference
1435  /// to the object.
1436  /// @sa
1437  /// Reset(TObjectType*)
1438  inline
1439  void Reset(void)
1440  {
1441  TObjectType* ptr = m_Data.second();
1442  if ( ptr ) {
1443  m_Data.second() = 0;
1444  m_Data.first().Unlock(ptr);
1445  }
1446  }
1447 
1448  /// Reset reference object to new pointer.
1449  ///
1450  /// This sets the pointer to object to the new pointer, and removes
1451  /// reference count to old object and deletes the old object if this is
1452  /// the last reference to the old object.
1453  /// @sa
1454  /// Reset()
1455  inline
1456  void Reset(TObjectType* newPtr)
1457  {
1458  TObjectType* oldPtr = m_Data.second();
1459  if ( newPtr != oldPtr ) {
1460  if ( newPtr ) {
1461  m_Data.first().Lock(newPtr);
1462  }
1463  m_Data.second() = newPtr;
1464  if ( oldPtr ) {
1465  m_Data.first().Unlock(oldPtr);
1466  }
1467  }
1468  }
1469 
1470  /// Release a reference to the object and return a pointer to the object.
1471  ///
1472  /// Releasing a reference means decreasing the reference count by "1". A
1473  /// pointer to the existing object is returned, unless this pointer is
1474  /// already null(0), in which case a null(0) is returned.
1475  ///
1476  /// Similar to Release(), except that this method returns a null,
1477  /// whereas Release() throws a null pointer exception.
1478  ///
1479  /// @sa
1480  /// Release()
1481  inline
1483  {
1484  TObjectType* ptr = m_Data.second();
1485  if ( !ptr ) {
1486  return 0;
1487  }
1488  m_Data.second() = 0;
1489  m_Data.first().UnlockRelease(ptr);
1490  return ptr;
1491  }
1492 
1493  NCBI_NORETURN
1494  static void ThrowNullPointerException(void)
1495  {
1496  CObject::ThrowNullPointerException(/*typeid(TObjectType*)*/);
1497  }
1498 
1499  /// Release a reference to the object and return a pointer to the object.
1500  ///
1501  /// Releasing a reference means decreasing the reference count by "1". A
1502  /// pointer to the existing object is returned, unless this pointer is
1503  /// already null(0), in which the null pointer exception (eNullPtr) is
1504  /// thrown.
1505  ///
1506  /// Similar to ReleaseOrNull(), except that this method throws an exception
1507  /// whereas ReleaseOrNull() does not.
1508  ///
1509  /// @sa
1510  /// ReleaseOrNull()
1511  inline
1513  {
1514  TObjectType* ptr = m_Data.second();
1515  if ( !ptr ) {
1517  }
1518  m_Data.second() = 0;
1519  m_Data.first().UnlockRelease(ptr);
1520  return ptr;
1521  }
1522 
1523  /// Reset reference object to new pointer.
1524  ///
1525  /// This sets the pointer to object to the new pointer, and removes
1526  /// reference count to old object and deletes the old object if this is
1527  /// the last reference to the old object.
1528  /// The new pointer is got from ref argument.
1529  /// Operation is atomic on this object, so that AtomicResetFrom() and
1530  /// AtomicReleaseTo() called from different threads will work properly.
1531  /// Operation is not atomic on ref argument.
1532  /// @sa
1533  /// AtomicReleaseTo(CConstRef& ref);
1534  inline
1535  void AtomicResetFrom(const CConstRef& ref)
1536  {
1537  TObjectType* ptr = ref.m_Data.second();
1538  if ( ptr )
1539  m_Data.first().Lock(ptr); // for this
1540  TObjectType* old_ptr = AtomicSwap(ptr);
1541  if ( old_ptr )
1542  m_Data.first().Unlock(old_ptr);
1543  }
1544  /// Release referenced object to another CConstRef<> object.
1545  ///
1546  /// This copies the pointer to object to the argument ref,
1547  /// and release reference from this object.
1548  /// Old reference object held by argument ref is released and deleted if
1549  /// necessary.
1550  /// Operation is atomic on this object, so that AtomicResetFrom() and
1551  /// AtomicReleaseTo() called from different threads will work properly.
1552  /// Operation is not atomic on ref argument.
1553  /// @sa
1554  /// AtomicResetFrom(const CConstRef& ref);
1555  inline
1557  {
1558  TObjectType* old_ptr = AtomicSwap(0);
1559  if ( old_ptr ) {
1560  ref.Reset(old_ptr);
1561  m_Data.first().Unlock(old_ptr);
1562  }
1563  else {
1564  ref.Reset();
1565  }
1566  }
1567 
1568  /// Assignment operator for const references.
1570  {
1571  x_AssignFromRef(ref.m_Data.second());
1572  return *this;
1573  }
1574 
1575  /// Assignment operator for const references of derived types
1576  template<class TDerived,
1577  class = typename enable_if_derived<TDerived>::type>
1579  {
1580  // we cannot use internals of CRef of derived type
1581  x_AssignFromRef(ref.m_Data.second());
1582  return *this;
1583  }
1584 
1585  /// Move assignment operator for const references.
1587  {
1588 #ifdef NCBI_COMPILER_MSVC
1589  // extra check on MSVC
1590  if (this == &ref) {
1591  // no-op
1592  return *this;
1593  }
1594 #endif
1595  x_MoveAssign(ref.m_Data.first(), ref.m_Data.second());
1596  ref.m_Data.second() = 0;
1597  return *this;
1598  }
1599 
1600  /// Move assignment operator for const references of derived types
1601  template<class TDerived,
1602  class = typename enable_if_derived<TDerived>::type>
1604  {
1605  x_MoveAssign(ref.m_Data.first(), ref.m_Data.second());
1606  ref.m_Data.second() = 0;
1607  return *this;
1608  }
1609 
1610  /// Assignment operator for assigning a reference of derived type
1611  template<class TDerived,
1612  class = typename enable_if_derived<TDerived>::type>
1614  {
1615  x_AssignFromRef(ref.m_Data.second());
1616  return *this;
1617  }
1618 
1619  /// Move assignment operator for assigning a reference of derived type
1620  template<class TDerived,
1621  class = typename enable_if_derived<TDerived>::type>
1623  {
1624  x_MoveAssign(ref.m_Data.first(), ref.m_Data.second());
1625  ref.m_Data.second() = 0;
1626  return *this;
1627  }
1628 
1629  /// Assignment operator for const references with right hand side set to
1630  /// a pointer.
1632  {
1633  Reset(ptr);
1634  return *this;
1635  }
1636 
1637  /// Assignment operator with right hand side set to ENull.
1639  {
1640  Reset();
1641  return *this;
1642  }
1643 
1644  /// Get pointer value and throw a null pointer exception if pointer
1645  /// is null.
1646  ///
1647  /// Similar to GetPointerOrNull() except that this method throws a null
1648  /// pointer exception if pointer is null, whereas GetPointerOrNull()
1649  /// returns a null value.
1650  ///
1651  /// @sa
1652  /// GetPointerOrNull(), GetPointer(), GetObject()
1653  inline
1655  {
1656  TObjectType* ptr = m_Data.second();
1657  if ( !ptr ) {
1659  }
1660  return ptr;
1661  }
1662 
1663  /// Get pointer value.
1664  ///
1665  /// Similar to GetNonNullPointer() except that this method returns a null
1666  /// if the pointer is null, whereas GetNonNullPointer() throws a null
1667  /// pointer exception.
1668  ///
1669  /// @sa
1670  /// GetNonNullPointer()
1671  inline
1673  {
1674  return m_Data.second();
1675  }
1676 
1677  /// Get pointer,
1678  ///
1679  /// Same as GetPointerOrNull().
1680  ///
1681  /// @sa
1682  /// GetPointerOrNull()
1683  inline
1685  {
1686  return GetPointerOrNull();
1687  }
1688 
1689  /// Get object.
1690  ///
1691  /// Similar to GetNonNullPointer(), except that this method returns the
1692  /// object whereas GetNonNullPointer() returns a pointer to the object.
1693  ///
1694  /// @sa
1695  /// GetNonNullPointer()
1696  inline
1697  TObjectType& GetObject(void) const
1698  {
1699  return *GetNonNullPointer();
1700  }
1701 
1702  /// Dereference operator returning object.
1703  ///
1704  /// @sa
1705  /// GetObject()
1706  inline
1707  TObjectType& operator*(void) const
1708  {
1709  return *GetNonNullPointer();
1710  }
1711 
1712  /// Reference operator.
1713  ///
1714  /// @sa
1715  /// GetPointer()
1716  inline
1718  {
1719  return GetNonNullPointer();
1720  }
1721 
1722  /// Dereference operator returning pointer.
1723  ///
1724  /// @sa
1725  /// GetPointer()
1726  inline
1727  operator TObjectType*(void) const
1728  {
1729  return GetPointerOrNull();
1730  }
1731 
1732 private:
1733  // lock after construction from ptr
1735  {
1736  if ( TObjectType* ptr = m_Data.second() ) {
1737  m_Data.first().Lock(ptr);
1738  }
1739  }
1740  // lock after construction from another ref
1742  {
1743  if ( TObjectType* ptr = m_Data.second() ) {
1744  m_Data.first().Relock(ptr);
1745  }
1746  }
1747  // lock after move construction from another ref
1748  void x_LockFromMoveConstructor(const Locker& src_locker)
1749  {
1750  if ( TObjectType* ptr = m_Data.second() ) {
1751  m_Data.first().TransferLock(ptr, src_locker);
1752  }
1753  }
1754  // assign from another ref
1756  {
1757  TObjectType* oldPtr = m_Data.second();
1758  if ( newPtr ) {
1759  m_Data.first().Relock(newPtr);
1760  }
1761  m_Data.second() = newPtr;
1762  if ( oldPtr ) {
1763  m_Data.first().Unlock(oldPtr);
1764  }
1765  }
1766  // move-assign from another ref
1767  void x_MoveAssign(const Locker& src_locker, TObjectType* newPtr)
1768  {
1769  TObjectType* oldPtr = m_Data.second();
1770  if ( newPtr ) {
1771  m_Data.first().TransferLock(newPtr, src_locker);
1772  }
1773  m_Data.second() = newPtr;
1774  if ( oldPtr ) {
1775  m_Data.first().Unlock(oldPtr);
1776  }
1777  }
1778 
1780  {
1781  // MIPSpro won't accept static_cast for some reason.
1782  return reinterpret_cast<TObjectType*>
1783  (SwapPointers(const_cast<void*volatile*>(
1784  const_cast<void**>(
1785  reinterpret_cast<const void**>(&m_Data.second()))),
1786  const_cast<C*>(ptr)));
1787  }
1788 
1790 
1791 private:
1792 // Hide incorrect operators
1793  void operator-(TObjectType*) const;
1794  void operator-(int) const;
1795  void operator+(int) const;
1796 };
1797 
1798 
1799 /////////////////////////////////////////////////////////////////////////////
1800 /// Comparison operators for CRef<> and CConstRef<> with ENull
1801 
1802 /// Template operator == function for CRef objects -- rhs is null.
1803 template<class T, class L>
1804 inline
1805 bool operator== (const CRef<T,L>& r1, ENull /*null*/)
1806 {
1807  return r1.IsNull();
1808 }
1809 
1810 /// Template operator == function for CRef objects -- lhs is null.
1811 template<class T, class L>
1812 inline
1813 bool operator== (ENull /*null*/, const CRef<T,L>& r1)
1814 {
1815  return r1.IsNull();
1816 }
1817 
1818 /// Template operator != function for CRef objects -- rhs is null.
1819 template<class T, class L>
1820 inline
1821 bool operator!= (const CRef<T,L>& r1, ENull /*null*/)
1822 {
1823  return !r1.IsNull();
1824 }
1825 
1826 /// Template operator != function for CRef objects -- lhs is null.
1827 template<class T, class L>
1828 inline
1829 bool operator!= (ENull /*null*/, const CRef<T,L>& r1)
1830 {
1831  return !r1.IsNull();
1832 }
1833 
1834 /// Template operator == function for CConstRef objects -- rhs is null.
1835 template<class T, class L>
1836 inline
1837 bool operator== (const CConstRef<T,L>& r1, ENull /*null*/)
1838 {
1839  return r1.IsNull();
1840 }
1841 
1842 /// Template operator == function for CConstRef objects -- lhs is null.
1843 template<class T, class L>
1844 inline
1845 bool operator== (ENull /*null*/, const CConstRef<T,L>& r1)
1846 {
1847  return r1.IsNull();
1848 }
1849 
1850 /// Template operator != function for CConstRef objects -- rhs is null.
1851 template<class T, class L>
1852 inline
1853 bool operator!= (const CConstRef<T,L>& r1, ENull /*null*/)
1854 {
1855  return !r1.IsNull();
1856 }
1857 
1858 /// Template operator != function for CConstRef objects -- lhs is null.
1859 template<class T, class L>
1860 inline
1861 bool operator!= (ENull /*null*/, const CConstRef<T,L>& r1)
1862 {
1863  return !r1.IsNull();
1864 }
1865 
1866 
1867 #if defined(NCBI_COMPILER_WORKSHOP)
1868 /// WorkShop fails to compare CRef/CConstRef via operator pointer sometimes.
1869 /////////////////////////////////////////////////////////////////////////////
1870 /// Comparison operators for CRef<>
1871 
1872 /// Template operator < function for CRef objects.
1873 template<class T, class L>
1874 inline
1875 bool operator< (const CRef<T,L>& r1, const CRef<T,L>& r2)
1876 {
1877  return r1.GetPointerOrNull() < r2.GetPointerOrNull();
1878 }
1879 
1880 /// Template operator > function for CRef objects.
1881 template<class T, class L>
1882 inline
1883 bool operator> (const CRef<T,L>& r1, const CRef<T,L>& r2)
1884 {
1885  return r1.GetPointerOrNull() > r2.GetPointerOrNull();
1886 }
1887 
1888 /// Template operator < function for CRef objects.
1889 template<class T, class L>
1890 inline
1891 bool operator<= (const CRef<T,L>& r1, const CRef<T,L>& r2)
1892 {
1893  return r1.GetPointerOrNull() <= r2.GetPointerOrNull();
1894 }
1895 
1896 /// Template operator > function for CRef objects.
1897 template<class T, class L>
1898 inline
1899 bool operator>= (const CRef<T,L>& r1, const CRef<T,L>& r2)
1900 {
1901  return r1.GetPointerOrNull() >= r2.GetPointerOrNull();
1902 }
1903 
1904 /// Template operator == function for CRef objects.
1905 template<class T, class L>
1906 inline
1907 bool operator== (const CRef<T,L>& r1, const CRef<T,L>& r2)
1908 {
1909  return r1.GetPointerOrNull() == r2.GetPointerOrNull();
1910 }
1911 
1912 /// Template operator == function for CRef and CRef objects.
1913 template<class T, class L>
1914 inline
1915 bool operator!= (const CRef<T,L>& r1, const CRef<T,L>& r2)
1916 {
1917  return r1.GetPointerOrNull() != r2.GetPointerOrNull();
1918 }
1919 
1920 /////////////////////////////////////////////////////////////////////////////
1921 /// Comparison operators for CConstRef<>
1922 
1923 /// Template operator < function for CConstRef objects.
1924 template<class T, class L>
1925 inline
1926 bool operator< (const CConstRef<T,L>& r1, const CConstRef<T,L>& r2)
1927 {
1928  return r1.GetPointerOrNull() < r2.GetPointerOrNull();
1929 }
1930 
1931 /// Template operator > function for CConstRef objects.
1932 template<class T, class L>
1933 inline
1934 bool operator> (const CConstRef<T,L>& r1, const CConstRef<T,L>& r2)
1935 {
1936  return r1.GetPointerOrNull() > r2.GetPointerOrNull();
1937 }
1938 
1939 /// Template operator < function for CConstRef objects.
1940 template<class T, class L>
1941 inline
1942 bool operator<= (const CConstRef<T,L>& r1, const CConstRef<T,L>& r2)
1943 {
1944  return r1.GetPointerOrNull() <= r2.GetPointerOrNull();
1945 }
1946 
1947 /// Template operator > function for CConstRef objects.
1948 template<class T, class L>
1949 inline
1950 bool operator>= (const CConstRef<T,L>& r1, const CConstRef<T,L>& r2)
1951 {
1952  return r1.GetPointerOrNull() >= r2.GetPointerOrNull();
1953 }
1954 
1955 /// Template operator == function for CConstRef objects.
1956 template<class T, class L>
1957 inline
1958 bool operator== (const CConstRef<T,L>& r1, const CConstRef<T,L>& r2)
1959 {
1960  return r1.GetPointerOrNull() == r2.GetPointerOrNull();
1961 }
1962 
1963 /// Template operator != function for CConstRef objects.
1964 template<class T, class L>
1965 inline
1966 bool operator!= (const CConstRef<T,L>& r1, const CConstRef<T,L>& r2)
1967 {
1968  return r1.GetPointerOrNull() != r2.GetPointerOrNull();
1969 }
1970 
1971 
1972 /////////////////////////////////////////////////////////////////////////////
1973 /// Mixed comparison operators
1974 
1975 /// Template operator == function for CConstRef and CRef objects.
1976 template<class T, class L>
1977 inline
1978 bool operator== (const CConstRef<T,L>& r1, const CRef<T,L>& r2)
1979 {
1980  return r1.GetPointerOrNull() == r2.GetPointerOrNull();
1981 }
1982 
1983 /// Template operator == function for CRef and CConstRef objects.
1984 template<class T, class L>
1985 inline
1986 bool operator== (const CRef<T,L>& r1, const CConstRef<T,L>& r2)
1987 {
1988  return r1.GetPointerOrNull() == r2.GetPointerOrNull();
1989 }
1990 
1991 /// Template operator != function for CConstRef and CRef objects.
1992 template<class T, class L>
1993 inline
1994 bool operator!= (const CConstRef<T,L>& r1, const CRef<T,L>& r2)
1995 {
1996  return r1.GetPointerOrNull() != r2.GetPointerOrNull();
1997 }
1998 
1999 /// Template operator != function for CRef and CConstRef objects.
2000 template<class T, class L>
2001 inline
2002 bool operator!= (const CRef<T,L>& r1, const CConstRef<T,L>& r2)
2003 {
2004  return r1.GetPointerOrNull() != r2.GetPointerOrNull();
2005 }
2006 #endif
2007 
2008 
2009 /////////////////////////////////////////////////////////////////////////////
2010 /// Helper functions to get CRef<> and CConstRef<> objects
2011 
2012 /// Template function for conversion of object pointer to CRef
2013 template<class C>
2014 inline
2015 CRef<C> Ref(C* object)
2016 {
2017  return CRef<C>(object);
2018 }
2019 
2020 
2021 /// Template function for conversion of const object pointer to CConstRef
2022 template<class C>
2023 inline
2024 CConstRef<C> ConstRef(const C* object)
2025 {
2026  return CConstRef<C>(object);
2027 }
2028 
2029 
2030 
2031 template<class Interface, class Locker = CInterfaceObjectLocker<Interface> >
2032 class CIRef : public CRef<Interface, Locker>
2033 {
2035 public:
2039 
2040  /// Helper template to template enable methods only for derived types
2041  template<class T>
2044 
2045  // We have to redefine all constructors and assignment operators
2046 
2047  /// Constructor for null pointer.
2049  {
2050  }
2051 
2052  /// Constructor for ENull pointer.
2054  {
2055  }
2056 
2057  /// Constructor for explicit type conversion from pointer to object.
2058  explicit CIRef(TObjectType* ptr)
2059  : TParent(ptr)
2060  {
2061  }
2062 
2063  /// Constructor from existing ref
2064  CIRef(const TThisType& ref)
2065  : TParent(ref)
2066  {
2067  }
2068 
2069  /// Constructor from existing ref of derived type
2070  template<class TDerived,
2071  class = typename enable_if_derived<TDerived>::type>
2073  : TParent(ref.GetNCPointerOrNull())
2074  {
2075  }
2076 
2077  /// Move constructor from existing ref
2079  : TParent(static_cast<TParent&&>(ref))
2080  {
2081  }
2082 
2083  /// Move constructor from existing ref of derived type
2084  template<class TDerived,
2085  class = typename enable_if_derived<TDerived>::type>
2087  : TParent(ref.GetPointerOrNull())
2088  {
2089  ref.ReleaseOrNull();
2090  }
2091 
2092  /// Constructor for explicit type conversion from pointer to object.
2093  CIRef(TObjectType* ptr, const locker_type& locker_value)
2094  : TParent(ptr, locker_value)
2095  {
2096  }
2097 
2098  /// Assignment operator for references.
2100  {
2101  TParent::operator=(ref);
2102  return *this;
2103  }
2104 
2105  /// Assignment operator for references of derived types
2106  template<class TDerived,
2107  class = typename enable_if_derived<TDerived>::type>
2109  {
2111  return *this;
2112  }
2113 
2114  /// Move assignment operator for references.
2116  {
2117  TParent::operator=(static_cast<TParent&&>(ref));
2118  return *this;
2119  }
2120 
2121  /// Move assignment operator for references of derived types
2122  template<class TDerived,
2123  class = typename enable_if_derived<TDerived>::type>
2125  {
2126  TParent::operator=(ref.GetNCPointerOrNull());
2127  ref.ReleaseOrNull();
2128  return *this;
2129  }
2130 
2131  /// Assignment operator for references with right hand side set to
2132  /// a pointer.
2134  {
2135  TParent::operator=(ptr);
2136  return *this;
2137  }
2138 
2139  /// Assignment operator with right hand side set to ENull.
2141  {
2142  TParent::operator=(null);
2143  return *this;
2144  }
2145 
2146  /// Swaps the pointer with another reference
2147  ///
2148  /// @sa
2149  /// Swap(CRef<>&)
2150  void Swap(TThisType& ref)
2151  {
2152  TParent::Swap(ref);
2153  }
2154 };
2155 
2156 
2157 template<class Interface, class Locker = CInterfaceObjectLocker<Interface> >
2158 class CConstIRef : public CConstRef<Interface, Locker>
2159 {
2161 public:
2165 
2166  /// Helper template to template enable methods only for derived types
2167  template<class T>
2170 
2171  // We have to redefine all constructors and assignment operators
2172 
2173  /// Constructor for null pointer.
2175  {
2176  }
2177 
2178  /// Constructor for ENull pointer.
2180  {
2181  }
2182 
2183  /// Constructor for explicit type conversion from pointer to object.
2184  explicit CConstIRef(TObjectType* ptr)
2185  : TParent(ptr)
2186  {
2187  }
2188 
2189  /// Constructor for explicit type conversion from pointer to object.
2190  CConstIRef(TObjectType* ptr, const locker_type& locker_value)
2191  : TParent(ptr, locker_value)
2192  {
2193  }
2194 
2195  /// Constructor from an existing CConstRef object
2196  CConstIRef(const TThisType& ref)
2197  : TParent(ref)
2198  {
2199  }
2200 
2201  /// Constructor from an existing CConstRef object of derived type
2202  template<class TDerived,
2203  class = typename enable_if_derived<TDerived>::type>
2205  : TParent(ref.GetPointerOrNull())
2206  {
2207  }
2208 
2209  /// Move constructor from an existing CConstRef object
2211  : TParent(static_cast<TParent&&>(ref))
2212  {
2213  }
2214 
2215  /// Move constructor from an existing CConstRef object of derived type
2216  template<class TDerived,
2217  class = typename enable_if_derived<TDerived>::type>
2219  : TParent(ref.GetPointerOrNull())
2220  {
2221  ref.ReleaseOrNull();
2222  }
2223 
2224  /// Constructor from an existing CRef object of derived type
2225  template<class TDerived,
2226  class = typename enable_if_derived<TDerived>::type>
2228  : TParent(ref.GetPointerOrNull())
2229  {
2230  }
2231 
2232  /// Move constructor from an existing CRef object of derived type
2233  template<class TDerived,
2234  class = typename enable_if_derived<TDerived>::type>
2236  : TParent(ref.GetPointerOrNull())
2237  {
2238  ref.ReleaseOrNull();
2239  }
2240 
2241  /// Assignment operator for references.
2243  {
2244  TParent::operator=(ref);
2245  return *this;
2246  }
2247 
2248  /// Assignment operator for references of derived types
2249  template<class TDerived,
2250  class = typename enable_if_derived<TDerived>::type>
2252  {
2254  return *this;
2255  }
2256 
2257  /// Move assignment operator for references.
2259  {
2260  TParent::operator=(static_cast<TParent&&>(ref));
2261  return *this;
2262  }
2263 
2264  /// Move assignment operator for references of derived types
2265  template<class TDerived,
2266  class = typename enable_if_derived<TDerived>::type>
2268  {
2269  TParent::operator=(ref.GetPointerOrNull());
2270  ref.ReleaseOrNull();
2271  return *this;
2272  }
2273 
2274  /// Assignment operator for assigning a reference to a const reference.
2275  template<class TDerived,
2276  class = typename enable_if_derived<TDerived>::type>
2278  {
2280  return *this;
2281  }
2282 
2283  /// Move assignment operator for assigning a reference to a const reference.
2284  template<class TDerived,
2285  class = typename enable_if_derived<TDerived>::type>
2287  {
2288  TParent::operator=(ref.GetPointerOrNull());
2289  ref.ReleaseOrNull();
2290  return *this;
2291  }
2292 
2293  /// Assignment operator for references with right hand side set to
2294  /// a pointer.
2296  {
2297  TParent::operator=(ptr);
2298  return *this;
2299  }
2300 
2301  /// Assignment operator with right hand side set to ENull.
2303  {
2304  TParent::operator=(null);
2305  return *this;
2306  }
2307 
2308  /// Swaps the pointer with another reference
2309  ///
2310  /// @sa
2311  /// Swap(CRef<>&)
2312  void Swap(TThisType& ref)
2313  {
2314  TParent::Swap(ref);
2315  }
2316 };
2317 
2318 
2319 /////////////////////////////////////////////////////////////////////////////
2320 ///
2321 /// CObjectFor --
2322 ///
2323 /// Define a template class whose template parameter is a standard data type
2324 /// that will be pointed to.
2325 ///
2326 /// The template class defines a private data member of the same type as the
2327 /// template parameter, and accessor methods GetData() to retrieve the value
2328 /// of this private data member. The class is derived from CObject and
2329 /// therefore inherits the reference counter defined in that class. In essence,
2330 /// this class serves as a "wrapper" class for standard data types allowing
2331 /// reference counted smart pointers to be used for standard data types.
2332 
2333 template<typename T>
2334 class CObjectFor : public CObject
2335 {
2336 public:
2337  typedef T TObjectType; ///< Define alias for template parameter
2338 
2339  template<class... Args>
2340  explicit CObjectFor(Args&&... args)
2341  : m_Data(std::forward<Args>(args)...)
2342  {
2343  }
2344 
2345  /// Get data as a reference.
2346  T& GetData(void)
2347  {
2348  return m_Data;
2349  }
2350 
2351  /// Get data as a reference -- const version.
2352  const T& GetData(void) const
2353  {
2354  return m_Data;
2355  }
2356 
2357  /// Operator () to get data -- same as GetData().
2358  ///
2359  /// @sa
2360  /// GetData()
2361  operator T& (void)
2362  {
2363  return GetData();
2364  }
2365 
2366  /// Operator () to get data -- const version, same as GetData().
2367  ///
2368  /// @sa
2369  /// GetData()
2370  operator const T& (void) const
2371  {
2372  return GetData();
2373  }
2374 
2375  /// Assignment operator.
2376  T& operator=(const T& data)
2377  {
2378  m_Data = data;
2379  return *this;
2380  }
2381 
2382 private:
2383  T m_Data; ///< Data member of template parameter type
2384 };
2385 
2386 
2387 // Forward declaration for CPtrToObjectProxy
2388 class CWeakObject;
2389 
2390 /////////////////////////////////////////////////////////////////////////////
2391 ///
2392 /// CPtrToObjectProxy --
2393 ///
2394 /// Proxy class used for building CWeakObject and CWeakPtr.
2395 ///
2396 /// Contains pointers to both CObject and CWeakObject instances.
2397 /// The pointers are set to NULL after the instances are destroyed.
2398 
2400 {
2401 public:
2403 
2405  ~CPtrToObjectProxy(void);
2406 
2407  /// Set pointer to NULL from object's destructor.
2408  void Clear(void);
2409 
2410  /// Lock the object and return pointer to it.
2411  /// If object is already destroyed then return NULL.
2413  CObject* GetLockedObject(void);
2414 
2415  /// Report about trying to convert incompatible interface fo CObject
2416  NCBI_NORETURN NCBI_XNCBI_EXPORT
2417  static void ReportIncompatibleType(const type_info& type);
2418 
2419 private:
2422 
2423 private:
2424  friend class CWeakObject;
2425  CObject* x_UpdateCObjectPtr(void);
2426 };
2427 
2428 
2429 
2430 
2431 /////////////////////////////////////////////////////////////////////////////
2432 ///
2433 /// CWeakObject --
2434 ///
2435 /// The class contains additional information to allow weak references to it.
2436 ///
2437 /// Note: If you want to have your class weak referenced you should derive
2438 /// from both CObject and CWeakObject.
2439 ///
2440 /// @sa CWeakRef<>
2441 
2443 {
2444 public:
2446  CWeakObject(void);
2447 
2449  virtual ~CWeakObject(void);
2450 
2451  /// Get pointer to proxy object containing pointer to this object
2452  CPtrToObjectProxy* GetPtrProxy(void) const;
2453 
2454 protected:
2455  /// Method cleaning all CWeakRefs referencing at this moment to the object
2456  /// After calling to this method all existing CWeakRefs referencing to the
2457  /// object will return NULL, so it effectively will be equal to deleting
2458  /// the object. This method should be called from DeleteThis() if it is
2459  /// overridden, if it does not actually deletes the object and if you want
2460  /// it to behave the same way as default DeleteThis() does in relation to
2461  /// CWeakRefs.
2463  void CleanWeakRefs(void) const;
2464 
2465 private:
2466  /// Add reference to the object in "weak" manner.
2467  /// If reference was added successfully returns TRUE.
2468  /// If the object is already destroying then returns FALSE.
2469  bool x_AddWeakReference(CObject* obj);
2470 
2471  friend class CPtrToObjectProxy;
2472 
2473  /// Proxy object with pointer to this instance
2475 };
2476 
2477 
2478 
2479 ////////////////////////////////////////////////////////////////////////////
2480 // CPtrToObjectProxy and CWeakObject inline methods
2481 ////////////////////////////////////////////////////////////////////////////
2482 
2483 
2484 inline
2486 {
2487  // Race condition is legal here. The worst that can happen is
2488  // that dynamic_cast<> can be called more than once.
2489  if ( !m_Ptr ) {
2490  m_Ptr = dynamic_cast<CObject*>(m_WeakPtr);
2491  if ( !m_Ptr )
2493  }
2494  return m_Ptr;
2495 }
2496 
2497 
2498 inline
2500 {
2501  // The x_UpdateCObjectPtr() member will check that the object derives from
2502  // CObject.
2503  CObject* object_ptr = m_SelfPtrProxy->x_UpdateCObjectPtr();
2504 
2505  // This tests that the object is controlled by CRef.
2506  if ( !object_ptr->Referenced() ) {
2507  NCBI_THROW(CObjectException, eNoRef,
2508  "Weak referenced object must be managed by CRef");
2509  }
2510  return m_SelfPtrProxy.GetNCPointer();
2511 }
2512 
2513 
2514 /////////////////////////////////////////////////////////////////////////////
2515 ///
2516 /// CObjectEx --
2517 ///
2518 /// The extended CObject class not only counting references to it but
2519 /// containing additional information to allow weak references to it.
2520 ///
2521 /// NOTE: If your class is derived from CObjectEx, you override DeleteThis()
2522 /// method, you do not actually delete the object in your implementation
2523 /// of DeleteThis() and you do not want all existing CWeakRefs to
2524 /// reference to this object any longer then you must call method
2525 /// CleanWeakRefs().
2526 ///
2527 /// @sa CWeakRef<>
2528 
2529 class CObjectEx : public CObject,
2530  public CWeakObject
2531 {
2532 public:
2534  {
2535  }
2536 
2538  virtual ~CObjectEx(void);
2539 };
2540 
2541 /////////////////////////////////////////////////////////////////////////////
2542 ///
2543 /// CWeakObjectLocker --
2544 ///
2545 /// Default locker class for CWeakRef template
2546 
2547 template <class C>
2549 {
2550 public:
2551  /// Type working as proxy storage for pointer to object
2553  /// Alias for this type
2555 
2556  /// Get proxy storage for pointer to object
2557  TPtrProxyType* GetPtrProxy(C* object) const
2558  {
2559  return object->GetPtrProxy();
2560  }
2561 
2562  /// Lock the object and return pointer to it stored in the proxy.
2563  /// If object is already destroyed then return NULL CRef.
2565  {
2566  CRef<C, TThisType> ref;
2567  if ( CObject* object = proxy->GetLockedObject() ) {
2568  ref.Reset(static_cast<C*>(object));
2569  object->RemoveReference(); // remove extra lock from GetLockedObject()
2570  }
2571  return ref;
2572  }
2573 };
2574 
2575 
2576 /////////////////////////////////////////////////////////////////////////////
2577 ///
2578 /// CWeakInterfaceLocker --
2579 ///
2580 /// Default locker class for CWeakIRef template
2581 
2582 template <class Interface>
2584 {
2585 public:
2586  /// Type working as proxy storage for pointer to object
2588  /// Alias for this type
2590 
2591  /// Get proxy storage for pointer to object
2592  TPtrProxyType* GetPtrProxy(Interface* ptr) const
2593  {
2594  CWeakObject* object = dynamic_cast<CWeakObject*>(ptr);
2595  if (!object) {
2597  }
2598  return object->GetPtrProxy();
2599  }
2600 
2601  /// Lock the object and return pointer to it stored in the proxy.
2602  /// If object is already destroyed then return NULL.
2604  {
2605  // We are not checking that result of dynamic_cast is not null
2606  // because type compatibility is already checked in GetPtrProxy()
2607  // which always called first. Now we can be sure that this
2608  // cast will not return null.
2610  if ( CObject* object = proxy->GetLockedObject() ) {
2611  ref.Reset(dynamic_cast<Interface*>(object));
2612  object->RemoveReference(); // remove extra lock from GetLockedObject()
2613  }
2614  return ref;
2615  }
2616 };
2617 
2618 
2619 /////////////////////////////////////////////////////////////////////////////
2620 // Traits for default locker parameter in CWeakRef
2621 /////////////////////////////////////////////////////////////////////////////
2622 
2623 template <class C>
2625 {
2626 public:
2628 };
2629 
2630 template<class Interface, class Locker>
2631 class CWeakIRef;
2632 
2633 
2634 /////////////////////////////////////////////////////////////////////////////
2635 ///
2636 /// CWeakRef --
2637 ///
2638 /// Holds a "weak" pointer to the object.
2639 ///
2640 /// It contains the pointer to the CObjectEx but does not control the lifetime
2641 /// of the object. Access to the object can be obtained only via method Lock()
2642 /// which will return CRef to the object which will guarantee that object is
2643 /// not destroyed yet and that it will not be destroyed at least until the
2644 /// returned CRef is destroyed.
2645 /// If the referenced object is already destroyed then Lock() will
2646 /// return empty reference.
2647 ///
2648 /// Parameter class C should be derived from CObjectEx class (or from both
2649 /// CObject and CWeakObject classes).
2650 /// A CWeakRef instance cannot be created for the objects for which there are
2651 /// currently no CRefs (except if the object is allocated in the stack or
2652 /// static memory).
2653 ///
2654 /// @sa CObjectEx, CWeakObject, CObject
2655 
2656 template<class C, class Locker = typename CWeakLockerTraits<C>::TLockerType>
2658 {
2659 public:
2660  typedef C element_type; ///< Define alias element_type
2661  typedef element_type TObjectType; ///< Define alias TObjectType
2662  typedef Locker locker_type; ///< Define alias for locking type
2663  typedef typename Locker::TPtrProxyType proxy_type;
2664  ///< Alias for pointer proxy type
2665  typedef CRef<C, Locker> TRefType; ///< Alias for the CRef type
2666  typedef CWeakRef<C, Locker> TThisType; ///< Alias for this type
2667 
2668 
2669  /// Constructor for null pointer
2670  CWeakRef(void)
2671  {
2672  }
2673 
2674  /// Constructor for ENull pointer
2675  CWeakRef(ENull /*null*/)
2676  {
2677  }
2678 
2679  /// Constructor for pointer to a particular object
2680  ///
2681  /// @param ptr Pointer to the object whose life time is controlled by CRef
2682  explicit CWeakRef(TObjectType* ptr)
2683  {
2684  // The reset member function calls the locker GetPtrProxy()
2685  // where type checking is done. In case of problems an exception
2686  // will be generated.
2687  Reset(ptr);
2688  }
2689 
2690  /// Constructor for explicit type conversion from pointer to object
2691  ///
2692  /// @param ptr Pointer to the object whose life time is controlled by CRef
2693  CWeakRef(TObjectType* ptr, const locker_type& locker_value)
2694  : m_Locker(locker_value)
2695  {
2696  // The reset member function calls the locker GetPtrProxy()
2697  // where type checking is done. In case of problems an exception
2698  // will be generated.
2699  Reset(ptr);
2700  }
2701 
2702  // Default copy constructor and copy assignment are ok
2703 
2704 
2705  /// Get reference to locker object
2706  const locker_type& GetLocker(void) const
2707  {
2708  return m_Locker;
2709  }
2710 
2711  /// Lock the object and return reference to it.
2712  /// If the refenced object is already deleted then return null reference.
2713  TRefType Lock(void) const
2714  {
2715  if (!m_Proxy)
2716  return null;
2717 
2718  return m_Locker.GetLockedObject(m_Proxy.GetNCPointer());
2719  }
2720 
2721  /// Reset the containing pointer to null
2722  void Reset(void)
2723  {
2724  m_Proxy.Reset();
2725  }
2726 
2727  /// Reset the containing pointer to null
2728  void Reset(ENull /*null*/)
2729  {
2730  m_Proxy.Reset();
2731  }
2732 
2733  /// Reset the containing pointer to another object
2734  void Reset(TObjectType* ptr)
2735  {
2736  if (ptr) {
2737  // GetPtrProxy() will make type checking i.e.
2738  // will make sure that the object derives from CObject
2739  // and that it is controlled by CRef.
2740  m_Proxy.Reset(m_Locker.GetPtrProxy(ptr));
2741  }
2742  else {
2743  m_Proxy.Reset();
2744  }
2745  }
2746 
2747  /// Swap values of this reference with another
2748  void Swap(TThisType& ref)
2749  {
2750  m_Proxy.Swap(ref.m_Proxy);
2751  swap(m_Locker, ref.m_Locker);
2752  }
2753 
2754  /// Assignment from ENull pointer
2756  {
2757  Reset();
2758  return *this;
2759  }
2760 
2761  /// Assignment from pointer to other object
2763  {
2764  Reset(ptr);
2765  return *this;
2766  }
2767 
2768  /// operator== to compare with another CWeakRef
2769  bool operator== (const TThisType& right)
2770  {
2771  return m_Proxy == right.m_Proxy;
2772  }
2773 
2774  /// operator!= to compare with another CWeakRef
2775  bool operator!= (const TThisType& right)
2776  {
2777  return !(*this == right);
2778  }
2779 
2780 private:
2781  friend class CWeakIRef<C, Locker>;
2782 
2785 };
2786 
2787 
2788 /////////////////////////////////////////////////////////////////////////////
2789 ///
2790 /// CWeakIRef --
2791 ///
2792 /// Template for "weak" pointer to the interface.
2793 ///
2794 /// Contains the pointer to interface. Final object pointed by this reference
2795 /// should have ability of dynamic cast to CObjectEx. Reference do not control
2796 /// the lifetime of the object. Access to the interface can be obtained only
2797 /// via method Lock() which will return CIRef to the object which will
2798 /// guarantee that object is not destroyed yet and until received CIRef is not
2799 /// destroyed. If contained interface is already destroyed at the time
2800 /// of calling Lock() then method will return empty reference.
2801 ///
2802 /// @sa CObjectEx, CWeakRef<>
2803 
2804 template<class Interface, class Locker = CWeakInterfaceLocker<Interface> >
2805 class CWeakIRef : public CWeakRef<Interface, Locker>
2806 {
2808 public:
2813 
2814 
2815  /// Constructor for null pointer
2817  {
2818  }
2819 
2820  /// Constructor for ENull pointer
2821  CWeakIRef(ENull /*null*/)
2822  {
2823  }
2824 
2825  /// Constructor for pointer to the interface
2826  explicit CWeakIRef(TObjectType* ptr)
2827  : TParent(ptr)
2828  {
2829  }
2830 
2831  /// Constructor for explicit type conversion from pointer to object.
2832  CWeakIRef(TObjectType* ptr, const locker_type& locker_value)
2833  : TParent(ptr, locker_value)
2834  {
2835  }
2836 
2837  // Default copy constructor and copy assignment are ok
2838 
2839 
2840  /// Assignment from ENull pointer
2842  {
2843  TParent::operator= (null);
2844  return *this;
2845  }
2846 
2847  /// Assignment from pointer to another interface
2849  {
2850  TParent::operator= (ptr);
2851  return *this;
2852  }
2853 
2854 
2855  /// Swap values of this reference with another
2856  void Swap(TThisType& ref)
2857  {
2858  TParent::Swap(ref);
2859  }
2860 
2861 
2862  /// Lock the object and return reference to it.
2863  /// If the refenced object is already deleted then return null reference.
2864  TRefType Lock(void) const
2865  {
2866  if (!this->m_Proxy)
2867  return null;
2868 
2869  return this->m_Locker.GetLockedObject(this->m_Proxy.GetNCPointer());
2870  }
2871 };
2872 
2873 
2874 /* @} */
2875 
2876 
2878 
2880 
2881 template<class C, class L>
2882 inline
2883 void swap(NCBI_NS_NCBI::CRef<C,L>& ref1,
2884  NCBI_NS_NCBI::CRef<C,L>& ref2)
2885 {
2886  ref1.Swap(ref2);
2887 }
2888 
2889 
2890 template<class C, class L>
2891 inline
2892 void swap(NCBI_NS_NCBI::CConstIRef<C,L>& ref1,
2893  NCBI_NS_NCBI::CConstIRef<C,L>& ref2)
2894 {
2895  ref1.Swap(ref2);
2896 }
2897 
2898 
2899 template<class C, class L>
2900 inline
2901 void swap(NCBI_NS_NCBI::CIRef<C,L>& ref1,
2902  NCBI_NS_NCBI::CIRef<C,L>& ref2)
2903 {
2904  ref1.Swap(ref2);
2905 }
2906 
2907 
2908 template<class C, class L>
2909 inline
2910 void swap(NCBI_NS_NCBI::CConstRef<C,L>& ref1,
2911  NCBI_NS_NCBI::CConstRef<C,L>& ref2)
2912 {
2913  ref1.Swap(ref2);
2914 }
2915 
2916 
2917 template<class C, class L>
2918 inline
2919 void swap(NCBI_NS_NCBI::CWeakRef<C,L>& ref1,
2920  NCBI_NS_NCBI::CWeakRef<C,L>& ref2)
2921 {
2922  ref1.Swap(ref2);
2923 }
2924 
2925 
2926 template<class C, class L>
2927 inline
2928 void swap(NCBI_NS_NCBI::CWeakIRef<C,L>& ref1,
2929  NCBI_NS_NCBI::CWeakIRef<C,L>& ref2)
2930 {
2931  ref1.Swap(ref2);
2932 }
2933 
2934 
2936 
2937 #endif /* NCBIOBJ__HPP */
CConstRef –.
Definition: ncbiobj.hpp:1266
CCoreException –.
Definition: ncbiexpt.hpp:1476
CObjectEx –.
Definition: ncbiobj.hpp:2531
CObjectException –.
Definition: ncbiobj.hpp:74
CObjectFor –.
Definition: ncbiobj.hpp:2335
CObject –.
Definition: ncbiobj.hpp:180
CPtrToObjectProxy –.
Definition: ncbiobj.hpp:2400
CRef –.
Definition: ncbiobj.hpp:618
CWeakIRef –.
Definition: ncbiobj.hpp:2806
CWeakInterfaceLocker –.
Definition: ncbiobj.hpp:2584
CWeakObjectLocker –.
Definition: ncbiobj.hpp:2549
CWeakObject –.
Definition: ncbiobj.hpp:2443
CWeakRef –.
Definition: ncbiobj.hpp:2658
Interface IAlignRow - abstracts row rendering in Multiple Alignment Widget.
Definition: ialign_row.hpp:67
IEventRecord.
char value[7]
Definition: config.c:431
static unsigned char depth[2 *(256+1+29)+1]
#define C(s)
Definition: common.h:231
#define T(s)
Definition: common.h:230
bool operator<(const CEquivRange &A, const CEquivRange &B)
static int type
Definition: getdata.c:31
const first_type & first() const
Definition: ncbimisc.hpp:269
const second_type & second() const
Definition: ncbimisc.hpp:278
ENull
CNullable –.
Definition: ncbimisc.hpp:645
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
virtual void x_InitErrCode(CException::EErrCode err_code)
Helper method for initializing error code.
Definition: ncbiexpt.cpp:567
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
Definition: ncbiexpt.cpp:757
#define THROWS_NONE
Do not use 'throw' dynamic exception specification for C++11 compilers.
Definition: ncbiexpt.hpp:74
EErrCode
Error types that an application can generate.
Definition: ncbiexpt.hpp:884
CExpression operator>=(CREATED, time_point)
CExpression operator<=(time_point, CREATED)
void RemoveLastReference(TCount count) const
Remove the last reference.
Definition: ncbiobj.cpp:824
CConstIRef(TObjectType *ptr, const locker_type &locker_value)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:2190
CIRef< Interface, Locker > TThisType
Definition: ncbiobj.hpp:2038
void TransferLock(const CObject *object, const CObjectCounterLocker &old_locker) const
Definition: ncbiobj.cpp:1179
CConstRef(const TThisType &ref)
Constructor from an existing CConstRef object.
Definition: ncbiobj.hpp:1306
const T & GetData(void) const
Get data as a reference – const version.
Definition: ncbiobj.hpp:2352
TObjectType * operator->(void) const
Reference operator.
Definition: ncbiobj.hpp:1717
CObjectEx(void)
Definition: ncbiobj.hpp:2533
TObjectType * GetNonNullPointer(void)
Get pointer value and throw a null pointer exception if pointer is null.
Definition: ncbiobj.hpp:968
CWeakObjectLocker< C > TThisType
Alias for this type.
Definition: ncbiobj.hpp:2554
static const int eCounterStep
Skip over the "in heap" bits.
Definition: ncbiobj.hpp:342
TParent::locker_type locker_type
Definition: ncbiobj.hpp:2037
CConstIRef(CIRef< TDerived > &&ref)
Move constructor from an existing CRef object of derived type.
Definition: ncbiobj.hpp:2235
TPtrProxyType * GetPtrProxy(Interface *ptr) const
Get proxy storage for pointer to object.
Definition: ncbiobj.hpp:2592
TObjectType * GetNCPointerOrNull(void) const THROWS_NONE
Get pointer value.
Definition: ncbiobj.hpp:1162
void Clear(void)
Set pointer to NULL from object's destructor.
Definition: ncbiobj.cpp:1303
void operator-(int) const
TThisType & operator=(TObjectType *ptr)
Assignment operator for const references with right hand side set to a pointer.
Definition: ncbiobj.hpp:1631
CRef< C, Locker > TRefType
Alias for the CRef type.
Definition: ncbiobj.hpp:2665
Locker::TPtrProxyType proxy_type
Alias for pointer proxy type.
Definition: ncbiobj.hpp:2663
bool Empty(void) const THROWS_NONE
Check if CConstRef is empty – not pointing to any object which means having a null value.
Definition: ncbiobj.hpp:1385
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
TThisType & operator=(TThisType &&ref)
Move assignment operator for const references.
Definition: ncbiobj.hpp:1586
CConstIRef(TThisType &&ref)
Move constructor from an existing CConstRef object.
Definition: ncbiobj.hpp:2210
TObjectType & operator*(void)
Dereference operator returning object.
Definition: ncbiobj.hpp:1021
BEGIN_STD_SCOPE void swap(NCBI_NS_NCBI::CRef< C, L > &ref1, NCBI_NS_NCBI::CRef< C, L > &ref2)
Definition: ncbiobj.hpp:2883
CWeakRef(TObjectType *ptr, const locker_type &locker_value)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:2693
pair_base_member< locker_type, TObjectType * > m_Data
Pointer to object.
Definition: ncbiobj.hpp:1789
Locker locker_type
Define alias for locking type.
Definition: ncbiobj.hpp:1270
CRef(const TThisType &ref)
Copy constructor from an existing CRef object.
Definition: ncbiobj.hpp:659
void TransferLock(const Interface *object, const CInterfaceObjectLocker< Interface > &old_locker) const
Definition: ncbiobj.hpp:596
TThisType & operator=(const CRef< TDerived, Locker > &ref)
Assignment operator for references of derived types.
Definition: ncbiobj.hpp:912
TParent::locker_type locker_type
Definition: ncbiobj.hpp:2163
static void ThrowNullPointerException(void)
Definition: ncbiobj.hpp:828
TThisType & operator=(const CConstIRef< TDerived > &ref)
Assignment operator for references of derived types.
Definition: ncbiobj.hpp:2251
TThisType & operator=(CRef< TDerived, Locker > &&ref)
Move assignment operator for assigning a reference of derived type.
Definition: ncbiobj.hpp:1622
TPtrProxyType * GetPtrProxy(C *object) const
Get proxy storage for pointer to object.
Definition: ncbiobj.hpp:2557
TThisType & operator=(TThisType &&ref)
Move assignment operator for references.
Definition: ncbiobj.hpp:919
TThisType & operator=(ENull null)
Assignment operator with right hand side set to ENull.
Definition: ncbiobj.hpp:2140
TThisType & operator=(const CIRef< TDerived > &ref)
Assignment operator for assigning a reference to a const reference.
Definition: ncbiobj.hpp:2277
bool operator!(void) const THROWS_NONE
Check if CRef is empty – not pointing to any object, which means having a null value.
Definition: ncbiobj.hpp:709
TParent::locker_type locker_type
Definition: ncbiobj.hpp:2810
TThisType & operator=(TObjectType *ptr)
Assignment operator for references with right hand side set to a pointer.
Definition: ncbiobj.hpp:2295
void CleanWeakRefs(void) const
Method cleaning all CWeakRefs referencing at this moment to the object After calling to this method a...
Definition: ncbiobj.cpp:1280
CRef(void) THROWS_NONE
Constructor for null pointer.
Definition: ncbiobj.hpp:634
TObjectType * AtomicSwap(TObjectType *ptr)
Definition: ncbiobj.hpp:1239
TParent::TObjectType TObjectType
Definition: ncbiobj.hpp:2162
void operator-(TObjectType *) const
bool IsNull(void) const THROWS_NONE
Check if pointer is null – same effect as Empty().
Definition: ncbiobj.hpp:1401
const TObjectType * GetPointer(void) const THROWS_NONE
Get pointer – constant version,.
Definition: ncbiobj.hpp:1076
CObjectCounterLocker TLockerType
Default locker type for CRef.
Definition: ncbiobj.hpp:183
Uint8 TCount
Alias for value type of counter.
Definition: ncbiobj.hpp:310
TThisType & operator=(const CIRef< TDerived > &ref)
Assignment operator for references of derived types.
Definition: ncbiobj.hpp:2108
bool NotNull(void) const THROWS_NONE
Check if pointer is not null – same effect as NotEmpty().
Definition: ncbiobj.hpp:744
CWeakIRef(TObjectType *ptr, const locker_type &locker_value)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:2832
TObjectType & operator*(void) const
Dereference operator returning object.
Definition: ncbiobj.hpp:1707
void AtomicResetFrom(const TThisType &ref)
Reset reference object to new pointer.
Definition: ncbiobj.hpp:869
void x_LockFromMoveConstructor(const Locker &src_locker)
Definition: ncbiobj.hpp:1748
static const TCount eCounterBitsPlaceMask
Mask for 'in heap' state flags.
Definition: ncbiobj.hpp:339
static void ReportLockedObjects(bool clear=false)
Print all currently locked objects of monitored type.
Definition: ncbiobj.cpp:1205
TObjectType * GetNCPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1174
virtual void DoDeleteThisObject(void)
Mark this object as allocated in heap – object can be deleted.
Definition: ncbiobj.cpp:926
TThisType & operator=(TObjectType *ptr)
Assignment operator for references with right hand side set to a pointer.
Definition: ncbiobj.hpp:945
void InvalidObject(void) const
Report object is invalid.
CConstRef< C > ConstRef(const C *object)
Template function for conversion of const object pointer to CConstRef.
Definition: ncbiobj.hpp:2024
CWeakRef< Interface, Locker > TParent
Definition: ncbiobj.hpp:2807
CObject * m_Ptr
Definition: ncbiobj.hpp:2420
void Unlock(const Interface *object) const
Definition: ncbiobj.hpp:575
static void StopMonitoring(void)
Stop lock/unlock monitoring.
Definition: ncbiobj.cpp:1196
void x_LockFromMoveConstructor(const Locker &src_locker)
Definition: ncbiobj.hpp:1208
CWeakRef(void)
Constructor for null pointer.
Definition: ncbiobj.hpp:2670
const TObjectType * GetNonNullPointer(void) const
Get pointer value and throw a null pointer exception if pointer is null – constant version.
Definition: ncbiobj.hpp:1047
EAllocFillMode
Control filling of newly allocated memory.
Definition: ncbiobj.hpp:286
TThisType & operator=(ENull)
Assignment operator with right hand side set to ENull.
Definition: ncbiobj.hpp:1638
void Reset(TObjectType *ptr)
Reset the containing pointer to another object.
Definition: ncbiobj.hpp:2734
static void SetAllocFillMode(EAllocFillMode mode)
Definition: ncbiobj.cpp:436
TThisType & operator=(ENull null)
Assignment operator with right hand side set to ENull.
Definition: ncbiobj.hpp:2302
void operator-(int) const
CRef< proxy_type > m_Proxy
Definition: ncbiobj.hpp:2783
CConstIRef(void) THROWS_NONE
Constructor for null pointer.
Definition: ncbiobj.hpp:2174
CPtrToObjectProxy(CWeakObject *ptr)
Definition: ncbiobj.cpp:1292
typename std::enable_if< std::is_convertible< T *, TObjectType * >::value > enable_if_derived
Helper template to template enable methods only for derived types.
Definition: ncbiobj.hpp:1276
TObjectType * ReleaseOrNull(void)
Release a reference to the object and return a pointer to the object.
Definition: ncbiobj.hpp:1482
static EAllocFillMode GetAllocFillMode(void)
Definition: ncbiobj.cpp:430
void InitCounter(void)
Initialize counter.
Definition: ncbiobj.cpp:646
TObjectType * ReleaseOrNull(void)
Release a reference to the object and return a pointer to the object.
Definition: ncbiobj.hpp:816
CRef(TObjectType *ptr)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:645
bool x_AddWeakReference(CObject *obj)
Add reference to the object in "weak" manner.
Definition: ncbiobj.cpp:1268
virtual ~CObject(void)
Destructor.
Definition: ncbiobj.cpp:750
void Reset(TObjectType *newPtr)
Reset reference object to new pointer.
Definition: ncbiobj.hpp:1456
void x_MoveAssign(const Locker &src_locker, TObjectType *newPtr)
Definition: ncbiobj.hpp:1227
CConstRef(CRef< TDerived, Locker > &&ref)
Move constructor from an existing CRef object of derived type.
Definition: ncbiobj.hpp:1351
virtual void DoNotDeleteThisObject(void)
Mark this object as not allocated in heap – do not delete this object.
Definition: ncbiobj.cpp:884
void x_AssignFromRef(TObjectType *newPtr)
Definition: ncbiobj.hpp:1755
CConstRef(TObjectType *ptr)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:1292
void Swap(TThisType &ref)
Swaps the pointer with another reference.
Definition: ncbiobj.hpp:2312
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
TObjectType * AtomicSwap(TObjectType *ptr)
Definition: ncbiobj.hpp:1779
TObjectType * GetNonNullNCPointer(void) const
Get pointer value and throw a null pointer exception if pointer is null.
Definition: ncbiobj.hpp:1144
void Relock(const CObject *object) const
Definition: ncbiobj.cpp:1152
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:1439
CRef< Interface, Locker > TParent
Definition: ncbiobj.hpp:2034
CConstRef(void) THROWS_NONE
Constructor for null pointer.
Definition: ncbiobj.hpp:1281
T & GetData(void)
Get data as a reference.
Definition: ncbiobj.hpp:2346
CIRef< Interface, Locker > TRefType
Definition: ncbiobj.hpp:2811
bool operator!=(const TThisType &right)
operator!= to compare with another CWeakRef
Definition: ncbiobj.hpp:2775
CConstRef(TObjectType *ptr, const locker_type &locker_value)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:1299
CWeakObject * m_WeakPtr
Definition: ncbiobj.hpp:2421
void ReleaseReference(void) const
Remove reference without deleting object.
Definition: ncbiobj.cpp:860
CObjectFor(Args &&... args)
Definition: ncbiobj.hpp:2340
static bool ObjectStateReferencedOnlyOnce(TCount count)
Check if object can be referenced only once.
Definition: ncbiobj.hpp:447
CConstIRef(CConstIRef< TDerived > &&ref)
Move constructor from an existing CConstRef object of derived type.
Definition: ncbiobj.hpp:2218
CConstIRef(const CIRef< TDerived > &ref)
Constructor from an existing CRef object of derived type.
Definition: ncbiobj.hpp:2227
TThisType & operator=(const TThisType &ref)
Assignment operator for references.
Definition: ncbiobj.hpp:2099
static NCBI_XNCBI_EXPORT void ThrowNullPointerException(void)
Define method to throw null pointer exception.
Definition: ncbiobj.cpp:1002
void x_LockFromRef()
Definition: ncbiobj.hpp:1201
C element_type
Define alias element_type.
Definition: ncbiobj.hpp:1268
virtual void DebugDump(CDebugDumpContext ddc, unsigned int depth) const
Define method for dumping debug information.
Definition: ncbiobj.cpp:988
C element_type
Define alias element_type.
Definition: ncbiobj.hpp:2660
CConstRef(TThisType &&ref)
Move constructor from an existing CConstRef object.
Definition: ncbiobj.hpp:1322
CConstIRef(const TThisType &ref)
Constructor from an existing CConstRef object.
Definition: ncbiobj.hpp:2196
virtual ~CWeakObject(void)
Definition: ncbiobj.cpp:1261
static const TCount eCounterBitsCanBeDeleted
Define possible object states.
Definition: ncbiobj.hpp:335
TThisType & operator=(const TThisType &ref)
Assignment operator for references.
Definition: ncbiobj.hpp:2242
void AddReference(void) const
Add reference to object.
Definition: ncbiobj.hpp:489
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
const TObjectType & operator*(void) const
Dereference operator returning object – constant version.
Definition: ncbiobj.hpp:1099
bool operator==(const CRef< T, L > &r1, ENull)
Comparison operators for CRef<> and CConstRef<> with ENull.
Definition: ncbiobj.hpp:1805
void UnlockRelease(const CObject *object) const
Definition: ncbiobj.cpp:1167
TThisType & operator=(const TThisType &ref)
Assignment operator for references.
Definition: ncbiobj.hpp:903
CRef(ENull) THROWS_NONE
Constructor for ENull pointer.
Definition: ncbiobj.hpp:640
#define NCBI_OBJECT_LOCKER_EXPORT
CObjectCounterLocker – Default locker class for CRef/CConstRef templates, all other locker classes sh...
Definition: ncbiobj.hpp:112
~CRef(void)
Destructor.
Definition: ncbiobj.hpp:693
TRefType Lock(void) const
Lock the object and return reference to it.
Definition: ncbiobj.hpp:2864
void operator-(TObjectType *) const
CConstRef< Interface, Locker > TParent
Definition: ncbiobj.hpp:2160
virtual void DeleteThis(void)
Virtual method "deleting" this object.
Definition: ncbiobj.cpp:809
TThisType & operator=(TThisType &&ref)
Move assignment operator for references.
Definition: ncbiobj.hpp:2258
void Reset(TObjectType *newPtr)
Reset reference object to new pointer.
Definition: ncbiobj.hpp:790
CPtrToObjectProxy * GetPtrProxy(void) const
Get pointer to proxy object containing pointer to this object.
Definition: ncbiobj.hpp:2499
bool NotEmpty(void) const THROWS_NONE
Check if CRef is not empty – pointing to an object and has a non-null value.
Definition: ncbiobj.hpp:726
CIRef< Interface, TThisType > GetLockedObject(TPtrProxyType *proxy) const
Lock the object and return pointer to it stored in the proxy.
Definition: ncbiobj.hpp:2603
void x_LockFromRef()
Definition: ncbiobj.hpp:1741
TThisType & operator=(const TThisType &ref)
Assignment operator for const references.
Definition: ncbiobj.hpp:1569
CWeakIRef< Interface, Locker > TThisType
Definition: ncbiobj.hpp:2812
void RemoveReference(void) const
Remove reference to object.
Definition: ncbiobj.hpp:500
bool operator!=(const CRef< T, L > &r1, ENull)
Template operator != function for CRef objects – rhs is null.
Definition: ncbiobj.hpp:1821
const locker_type & GetLocker(void) const
Get reference to locker object.
Definition: ncbiobj.hpp:699
static bool ObjectStateValid(TCount count)
Check if object state is valid.
Definition: ncbiobj.hpp:426
static bool ObjectStateReferenced(TCount count)
Check if object can be referenced.
Definition: ncbiobj.hpp:433
NCBI_XNCBI_EXPORT void CheckReferenceOverflow(TCount count) const
Report that counter has overflowed.
Definition: ncbiobj.cpp:785
CConstRef< C, Locker > TThisType
Alias for this template type.
Definition: ncbiobj.hpp:1271
CConstIRef< Interface, Locker > TThisType
Definition: ncbiobj.hpp:2164
void Lock(const Interface *object) const
Definition: ncbiobj.hpp:559
void Swap(TThisType &ref)
Swaps the pointer with another reference.
Definition: ncbiobj.hpp:1420
const TObjectType * GetPointerOrNull(void) const THROWS_NONE
Get pointer value – constant version.
Definition: ncbiobj.hpp:1064
CRef(const CRef< TDerived, Locker > &ref)
Copy constructor from an existing CRef object of derived type.
Definition: ncbiobj.hpp:668
void AtomicResetFrom(const CConstRef &ref)
Reset reference object to new pointer.
Definition: ncbiobj.hpp:1535
CWeakRef< C, Locker > TThisType
Alias for this type.
Definition: ncbiobj.hpp:2666
static bool ObjectStateIsAllocatedInPool(TCount count)
Check if object is allocated in memory pool.
Definition: ncbiobj.hpp:418
CRef(TObjectType *ptr, const locker_type &locker_value)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:652
void Swap(TThisType &ref)
Swap values of this reference with another.
Definition: ncbiobj.hpp:2856
TThisType & operator=(ENull null)
Assignment from ENull pointer.
Definition: ncbiobj.hpp:2841
T & operator=(const T &data)
Assignment operator.
Definition: ncbiobj.hpp:2376
CConstIRef(TObjectType *ptr)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:2184
T TObjectType
Define alias for template parameter.
Definition: ncbiobj.hpp:2337
Locker locker_type
Define alias for locking type.
Definition: ncbiobj.hpp:2662
CWeakObject(void)
Definition: ncbiobj.cpp:1255
TObjectType * operator->(void)
Reference operator.
Definition: ncbiobj.hpp:1031
void operator+(int) const
bool Referenced(void) const THROWS_NONE
Check if object is referenced.
Definition: ncbiobj.hpp:468
void operator+(int) const
void UnlockRelease(const Interface *object) const
Definition: ncbiobj.hpp:582
CConstRef(ENull) THROWS_NONE
Constructor for ENull pointer.
Definition: ncbiobj.hpp:1287
const locker_type & GetLocker(void) const
Get reference to locker object.
Definition: ncbiobj.hpp:2706
TThisType & operator=(TObjectType *ptr)
Assignment operator for references with right hand side set to a pointer.
Definition: ncbiobj.hpp:2133
CObject * x_UpdateCObjectPtr(void)
Definition: ncbiobj.hpp:2485
TRefType Lock(void) const
Lock the object and return reference to it.
Definition: ncbiobj.hpp:2713
bool NotNull(void) const THROWS_NONE
Check if pointer is not null – same effect as NotEmpty().
Definition: ncbiobj.hpp:1410
void Swap(TThisType &ref)
Swaps the pointer with another reference.
Definition: ncbiobj.hpp:754
void Swap(TThisType &ref)
Swaps the pointer with another reference.
Definition: ncbiobj.hpp:2150
NCBI_EXCEPTION_DEFAULT(CObjectException, CCoreException)
CRef< C, TThisType > GetLockedObject(TPtrProxyType *proxy) const
Lock the object and return pointer to it stored in the proxy.
Definition: ncbiobj.hpp:2564
static void ReportIncompatibleType(const type_info &type)
Definition: ncbiobj.cpp:1226
element_type TObjectType
Define alias TObjectType.
Definition: ncbiobj.hpp:621
element_type TObjectType
Define alias TObjectType.
Definition: ncbiobj.hpp:2661
bool ReferencedOnlyOnce(void) const THROWS_NONE
Check if object is referenced only once.
Definition: ncbiobj.hpp:475
TThisType & operator=(ENull)
Assignment operator with right hand side set to ENull.
Definition: ncbiobj.hpp:952
bool CanBeDeleted(void) const THROWS_NONE
Check if object can be deleted.
Definition: ncbiobj.hpp:454
TParent::TObjectType TObjectType
Definition: ncbiobj.hpp:2036
TObjectType * GetPointerOrNull(void) const THROWS_NONE
Get pointer value.
Definition: ncbiobj.hpp:1672
const TObjectType * operator->(void) const
Reference operator – constant version.
Definition: ncbiobj.hpp:1109
const TObjectType & GetObject(void) const
Get object – constant version.
Definition: ncbiobj.hpp:1089
CObject & operator=(const CObject &src) THROWS_NONE
Assignment operator.
Definition: ncbiobj.hpp:482
void x_AssignFromRef(TObjectType *newPtr)
Definition: ncbiobj.hpp:1215
TThisType & operator=(TThisType &&ref)
Move assignment operator for references.
Definition: ncbiobj.hpp:2115
CWeakIRef(TObjectType *ptr)
Constructor for pointer to the interface.
Definition: ncbiobj.hpp:2826
static const TCount eCounterValid
Minimal value for valid objects (reference counter is zero) Must be a single bit value.
Definition: ncbiobj.hpp:352
CWeakRef(ENull)
Constructor for ENull pointer.
Definition: ncbiobj.hpp:2675
CConstIRef(ENull) THROWS_NONE
Constructor for ENull pointer.
Definition: ncbiobj.hpp:2179
CConstRef(const CConstRef< TDerived, Locker > &ref)
Constructor from an existing CConstRef object of derived type.
Definition: ncbiobj.hpp:1315
void Reset(void)
Reset the containing pointer to null.
Definition: ncbiobj.hpp:2722
CWeakObjectLocker< C > TLockerType
Definition: ncbiobj.hpp:2627
CPtrToObjectProxy TPtrProxyType
Type working as proxy storage for pointer to object.
Definition: ncbiobj.hpp:2587
TObjectType * Release(void)
Release a reference to the object and return a pointer to the object.
Definition: ncbiobj.hpp:1512
void x_LockFromPtr()
Definition: ncbiobj.hpp:1734
~CPtrToObjectProxy(void)
Definition: ncbiobj.cpp:1298
CConstRef(CConstRef< TDerived, Locker > &&ref)
Move constructor from an existing CConstRef object of derived type.
Definition: ncbiobj.hpp:1332
static void MonitorObjectType(const type_info &type)
Set monitored object type, e.g.
Definition: ncbiobj.cpp:1189
CPtrToObjectProxy TPtrProxyType
Type working as proxy storage for pointer to object.
Definition: ncbiobj.hpp:2552
bool IsNull(void) const THROWS_NONE
Check if pointer is null – same effect as Empty().
Definition: ncbiobj.hpp:735
CRef< CPtrToObjectProxy > m_SelfPtrProxy
Proxy object with pointer to this instance.
Definition: ncbiobj.hpp:2474
CIRef(const CIRef< TDerived > &ref)
Constructor from existing ref of derived type.
Definition: ncbiobj.hpp:2072
CWeakIRef(ENull)
Constructor for ENull pointer.
Definition: ncbiobj.hpp:2821
TObjectType & GetObject(void)
Get object.
Definition: ncbiobj.hpp:1011
typename std::enable_if< std::is_convertible< T *, TObjectType * >::value > enable_if_derived
Helper template to template enable methods only for derived types.
Definition: ncbiobj.hpp:628
CObject * GetLockedObject(void)
Lock the object and return pointer to it.
Definition: ncbiobj.cpp:1312
CIRef(const TThisType &ref)
Constructor from existing ref.
Definition: ncbiobj.hpp:2064
CIRef(TThisType &&ref)
Move constructor from existing ref.
Definition: ncbiobj.hpp:2078
TObjectType * Release(void)
Release a reference to the object and return a pointer to the object.
Definition: ncbiobj.hpp:846
TThisType & operator=(CIRef< TDerived > &&ref)
Move assignment operator for references of derived types.
Definition: ncbiobj.hpp:2124
CIRef(TObjectType *ptr, const locker_type &locker_value)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:2093
CWeakRef(TObjectType *ptr)
Constructor for pointer to a particular object.
Definition: ncbiobj.hpp:2682
TParent::TObjectType TObjectType
Definition: ncbiobj.hpp:2809
bool operator!(void) const THROWS_NONE
Check if CConstRef is empty – not pointing to any object, which means having a null value.
Definition: ncbiobj.hpp:1375
bool NotEmpty(void) const THROWS_NONE
Check if CConstRef is not empty – pointing to an object and has a non-null value.
Definition: ncbiobj.hpp:1392
TThisType & operator=(CIRef< TDerived > &&ref)
Move assignment operator for assigning a reference to a const reference.
Definition: ncbiobj.hpp:2286
TThisType & operator=(ENull)
Assignment from ENull pointer.
Definition: ncbiobj.hpp:2755
Locker locker_type
Define alias for locking type.
Definition: ncbiobj.hpp:622
static void ThrowNullPointerException(void)
Definition: ncbiobj.hpp:1494
TThisType & operator=(const CConstRef< TDerived, Locker > &ref)
Assignment operator for const references of derived types.
Definition: ncbiobj.hpp:1578
void Unlock(const CObject *object) const
Definition: ncbiobj.cpp:1158
C element_type
Define alias element_type.
Definition: ncbiobj.hpp:620
void x_MoveAssign(const Locker &src_locker, TObjectType *newPtr)
Definition: ncbiobj.hpp:1767
atomic< Uint8 > TCounter
Counter type is CAtomiCounter.
Definition: ncbiobj.hpp:309
CIRef(ENull) THROWS_NONE
Constructor for ENull pointer.
Definition: ncbiobj.hpp:2053
void AtomicReleaseTo(CConstRef &ref)
Release referenced object to another CConstRef<> object.
Definition: ncbiobj.hpp:1556
CRef(TThisType &&ref)
Move constructor from an existing CRef object.
Definition: ncbiobj.hpp:675
CWeakInterfaceLocker< Interface > TThisType
Alias for this type.
Definition: ncbiobj.hpp:2589
TThisType & operator=(CConstRef< TDerived, Locker > &&ref)
Move assignment operator for const references of derived types.
Definition: ncbiobj.hpp:1603
static bool ObjectStateCanBeDeleted(TCount count)
Check if object can be deleted.
Definition: ncbiobj.hpp:410
virtual ~CObjectEx(void)
Definition: ncbiobj.cpp:1287
TThisType & operator=(CRef< TDerived, Locker > &&ref)
Move assignment operator for references of derived types.
Definition: ncbiobj.hpp:936
const locker_type & GetLocker(void) const
Get reference to locker object.
Definition: ncbiobj.hpp:1365
CRef< C, Locker > TThisType
Alias for this template type.
Definition: ncbiobj.hpp:623
void Reset(ENull)
Reset the containing pointer to null.
Definition: ncbiobj.hpp:2728
void Lock(const CObject *object) const
Definition: ncbiobj.cpp:1143
CRef(CRef< TDerived, Locker > &&ref)
Move constructor from an existing CRef object of derived type.
Definition: ncbiobj.hpp:685
CIRef(TObjectType *ptr)
Constructor for explicit type conversion from pointer to object.
Definition: ncbiobj.hpp:2058
CObjectCounterLocker TLockerType
Definition: ncbiobj.hpp:166
CObject(void)
Constructor.
Definition: ncbiobj.cpp:738
TObjectType * GetPointerOrNull(void) THROWS_NONE
Get pointer value.
Definition: ncbiobj.hpp:986
bool operator==(const TThisType &right)
operator== to compare with another CWeakRef
Definition: ncbiobj.hpp:2769
static NCBI_XNCBI_EXPORT void ReportIncompatibleType(const type_info &type)
Report about trying to convert incompatible interface fo CObject.
Definition: ncbiobj.cpp:1331
CWeakIRef(void)
Constructor for null pointer.
Definition: ncbiobj.hpp:2816
CIRef(void) THROWS_NONE
Constructor for null pointer.
Definition: ncbiobj.hpp:2048
static const TCount eCounterBitsInPlainHeap
Heap signature was found.
Definition: ncbiobj.hpp:337
TObjectType & GetNCObject(void) const
Get object.
Definition: ncbiobj.hpp:1187
locker_type m_Locker
Definition: ncbiobj.hpp:2784
pair_base_member< locker_type, TObjectType * > m_Data
Pointer to object.
Definition: ncbiobj.hpp:1248
TThisType & operator=(const CRef< TDerived, Locker > &ref)
Assignment operator for assigning a reference of derived type.
Definition: ncbiobj.hpp:1613
const element_type TObjectType
Define alias TObjectType.
Definition: ncbiobj.hpp:1269
CConstIRef(const CConstIRef< TDerived > &ref)
Constructor from an existing CConstRef object of derived type.
Definition: ncbiobj.hpp:2204
TCounter m_Counter
The actual reference counter.
Definition: ncbiobj.hpp:400
~CConstRef(void)
Destructor.
Definition: ncbiobj.hpp:1359
static bool ObjectStateUnreferenced(TCount count)
Check if object can be referenced.
Definition: ncbiobj.hpp:440
CConstRef(const CRef< TDerived, Locker > &ref)
Constructor from an existing CRef object of derived type.
Definition: ncbiobj.hpp:1342
bool IsAllocatedInPool(void) const THROWS_NONE
Check if object is allocated in memory pool (not system heap)
Definition: ncbiobj.hpp:461
TObjectType & GetObject(void) const
Get object.
Definition: ncbiobj.hpp:1697
void AtomicReleaseTo(TThisType &ref)
Release referenced object to another CRef<> object.
Definition: ncbiobj.hpp:890
void Relock(const Interface *object) const
Definition: ncbiobj.hpp:568
void x_LockFromPtr()
Definition: ncbiobj.hpp:1194
void Swap(TThisType &ref)
Swap values of this reference with another.
Definition: ncbiobj.hpp:2748
T m_Data
Data member of template parameter type.
Definition: ncbiobj.hpp:2383
TObjectType * GetNonNullPointer(void) const
Get pointer value and throw a null pointer exception if pointer is null.
Definition: ncbiobj.hpp:1654
CIRef(CIRef< TDerived > &&ref)
Move constructor from existing ref of derived type.
Definition: ncbiobj.hpp:2086
TThisType & operator=(CConstIRef< TDerived > &&ref)
Move assignment operator for references of derived types.
Definition: ncbiobj.hpp:2267
static const TCount eCounterStateMask
Valid object, and object in heap.
Definition: ncbiobj.hpp:355
bool Empty(void) const THROWS_NONE
Check if CRef is empty – not pointing to any object, which means having a null value.
Definition: ncbiobj.hpp:719
@ eAllocFillNone
Definition: ncbiobj.hpp:287
@ eAllocFillZero
Definition: ncbiobj.hpp:288
@ eAllocFillPattern
Definition: ncbiobj.hpp:289
@ eDeleted
Attempt to delete a deleted object.
Definition: ncbiobj.hpp:79
@ eRefDelete
Attempt to delete valid reference.
Definition: ncbiobj.hpp:78
@ eCorrupted
Object corrupted error.
Definition: ncbiobj.hpp:80
@ eRefOverflow
Reference overflow error.
Definition: ncbiobj.hpp:81
@ eNoRef
Attempt to access an object that is unreferenced.
Definition: ncbiobj.hpp:82
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_STD_SCOPE
Place it for adding new funtionality to STD scope.
Definition: ncbistl.hpp:92
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define END_STD_SCOPE
End previously defined STD scope.
Definition: ncbistl.hpp:95
#define NCBI_XNCBI_EXPORT
Definition: ncbi_export.h:1274
mdb_mode_t mode
Definition: lmdb++.h:38
const struct ncbi::grid::netcache::search::fields::SIZE size
Defines MS Windows specifics for our "C++" code.
Multi-threading – atomic pointer exchange function.
void * SwapPointers(void *volatile *location, void *new_value)
Definition: ncbiatomic.hpp:47
Definition: type.c:6
#define _ASSERT
bool operator>(const typename tree< T, tree_node_allocator >::iterator_base &one, const typename tree< T, tree_node_allocator >::iterator_base &two)
Definition: tree_msvc7.hpp:426
Modified on Wed Oct 04 02:29:35 2023 by modify_doxy.py rev. 669887