00001 // -*- C++ -*- 00002 // 00003 // RCPtr.h is a part of ThePEG - Toolkit for HEP Event Generation 00004 // Copyright (C) 1999-2007 Leif Lonnblad 00005 // 00006 // ThePEG is licenced under version 2 of the GPL, see COPYING for details. 00007 // Please respect the MCnet academic guidelines, see GUIDELINES for details. 00008 // 00009 #ifndef ThePEG_RCPtr_H 00010 #define ThePEG_RCPtr_H 00011 // This is the declaration of the RCPtrBase, 00012 00013 00014 #include "ReferenceCounted.h" 00015 #include "RCPtr.fh" 00016 #include "PtrTraits.h" 00017 00018 namespace ThePEG { 00019 namespace Pointer { 00020 00030 class RCPtrBase { 00031 00033 typedef ReferenceCounted::CounterType CounterType; 00034 00035 protected: 00036 00040 void increment(const ReferenceCounted * rcp) { 00041 if ( rcp ) rcp->incrementReferenceCount(); 00042 } 00046 bool release(const ReferenceCounted * rcp) { 00047 return rcp && rcp->decrementReferenceCount(); 00048 } 00049 00050 }; 00051 00059 template <typename T> 00060 class RCPtr: public RCPtrBase { 00061 00062 public: 00063 00065 typedef void iterator_category; 00067 typedef void difference_type; 00069 typedef T * pointer; 00071 typedef const T * const_pointer; 00073 typedef T & reference; 00075 typedef const T & const_reference; 00077 typedef T value_type; 00078 00079 public: 00080 00085 RCPtr() : ptr(0) {} 00086 00090 RCPtr(const RCPtr & p) : ptr(p.ptr) { increment(); } 00091 00096 template <typename UPtr> 00097 RCPtr(const UPtr & u) 00098 : ptr(PtrTraits<UPtr>::barePointer(u)) { increment(); } 00099 00103 explicit RCPtr(pointer p) : ptr(p) { increment(); } 00104 00109 ~RCPtr() { release(); } 00110 00115 static RCPtr Create() { 00116 RCPtr<T> p; 00117 return p.create(); 00118 } 00119 00124 static RCPtr Create(const_reference t) { 00125 RCPtr<T> p; 00126 return p.create(t); 00127 } 00128 00129 00134 RCPtr & create() { 00135 release(); 00136 ptr = new T; 00137 // increment(); // ReferenceCounted() constructor starts at 1 00138 return *this; 00139 } 00140 00145 RCPtr & create(const_reference t) { 00146 release(); 00147 ptr = new T(t); 00148 // increment(); // ReferenceCounted() constructor starts at 1 00149 return *this; 00150 } 00151 00155 RCPtr & operator=(const RCPtr & p) { 00156 if ( ptr == p.ptr ) return *this; 00157 release(); 00158 ptr = p.ptr; 00159 increment(); 00160 return *this; 00161 } 00162 00167 template <typename UPtr> 00168 RCPtr & operator=(const UPtr & u) { 00169 if ( ptr == PtrTraits<UPtr>::barePointer(u) ) return *this; 00170 release(); 00171 ptr = PtrTraits<UPtr>::barePointer(u); 00172 increment(); 00173 return *this; 00174 } 00175 00180 template <typename UPtr> 00181 RCPtr & assignDynamic(const UPtr & u) { 00182 pointer up = dynamic_cast<pointer>(PtrTraits<UPtr>::barePointer(u)); 00183 if ( ptr == up ) return *this; 00184 release(); 00185 ptr = up; 00186 increment(); 00187 return *this; 00188 } 00189 00194 template <typename UPtr> 00195 RCPtr & assignConst(const UPtr & u) { 00196 pointer up = const_cast<pointer>(PtrTraits<UPtr>::barePointer(u)); 00197 if ( ptr == up ) return *this; 00198 release(); 00199 ptr = up; 00200 increment(); 00201 return *this; 00202 } 00203 00207 void swap(RCPtr & p) { 00208 const pointer tmp = ptr; 00209 ptr = p.ptr; 00210 p.ptr = tmp; 00211 // std::swap(ptr, p.ptr); 00212 } 00213 00217 bool operator==(const RCPtr & p) const { return ptr == p.ptr; } 00218 00222 bool operator!=(const RCPtr & p) const { return ptr != p.ptr; } 00223 00227 bool operator==(const_pointer p) const { return ptr == p; } 00228 00232 bool operator!=(const_pointer p) const { return ptr != p; } 00233 00237 template <typename UPtr> 00238 bool operator==(const UPtr & u) const { 00239 return ptr == PtrTraits<UPtr>::barePointer(u); 00240 } 00241 00245 template <typename UPtr> 00246 bool operator!=(const UPtr & u) const { 00247 return ptr != PtrTraits<UPtr>::barePointer(u); 00248 } 00249 00253 bool operator<(const RCPtr & p) const { 00254 return ( ptr && p.ptr && ptr->uniqueId != p.ptr->uniqueId ) ? 00255 ptr->uniqueId < p.ptr->uniqueId : ptr < p.ptr; 00256 } 00257 00261 bool operator<(const_pointer p) const { 00262 return ( ptr && p && ptr->uniqueId != p->uniqueId ) ? 00263 ptr->uniqueId < p->uniqueId : ptr < p; 00264 } 00265 00269 bool operator!() const { return !ptr; } 00270 00274 operator T * () const { return ptr; } 00275 00279 pointer operator->() const { return ptr; } 00280 00284 reference operator*() const { return *ptr; } 00285 00286 private: 00287 00291 void increment() { RCPtrBase::increment(ptr); } 00292 00297 void release() { if ( RCPtrBase::release(ptr) ) delete ptr; } 00298 00302 pointer ptr; 00303 00304 }; 00305 00314 template <typename T> 00315 class ConstRCPtr : public RCPtrBase { 00316 00317 public: 00318 00320 typedef void iterator_category; 00322 typedef void difference_type; 00324 typedef T * pointer; 00326 typedef const T * const_pointer; 00328 typedef T & reference; 00330 typedef const T & const_reference; 00332 typedef T value_type; 00333 00334 public: 00335 00339 ConstRCPtr() : ptr(0) {} 00340 00344 ConstRCPtr(const ConstRCPtr & p) : ptr(p.ptr) { increment(); } 00345 00350 template <typename UPtr> 00351 ConstRCPtr(const UPtr & u) : ptr(PtrTraits<UPtr>::barePointer(u)) { increment(); } 00352 00356 explicit ConstRCPtr(const_pointer p) : ptr(p) { increment(); } 00357 00362 ~ConstRCPtr() { release(); } 00363 00367 ConstRCPtr & operator=(const ConstRCPtr & p) { 00368 if ( ptr == p.ptr ) return *this; 00369 release(); 00370 ptr = p.ptr; 00371 increment(); 00372 return *this; 00373 } 00374 00379 template <typename UPtr> 00380 ConstRCPtr & operator=(const UPtr & u) { 00381 if ( ptr == PtrTraits<UPtr>::barePointer(u) ) return *this; 00382 release(); 00383 ptr = PtrTraits<UPtr>::barePointer(u); 00384 increment(); 00385 return *this; 00386 } 00387 00392 template <typename UPtr> 00393 ConstRCPtr & assignDynamic(const UPtr & u) { 00394 const_pointer up = 00395 dynamic_cast<const_pointer>(PtrTraits<UPtr>::barePointer(u)); 00396 if ( ptr == up ) return *this; 00397 release(); 00398 ptr = up; 00399 increment(); 00400 return *this; 00401 } 00402 00406 void swap(ConstRCPtr & p) { 00407 const const_pointer tmp = ptr; 00408 ptr = p.ptr; 00409 p.ptr = tmp; 00410 // std::swap(ptr, p.ptr); 00411 } 00412 00416 bool operator==(const ConstRCPtr & p) const { return ptr == p.ptr; } 00417 00421 bool operator!=(const ConstRCPtr & p) const { return ptr != p.ptr; } 00422 00426 bool operator==(const_pointer p) const { return ptr == p; } 00427 00431 bool operator!=(const_pointer p) const { return ptr != p; } 00432 00436 template <typename UPtr> 00437 bool operator==(const UPtr & u) const { return ptr == PtrTraits<UPtr>::barePointer(u); } 00438 00442 template <typename UPtr> 00443 bool operator!=(const UPtr & u) const { return ptr != PtrTraits<UPtr>::barePointer(u); } 00444 00448 bool operator<(const ConstRCPtr & p) const { 00449 return ( ptr && p.ptr && ptr->uniqueId != p.ptr->uniqueId ) ? 00450 ptr->uniqueId < p.ptr->uniqueId : ptr < p.ptr; 00451 } 00452 00456 bool operator<(const_pointer p) const { 00457 return ( ptr && p && ptr->uniqueId != p->uniqueId ) ? 00458 ptr->uniqueId < p->uniqueId : ptr < p; 00459 } 00460 00464 bool operator!() const { return !ptr; } 00465 00469 operator const T * () const { return ptr; } 00470 00474 const_pointer operator->() const { return ptr; } 00475 00479 const_reference operator*() const { return *ptr; } 00480 00481 private: 00482 00486 void increment() { RCPtrBase::increment(ptr); } 00487 00492 void release() { if ( RCPtrBase::release(ptr) ) delete ptr; } 00493 00497 const_pointer ptr; 00498 00499 }; 00500 00508 template <typename T> 00509 class TransientRCPtr { 00510 00511 public: 00512 00514 typedef void iterator_category; 00516 typedef void difference_type; 00518 typedef T * pointer; 00520 typedef const T * const_pointer; 00522 typedef T & reference; 00524 typedef const T & const_reference; 00526 typedef T value_type; 00527 00528 public: 00529 00533 TransientRCPtr() : ptr(0) {} 00534 00538 TransientRCPtr(const TransientRCPtr & p) : ptr(p.ptr) {} 00539 00544 template <typename UPtr> 00545 TransientRCPtr(const UPtr & u) : ptr(PtrTraits<UPtr>::barePointer(u)) {} 00546 00550 explicit TransientRCPtr(pointer p) : ptr(p) {} 00551 00555 ~TransientRCPtr() {} 00556 00560 TransientRCPtr & operator=(const TransientRCPtr & p) { 00561 ptr = p.ptr; 00562 return *this; 00563 } 00564 00569 template <typename UPtr> 00570 TransientRCPtr & operator=(const UPtr & u) { 00571 ptr = PtrTraits<UPtr>::barePointer(u); 00572 return *this; 00573 } 00574 00579 template <typename UPtr> 00580 TransientRCPtr & assignDynamic(const UPtr & u) { 00581 ptr = dynamic_cast<pointer>(PtrTraits<UPtr>::barePointer(u)); 00582 return *this; 00583 } 00584 00589 template <typename UPtr> 00590 TransientRCPtr & assignConst(const UPtr & u) { 00591 ptr = const_cast<pointer>(PtrTraits<UPtr>::barePointer(u)); 00592 return *this; 00593 } 00594 00598 bool operator==(const TransientRCPtr & p) const { return ptr == p.ptr; } 00599 00603 bool operator!=(const TransientRCPtr & p) const { return ptr != p.ptr; } 00604 00608 bool operator==(const_pointer p) const { return ptr == p; } 00609 00613 bool operator!=(const_pointer p) const { return ptr != p; } 00614 00618 template <typename UPtr> 00619 bool operator==(const UPtr & u) const { return ptr == PtrTraits<UPtr>::barePointer(u); } 00620 00624 template <typename UPtr> 00625 bool operator!=(const UPtr & u) const { return ptr != PtrTraits<UPtr>::barePointer(u); } 00626 00630 bool operator<(const TransientRCPtr & p) const { 00631 return ( ptr && p.ptr && ptr->uniqueId != p.ptr->uniqueId ) ? 00632 ptr->uniqueId < p.ptr->uniqueId : ptr < p.ptr; 00633 } 00634 00638 bool operator<(const_pointer p) const { 00639 return ( ptr && p && ptr->uniqueId != p->uniqueId ) ? 00640 ptr->uniqueId < p->uniqueId : ptr < p; 00641 } 00642 00646 bool operator!() const { return !ptr; } 00647 00651 operator T * () const { return ptr; } 00652 00656 pointer operator->() const { return ptr; } 00657 00661 reference operator*() const { return *ptr; } 00662 00663 private: 00664 00668 pointer ptr; 00669 00670 }; 00671 00680 template <typename T> 00681 class TransientConstRCPtr { 00682 00683 public: 00684 00686 typedef void iterator_category; 00688 typedef void difference_type; 00690 typedef T * pointer; 00692 typedef const T * const_pointer; 00694 typedef T & reference; 00696 typedef const T & const_reference; 00698 typedef T value_type; 00699 00700 public: 00701 00705 TransientConstRCPtr() : ptr(0) {} 00706 00710 TransientConstRCPtr(const TransientConstRCPtr & p) : ptr(p.ptr) {} 00711 00716 template <typename UPtr> 00717 TransientConstRCPtr(const UPtr & u) : ptr(PtrTraits<UPtr>::barePointer(u)) {} 00718 00722 explicit TransientConstRCPtr(const_pointer p) : ptr(p) {} 00723 00727 ~TransientConstRCPtr() {} 00728 00732 TransientConstRCPtr & operator=(const TransientConstRCPtr & p) { 00733 ptr = p.ptr; 00734 return *this; 00735 } 00736 00741 template <typename UPtr> 00742 TransientConstRCPtr & operator=(const UPtr & u) { 00743 ptr = PtrTraits<UPtr>::barePointer(u); 00744 return *this; 00745 } 00746 00751 template <typename UPtr> 00752 TransientConstRCPtr & assignDynamic(const UPtr & u) { 00753 ptr = dynamic_cast<const_pointer>(PtrTraits<UPtr>::barePointer(u)); 00754 return *this; 00755 } 00756 00760 bool operator==(const TransientConstRCPtr & p) const { return ptr == p.ptr; } 00761 00765 bool operator!=(const TransientConstRCPtr & p) const { return ptr != p.ptr; } 00766 00770 bool operator==(const_pointer p) const { return ptr == p; } 00771 00772 00776 bool operator!=(const_pointer p) const { return ptr != p; } 00777 00781 template <typename UPtr> 00782 bool operator==(const UPtr & u) const { return ptr == PtrTraits<UPtr>::barePointer(u); } 00783 00787 template <typename UPtr> 00788 bool operator!=(const UPtr & u) const { return ptr != PtrTraits<UPtr>::barePointer(u); } 00789 00793 bool operator<(const TransientConstRCPtr & p) const { 00794 return ( ptr && p.ptr && ptr->uniqueId != p.ptr->uniqueId ) ? 00795 ptr->uniqueId < p.ptr->uniqueId : ptr < p.ptr; 00796 } 00797 00801 bool operator<(const_pointer p) const { 00802 return ( ptr && p && ptr->uniqueId != p->uniqueId ) ? 00803 ptr->uniqueId < p->uniqueId : ptr < p; 00804 } 00805 00809 bool operator!() const { return !ptr; } 00810 00814 operator const T * () const { return ptr; } 00815 00819 const_pointer operator->() const { return ptr; } 00820 00824 const_reference operator*() const { return *ptr; } 00825 00826 private: 00827 00831 const_pointer ptr; 00832 00833 }; 00834 00838 template <typename T> 00839 struct PtrTraits< RCPtr<T> >: public PtrTraitsType { 00840 00842 typedef typename RCPtr<T>::value_type value_type; 00844 typedef typename RCPtr<T>::reference reference; 00846 typedef typename RCPtr<T>::const_reference const_reference; 00848 typedef RCPtr<T> pointer; 00850 typedef ConstRCPtr<T> const_pointer; 00852 typedef TransientRCPtr<T> transient_pointer; 00854 typedef TransientConstRCPtr<T> transient_const_pointer; 00855 00859 static T * barePointer(const RCPtr<T> & p) { return p.operator->(); } 00860 00864 static pointer create() { return RCPtr<T>::Create(); } 00865 00869 static pointer create(const_reference t) { return RCPtr<T>::Create(t); } 00870 00874 static void destroy(pointer tp) {} 00875 00879 template <typename UPtr> 00880 static pointer DynamicCast(const UPtr & u) { 00881 pointer t; 00882 t.assignDynamic(u); 00883 return t; 00884 } 00885 00889 template <typename UPtr> 00890 static pointer ConstCast(const UPtr & u) { 00891 pointer t; 00892 t.assignConst(u); 00893 return t; 00894 } 00895 00899 static pointer PtrCast(T * t) { 00900 return pointer(t); 00901 } 00902 00906 static const bool reference_counted = true; 00907 00908 }; 00909 00913 template <typename T> 00914 struct PtrTraits< ConstRCPtr<T> >: public PtrTraitsType { 00915 00917 typedef typename ConstRCPtr<T>::value_type value_type; 00919 typedef typename ConstRCPtr<T>::reference reference; 00921 typedef typename ConstRCPtr<T>::const_reference const_reference; 00923 typedef RCPtr<T> pointer; 00925 typedef ConstRCPtr<T> const_pointer; 00927 typedef TransientRCPtr<T> transient_pointer; 00929 typedef TransientConstRCPtr<T> transient_const_pointer; 00930 00934 static const T * barePointer(const ConstRCPtr<T> & p) { 00935 return p.operator->(); 00936 } 00937 00941 static const_pointer create() { 00942 return RCPtr<T>::Create(); 00943 } 00944 00948 static const_pointer create(const_reference t) { 00949 return RCPtr<T>::Create(t); 00950 } 00951 00955 static void destroy(const_pointer tp) {} 00956 00960 template <typename UPtr> 00961 static const_pointer DynamicCast(const UPtr & u) { 00962 const_pointer t; 00963 t.assignDynamic(u); 00964 return t; 00965 } 00966 00970 template <typename UPtr> 00971 static const_pointer ConstCast(const UPtr & u) { 00972 const_pointer t; 00973 t.assignDynamic(u); 00974 return t; 00975 } 00976 00980 static const_pointer PtrCast(const T * t) { 00981 return const_pointer(t); 00982 } 00983 00987 static const bool reference_counted = true; 00988 00989 }; 00990 00994 template <typename T> 00995 struct PtrTraits< TransientRCPtr<T> >: public PtrTraitsType { 00996 00998 typedef typename TransientRCPtr<T>::value_type value_type; 01000 typedef typename TransientRCPtr<T>::reference reference; 01002 typedef typename TransientRCPtr<T>::const_reference const_reference; 01004 typedef RCPtr<T> pointer; 01006 typedef ConstRCPtr<T> const_pointer; 01008 typedef TransientRCPtr<T> transient_pointer; 01010 typedef TransientConstRCPtr<T> transient_const_pointer; 01011 01015 static T * barePointer(const TransientRCPtr<T> & p) { 01016 return p.operator->(); 01017 } 01018 01022 static void destroy(transient_pointer tp) {} 01023 01027 template <typename UPtr> 01028 static transient_pointer DynamicCast(const UPtr & u) { 01029 transient_pointer t; 01030 t.assignDynamic(u); 01031 return t; 01032 } 01033 01037 static transient_pointer ConstCast(transient_const_pointer c) { 01038 transient_pointer t; 01039 t.assignConst(c); 01040 return t; 01041 } 01042 01046 static transient_pointer PtrCast(T * t) { 01047 return transient_pointer(t); 01048 } 01049 01053 static const bool reference_counted = false; 01054 01055 }; 01056 01060 template <typename T> 01061 struct PtrTraits< TransientConstRCPtr<T> >: public PtrTraitsType { 01062 01064 typedef typename TransientConstRCPtr<T>::value_type value_type; 01066 typedef typename TransientConstRCPtr<T>::reference reference; 01068 typedef typename TransientConstRCPtr<T>::const_reference const_reference; 01070 typedef RCPtr<T> pointer; 01072 typedef ConstRCPtr<T> const_pointer; 01074 typedef TransientRCPtr<T> transient_pointer; 01076 typedef TransientConstRCPtr<T> transient_const_pointer; 01077 01081 static const T * barePointer(const TransientConstRCPtr<T> & p) { 01082 return p.operator->(); 01083 } 01084 01088 static void destroy(transient_const_pointer tp) {} 01089 01093 template <typename UPtr> 01094 static transient_const_pointer DynamicCast(const UPtr & u) { 01095 transient_const_pointer t; 01096 t.assignDynamic(u); 01097 return t; 01098 } 01099 01103 template <typename UPtr> 01104 static transient_const_pointer ConstCast(const UPtr & u) { 01105 transient_const_pointer t; 01106 t.assignConst(u); 01107 return t; 01108 } 01109 01113 static transient_const_pointer PtrCast(const T * t) { 01114 return transient_const_pointer(t); 01115 } 01116 01120 static const bool reference_counted = false; 01121 01122 }; 01123 01124 } 01125 } 01126 01127 namespace std { 01128 01133 template <typename T> 01134 inline void swap(ThePEG::Pointer::RCPtr<T> & t1, 01135 ThePEG::Pointer::RCPtr<T> & t2) { 01136 t1.swap(t2); 01137 } 01138 01143 template <typename T> 01144 inline void swap(ThePEG::Pointer::ConstRCPtr<T> & t1, 01145 ThePEG::Pointer::ConstRCPtr<T> & t2) { 01146 t1.swap(t2); 01147 } 01148 01149 } 01150 01151 #endif /* ThePEG_RCPtr_H */