Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:38:30

0001 // -*- C++ -*-
0002 //
0003 // RCPtr.h is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 1999-2019 Leif Lonnblad
0005 //
0006 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 #ifndef ThePEG_RCPtr_H
0010 #define ThePEG_RCPtr_H
0011 // This is the declaration of the RCPtrBase,
0012 
0013 
0014 #include "ReferenceCounted.h"
0015 #include "RCPtr.fh"
0016 #include "PtrTraits.h"
0017 
0018 namespace ThePEG {
0019 namespace Pointer {
0020 
0021 /**
0022  * RCPtrBase is the base class of RCPtr and ConstRCPtr which are
0023  * reference counted (smart) pointers. The RCPtrBase class communicates with the
0024  * ReferenceCounted object which must be the base class of
0025  * all objects pointed to and which keeps count of the pointers
0026  * pointing to an object.
0027  *
0028  * @see ReferenceCounted
0029  */
0030 class RCPtrBase {
0031 
0032   /** Get counter type from ReferenceCounted class. */
0033   typedef ReferenceCounted::CounterType CounterType;
0034 
0035 protected:
0036 
0037   /**
0038    * Increment the counter of a reference counted object.
0039    */
0040   void increment(const ReferenceCounted * rcp) {
0041     if ( rcp ) rcp->incrementReferenceCount();
0042   }
0043   /**
0044    * Decrement the counter of a reference counted object.
0045    */
0046   bool release(const ReferenceCounted * rcp) {
0047     return rcp && rcp->decrementReferenceCount();
0048   }
0049 
0050 };
0051 
0052 /**
0053  * RCPtr is a reference counted (smart) pointer. Objects created using
0054  * the RCPtr::create() methods will continue living until no RCPtr or
0055  * ConstRCPtr are pointing to it, at which point it will be deleted.
0056  *
0057  * @see ReferenceCounted
0058  */
0059 template <typename T>
0060 class RCPtr: public RCPtrBase {
0061 
0062 public:
0063 
0064   /** Template argument typedef. */
0065   typedef void iterator_category;
0066   /** Template argument typedef. */
0067   typedef void difference_type;
0068   /** Template argument typedef. */
0069   typedef T * pointer;
0070   /** Template argument typedef. */
0071   typedef const T * const_pointer;
0072   /** Template argument typedef. */
0073   typedef T & reference;
0074   /** Template argument typedef. */
0075   typedef const T & const_reference;
0076   /** Template argument typedef. */
0077   typedef T value_type;
0078 
0079 public:
0080 
0081   /** <code></code> */
0082   /**
0083    * Constructor for null pointer.
0084    */
0085   RCPtr() : ptr(nullptr) {}
0086 
0087   /**
0088    * Constructor for nullptr.
0089    */
0090   RCPtr( decltype(nullptr) ) : ptr(nullptr) {}
0091 
0092   /**
0093    * Copy constructor.
0094    */
0095   RCPtr(const RCPtr & p) : ptr(p.ptr) { increment(); }
0096 
0097   /**
0098    * Copy constructor for class UPtr which has operator-> defined
0099    * resulting in a value implicitly convertible to T *.
0100    */
0101   template <typename UPtr>
0102   RCPtr(const UPtr & u) 
0103     : ptr(PtrTraits<UPtr>::barePointer(u)) { increment(); }
0104 
0105   /**
0106    * Construction from real pointer.
0107    */
0108   explicit RCPtr(pointer p) : ptr(p) { increment(); }
0109 
0110   /**
0111    * Destructor. Deletes the object pointed to if this is the last
0112    * pointer to it.
0113    */
0114   ~RCPtr() { release(); }
0115 
0116   /**
0117    * Allocate and construct an object of class T and return a RCPtr to
0118    * it.
0119    */
0120   static RCPtr Create() {
0121     RCPtr<T> p;
0122     return p.create();
0123   }
0124 
0125   /**
0126    * Allocate and copy-construct an object of class T and return a
0127    * RCPtr to it.
0128    */
0129   static RCPtr Create(const_reference t) {
0130     RCPtr<T> p;
0131     return p.create(t);
0132   }
0133 
0134 
0135   /**
0136    * Allocate and construct an object of class T and point to it,
0137    * possibly deleting the object pointed to before.
0138    */
0139   RCPtr & create() {
0140     release();
0141     ptr = new T;
0142     //  increment(); // ReferenceCounted() constructor starts at 1
0143     return *this;
0144   }
0145 
0146   /**
0147    * Allocate and copy-construct an object of class T and point to it,
0148    * possibly deleting the object pointed to before.
0149    */
0150   RCPtr & create(const_reference t) {
0151     release();
0152     ptr = new T(t);
0153     //  increment(); // ReferenceCounted() constructor starts at 1
0154     return *this;
0155   }
0156 
0157   /**
0158    * Assignment.
0159    */
0160   RCPtr & operator=(const RCPtr & p) {
0161     if ( ptr == p.ptr ) return *this;
0162     release();
0163     ptr = p.ptr;
0164     increment();
0165     return *this;
0166   }
0167 
0168   /**
0169    * Assignment from class UPtr which has operator-> defined resulting
0170    * in a value implicitly convertible to T *.
0171    */
0172   template <typename UPtr>
0173   RCPtr & operator=(const UPtr & u) {
0174     if ( ptr == PtrTraits<UPtr>::barePointer(u) ) return *this;
0175     release();
0176     ptr = PtrTraits<UPtr>::barePointer(u);
0177     increment();
0178     return *this;
0179   }
0180 
0181   /**
0182    * Assignment from class UPtr which has operator-> defined resulting
0183    * in a value which can be cast dynamically to T *.
0184    */
0185   template <typename UPtr>
0186   RCPtr & assignDynamic(const UPtr & u) {
0187     pointer up = dynamic_cast<pointer>(PtrTraits<UPtr>::barePointer(u));
0188     if ( ptr == up ) return *this;
0189     release();
0190     ptr = up;
0191     increment();
0192     return *this;
0193   }
0194 
0195   /**
0196    * Assignment from class UPtr which has operator-> defined resulting
0197    * in a value which can be const_cast'ed to T *.
0198    */
0199   template <typename UPtr>
0200   RCPtr & assignConst(const UPtr & u) {
0201     pointer up = const_cast<pointer>(PtrTraits<UPtr>::barePointer(u));
0202     if ( ptr == up ) return *this;
0203     release();
0204     ptr = up;
0205     increment();
0206     return *this;
0207   }
0208 
0209   /**
0210    * Make p point to the object pointed to by this and vice versa.  
0211    */
0212   void swap(RCPtr & p) {
0213     const pointer tmp = ptr;
0214     ptr = p.ptr;
0215     p.ptr = tmp;
0216     //  std::swap(ptr, p.ptr);
0217   }
0218 
0219   /**
0220    * Test for equality of the underlying pointers.
0221    */
0222   bool operator==(const RCPtr & p) const { return ptr == p.ptr; }
0223 
0224   /**
0225    * Test for inequality of the underlying pointers.
0226    */
0227   bool operator!=(const RCPtr & p) const { return ptr != p.ptr; }
0228 
0229   /**
0230    * Test for equality of the underlying pointers.
0231    */
0232   bool operator==(const_pointer p) const { return ptr == p; }
0233 
0234   /**
0235    * Test for inequality of the underlying pointers.
0236    */
0237   bool operator!=(const_pointer p) const { return ptr != p; }
0238 
0239   /**
0240    * Test for equality of the underlying pointers.
0241    */
0242   template <typename UPtr>
0243   bool operator==(const UPtr & u) const {
0244     return ptr == PtrTraits<UPtr>::barePointer(u);
0245   }
0246 
0247   /**
0248    * Test for inequality of the underlying pointers.
0249    */
0250   template <typename UPtr>
0251   bool operator!=(const UPtr & u) const {
0252     return ptr != PtrTraits<UPtr>::barePointer(u);
0253   }
0254 
0255   /**
0256    * Test for ordering.
0257    */
0258   bool operator<(const RCPtr & p) const {
0259     return ( ptr && p.ptr && ptr->uniqueId != p.ptr->uniqueId ) ?
0260       ptr->uniqueId < p.ptr->uniqueId : ptr < p.ptr;
0261   }
0262 
0263   /**
0264    * Test for ordering.
0265    */
0266   bool operator<(const_pointer p) const {
0267     return ( ptr && p && ptr->uniqueId != p->uniqueId ) ?
0268       ptr->uniqueId < p->uniqueId : ptr < p;
0269   }
0270 
0271   /**
0272    * Returns true if the underlying pointer is null.
0273    */
0274   bool operator!() const { return !ptr; }
0275 
0276   /**
0277    * Returns the underlying pointer.
0278    */
0279   operator T * () const { return ptr; }
0280 
0281   /**
0282    * Member access.
0283    */
0284   pointer operator->() const { return ptr; }
0285 
0286   /**
0287    * Dereferencing.
0288    */
0289   reference operator*() const { return *ptr; }
0290 
0291 private:
0292 
0293   /**
0294    * Increment the counter of the object pointed to.
0295    */
0296   void increment() { RCPtrBase::increment(ptr); }
0297 
0298   /**
0299    * Stop pointing to the current object and delete it if this was the
0300    * last pointer to it.
0301    */
0302   void release() { if ( RCPtrBase::release(ptr) )  delete ptr; }
0303    
0304   /**
0305    * The actual pointer.
0306    */
0307   pointer ptr;
0308 
0309 };
0310 
0311 /**
0312  * ConstRCPtr is a reference counted (smart) const pointer. Objects
0313  * created using the RCPtr::create() methods will continue living
0314  * until no RCPtr or ConstRCPtr are pointing to it, at which point it
0315  * will be deleted.
0316  *
0317  * @see ReferenceCounted
0318  */
0319 template <typename T>
0320 class ConstRCPtr : public RCPtrBase {
0321 
0322 public:
0323 
0324   /** Template argument typedef. */
0325   typedef void iterator_category;
0326   /** Template argument typedef. */
0327   typedef void difference_type;
0328   /** Template argument typedef. */
0329   typedef T * pointer;
0330   /** Template argument typedef. */
0331   typedef const T * const_pointer;
0332   /** Template argument typedef. */
0333   typedef T & reference;
0334   /** Template argument typedef. */
0335   typedef const T & const_reference;
0336   /** Template argument typedef. */
0337   typedef T value_type;
0338 
0339 public:
0340 
0341   /**
0342    * Constructor for null pointer.
0343    */
0344   ConstRCPtr() : ptr(nullptr) {}
0345 
0346   /**
0347    * Constructor for nullptr.
0348    */
0349   ConstRCPtr( decltype(nullptr) ) : ptr(nullptr) {}
0350 
0351   /**
0352    * Copy constructor.
0353    */
0354   ConstRCPtr(const ConstRCPtr & p) : ptr(p.ptr) { increment(); }
0355 
0356   /**
0357    * Copyconstructor for class UPtr which has operator-> defined
0358    * resulting in a value implicitly convertible to const T *.
0359    */
0360   template <typename UPtr>
0361   ConstRCPtr(const UPtr & u) : ptr(PtrTraits<UPtr>::barePointer(u)) { increment(); }
0362 
0363   /**
0364    * Construction from real pointer.
0365    */
0366   explicit ConstRCPtr(const_pointer p) : ptr(p) { increment(); }
0367 
0368   /**
0369    * Destructor. Deletes the object pointed to if this is the last
0370    * pointer to it.
0371    */
0372   ~ConstRCPtr() { release(); }
0373 
0374   /**
0375    * Assignment.
0376    */
0377   ConstRCPtr & operator=(const ConstRCPtr & p) {
0378     if ( ptr == p.ptr ) return *this;
0379     release();
0380     ptr = p.ptr;
0381     increment();
0382     return *this;
0383   }
0384   
0385   /**
0386    * Assignment from class UPtr which has operator-> defined resulting
0387    * in a value implicitly convertible to const T *.
0388    */
0389   template <typename UPtr>
0390   ConstRCPtr & operator=(const UPtr & u) {
0391     if ( ptr == PtrTraits<UPtr>::barePointer(u) ) return *this;
0392     release();
0393     ptr = PtrTraits<UPtr>::barePointer(u);
0394     increment();
0395     return *this;
0396   }
0397 
0398   /**
0399    * Assignment from class UPtr which has operator-> defined resulting
0400    * in a value which can be cast dynamically to const T *.
0401    */
0402   template <typename UPtr>
0403   ConstRCPtr & assignDynamic(const UPtr & u) {
0404     const_pointer up =
0405       dynamic_cast<const_pointer>(PtrTraits<UPtr>::barePointer(u));
0406     if ( ptr == up ) return *this;
0407     release();
0408     ptr = up;
0409     increment();
0410     return *this;
0411   }
0412 
0413   /**
0414    * Make p point to the object pointed to by this and vice versa.  
0415    */
0416   void swap(ConstRCPtr & p) {
0417     const const_pointer tmp = ptr;
0418     ptr = p.ptr;
0419     p.ptr = tmp;
0420     //  std::swap(ptr, p.ptr);
0421   }  
0422 
0423   /**
0424    * Test for equality of the underlying pointers.
0425    */
0426   bool operator==(const ConstRCPtr & p) const { return ptr == p.ptr; }
0427 
0428   /**
0429    * Test for inequality of the underlying pointers.
0430    */
0431   bool operator!=(const ConstRCPtr & p) const { return ptr != p.ptr; }
0432 
0433   /**
0434    * Test for equality of the underlying pointers.
0435    */
0436   bool operator==(const_pointer p) const { return ptr == p; }
0437 
0438   /**
0439    * Test for inequality of the underlying pointers.
0440    */
0441   bool operator!=(const_pointer p) const { return ptr != p; }
0442 
0443   /**
0444    * Test for equality of the underlying pointers.
0445    */
0446   template <typename UPtr>
0447     bool operator==(const UPtr & u) const { return ptr == PtrTraits<UPtr>::barePointer(u); }
0448 
0449   /**
0450    * Test for inequality of the underlying pointers.
0451    */
0452   template <typename UPtr>
0453   bool operator!=(const UPtr & u) const { return ptr != PtrTraits<UPtr>::barePointer(u); }
0454 
0455   /**
0456    * Test for ordering.
0457    */
0458   bool operator<(const ConstRCPtr & p) const {
0459     return ( ptr && p.ptr && ptr->uniqueId != p.ptr->uniqueId ) ?
0460       ptr->uniqueId < p.ptr->uniqueId : ptr < p.ptr;
0461   }
0462 
0463   /**
0464    * Test for ordering.
0465    */
0466   bool operator<(const_pointer p) const {
0467     return ( ptr && p && ptr->uniqueId != p->uniqueId ) ?
0468       ptr->uniqueId < p->uniqueId : ptr < p;
0469   }
0470 
0471   /**
0472    * Returns true if the underlying pointer is null.
0473    */
0474   bool operator!() const { return !ptr; }
0475 
0476   /**
0477    * Returns the underlying pointer.
0478    */
0479   operator const T * () const { return ptr; }
0480 
0481   /**
0482    * Member access.
0483    */
0484   const_pointer operator->() const { return ptr; }
0485 
0486   /**
0487    * Dereferencing.
0488    */
0489   const_reference operator*() const { return *ptr; }
0490 
0491 private:
0492 
0493   /**
0494    * Increment the counter of the object pointed to.
0495    */
0496   void increment() { RCPtrBase::increment(ptr); }
0497 
0498   /**
0499    * Stop pointing to the current object and delete it if this was the
0500    * last pointer to it.
0501    */
0502   void release() { if ( RCPtrBase::release(ptr) ) delete ptr; }
0503    
0504   /**
0505    * The actual pointer.
0506    */
0507   const_pointer ptr;
0508 
0509 };
0510 
0511 /**
0512  * TransientRCPtr is a simple wrapper around a bare pointer which can
0513  * be assigned to and from an RCPtr and ConstRCPtr without problem.
0514  *
0515  * @see RCPtr
0516  * @see ConstRCPtr
0517  */
0518 template <typename T>
0519 class TransientRCPtr {
0520 
0521 public:
0522 
0523   /** Template argument typedef. */
0524   typedef void iterator_category;
0525   /** Template argument typedef. */
0526   typedef void difference_type;
0527   /** Template argument typedef. */
0528   typedef T * pointer;
0529   /** Template argument typedef. */
0530   typedef const T * const_pointer;
0531   /** Template argument typedef. */
0532   typedef T & reference;
0533   /** Template argument typedef. */
0534   typedef const T & const_reference;
0535   /** Template argument typedef. */
0536   typedef T value_type;
0537 
0538 public:
0539 
0540   /**
0541    * Constructor for null pointer.
0542    */
0543   TransientRCPtr() : ptr(nullptr) {}
0544 
0545   /**
0546    * Constructor for nullptr.
0547    */
0548   TransientRCPtr( decltype(nullptr) ) : ptr(nullptr) {}
0549 
0550   /**
0551    * Copy constructor.
0552    */
0553   TransientRCPtr(const TransientRCPtr & p) : ptr(p.ptr) {}
0554 
0555   /**
0556    * Copyconstructor for class UPtr which has operator-> defined
0557    * resulting in a value implicitly convertible to T *.
0558    */
0559   template <typename UPtr>
0560   TransientRCPtr(const UPtr & u) : ptr(PtrTraits<UPtr>::barePointer(u)) {}
0561 
0562   /**
0563    * Construction from real pointer.
0564    */
0565   explicit TransientRCPtr(pointer p) : ptr(p) {}
0566 
0567   /**
0568    * Destructor. Does not delete the object pointed to.
0569    */
0570   ~TransientRCPtr() {}
0571 
0572   /**
0573    * Assignment.
0574    */
0575   TransientRCPtr & operator=(const TransientRCPtr & p) {
0576     ptr = p.ptr;
0577     return *this;
0578   }
0579 
0580   /**
0581    * Assignment from class UPtr which has operator-> defined resulting
0582    * in a value implicitly convertible to T *.
0583    */
0584   template <typename UPtr>
0585   TransientRCPtr & operator=(const UPtr & u) {
0586     ptr = PtrTraits<UPtr>::barePointer(u);
0587     return *this;
0588   }
0589 
0590   /**
0591    * Assignment from class UPtr which has operator-> defined resulting
0592    * in a value which can be cast dynamically to T *.
0593    */
0594   template <typename UPtr>
0595   TransientRCPtr & assignDynamic(const UPtr & u) {
0596     ptr = dynamic_cast<pointer>(PtrTraits<UPtr>::barePointer(u));
0597     return *this;
0598   }
0599 
0600   /**
0601    * Assignment from class UPtr which has operator-> defined resulting
0602    * in a value whcih can be const_cast'ed to T *.
0603    */
0604   template <typename UPtr>
0605   TransientRCPtr & assignConst(const UPtr & u) {
0606     ptr = const_cast<pointer>(PtrTraits<UPtr>::barePointer(u));
0607     return *this;
0608   }
0609 
0610   /**
0611    * Test for equality of the underlying pointers.
0612    */
0613   bool operator==(const TransientRCPtr & p) const { return ptr == p.ptr; }
0614 
0615   /**
0616    * Test for inequality of the underlying pointers.
0617    */
0618   bool operator!=(const TransientRCPtr & p) const { return ptr != p.ptr; }
0619 
0620   /**
0621    * Test for equality of the underlying pointers.
0622    */
0623   bool operator==(const_pointer p) const { return ptr == p; }
0624 
0625   /**
0626    * Test for inequality of the underlying pointers.
0627    */
0628   bool operator!=(const_pointer p) const { return ptr != p; }
0629 
0630   /**
0631    * Test for equality of the underlying pointers.
0632    */
0633   template <typename UPtr>
0634   bool operator==(const UPtr & u) const { return ptr == PtrTraits<UPtr>::barePointer(u); }
0635 
0636   /**
0637    * Test for inequality of the underlying pointers.
0638    */
0639   template <typename UPtr>
0640   bool operator!=(const UPtr & u) const { return ptr != PtrTraits<UPtr>::barePointer(u); }
0641 
0642   /**
0643    * Test for ordering.
0644    */
0645   bool operator<(const TransientRCPtr & p) const {
0646     return ( ptr && p.ptr && ptr->uniqueId != p.ptr->uniqueId ) ?
0647       ptr->uniqueId < p.ptr->uniqueId : ptr < p.ptr;
0648   }
0649 
0650   /**
0651    * Test for ordering.
0652    */
0653   bool operator<(const_pointer p) const {
0654     return ( ptr && p && ptr->uniqueId != p->uniqueId ) ?
0655       ptr->uniqueId < p->uniqueId : ptr < p;
0656   }
0657 
0658   /**
0659    * Returns true if the underlying pointer is null.
0660    */
0661   bool operator!() const { return !ptr; }
0662 
0663   /**
0664    * Returns the underlying pointer.
0665    */
0666   operator T * () const { return ptr; }
0667 
0668   /**
0669    * Member access.
0670    */
0671   pointer operator->() const { return ptr; }
0672 
0673   /**
0674    * Dereferencing.
0675    */
0676   reference operator*() const { return *ptr; }
0677 
0678 private:
0679 
0680   /**
0681    * The actual pointer.
0682    */
0683   pointer ptr;
0684 
0685 };
0686 
0687 /**
0688  * TransientConstRCPtr is a simple wrapper around a bare const pointer
0689  * which can be assigned to and from an RCPtr and ConstRCPtr without
0690  * problem.
0691  *
0692  * @see RCPtr
0693  * @see ConstRCPtr
0694  */
0695 template <typename T>
0696 class TransientConstRCPtr {
0697 
0698 public:
0699 
0700   /** Template argument typedef. */
0701   typedef void iterator_category;
0702   /** Template argument typedef. */
0703   typedef void difference_type;
0704   /** Template argument typedef. */
0705   typedef T * pointer;
0706   /** Template argument typedef. */
0707   typedef const T * const_pointer;
0708   /** Template argument typedef. */
0709   typedef T & reference;
0710   /** Template argument typedef. */
0711   typedef const T & const_reference;
0712   /** Template argument typedef. */
0713   typedef T value_type;
0714 
0715 public:
0716 
0717   /**
0718    * Constructor for null pointer.
0719    */
0720   TransientConstRCPtr() : ptr(nullptr) {}
0721 
0722   /**
0723    * Constructor for nullptr.
0724    */
0725   TransientConstRCPtr( decltype(nullptr) ) : ptr(nullptr) {}
0726 
0727   /**
0728    * Copy constructor.
0729    */
0730   TransientConstRCPtr(const TransientConstRCPtr & p) : ptr(p.ptr) {}
0731 
0732   /**
0733    * Copyconstructor for class UPtr which has operator-> defined
0734    * resulting in a value implicitly convertible to const T *.
0735    */
0736   template <typename UPtr>
0737   TransientConstRCPtr(const UPtr & u) : ptr(PtrTraits<UPtr>::barePointer(u)) {}
0738 
0739   /**
0740    * Construction from real pointer.
0741    */
0742   explicit TransientConstRCPtr(const_pointer p) : ptr(p) {}
0743 
0744   /**
0745    * Destructor. Does not delete the object pointed to.
0746    */
0747   ~TransientConstRCPtr() {}
0748 
0749   /**
0750    * Assignment.
0751    */
0752   TransientConstRCPtr & operator=(const TransientConstRCPtr & p) {
0753     ptr = p.ptr;
0754     return *this;
0755   }
0756 
0757   /**
0758    * Assignment from class UPtr which has operator-> defined resulting
0759    * in a value implicitly convertible to const T *.
0760    */
0761   template <typename UPtr>
0762   TransientConstRCPtr & operator=(const UPtr & u) {
0763     ptr = PtrTraits<UPtr>::barePointer(u);
0764     return *this;
0765   }
0766 
0767   /**
0768    * Assignment from class UPtr which has operator-> defined resulting
0769    * in a value which can be cast dynamically to const T *.
0770    */
0771   template <typename UPtr>
0772   TransientConstRCPtr & assignDynamic(const UPtr & u) {
0773     ptr = dynamic_cast<const_pointer>(PtrTraits<UPtr>::barePointer(u));
0774     return *this;
0775   }
0776 
0777   /**
0778    * Test for equality of the underlying pointers.
0779    */
0780   bool operator==(const TransientConstRCPtr & p) const { return ptr == p.ptr; }
0781 
0782   /**
0783    * Test for inequality of the underlying pointers.
0784    */
0785   bool operator!=(const TransientConstRCPtr & p) const { return ptr != p.ptr; }
0786 
0787   /**
0788    * Test for equality of the underlying pointers.
0789    */
0790   bool operator==(const_pointer p) const { return ptr == p; }
0791 
0792 
0793   /**
0794    * Test for inequality of the underlying pointers.
0795    */
0796   bool operator!=(const_pointer p) const { return ptr != p; }
0797 
0798   /**
0799    * Test for equality of the underlying pointers.
0800    */
0801   template <typename UPtr>
0802   bool operator==(const UPtr & u) const { return ptr == PtrTraits<UPtr>::barePointer(u); }
0803 
0804   /**
0805    * Test for inequality of the underlying pointers.
0806    */
0807   template <typename UPtr>
0808   bool operator!=(const UPtr & u) const { return ptr != PtrTraits<UPtr>::barePointer(u); }
0809 
0810   /**
0811    * Test for ordering.
0812    */
0813   bool operator<(const TransientConstRCPtr & p) const {
0814     return ( ptr && p.ptr && ptr->uniqueId != p.ptr->uniqueId ) ?
0815       ptr->uniqueId < p.ptr->uniqueId : ptr < p.ptr;
0816   }
0817 
0818   /**
0819    * Test for ordering.
0820    */
0821   bool operator<(const_pointer p) const {
0822     return ( ptr && p && ptr->uniqueId != p->uniqueId ) ?
0823       ptr->uniqueId < p->uniqueId : ptr < p;
0824   }
0825 
0826   /**
0827    * Returns true if the underlying pointer is null.
0828    */
0829   bool operator!() const { return !ptr; }
0830 
0831   /**
0832    * Returns (not) the underlying pointer.
0833    */
0834   operator const T * () const { return ptr; }
0835 
0836   /**
0837    * Member access.
0838    */
0839   const_pointer operator->() const { return ptr; }
0840 
0841   /**
0842    * Dereferencing.
0843    */
0844   const_reference operator*() const { return *ptr; }
0845 
0846 private:
0847 
0848   /**
0849    * The actual pointer.
0850    */
0851   const_pointer ptr;
0852 
0853 };
0854 
0855 /**
0856  * Specialization of the PtrTraits class for RCPtr.
0857  */
0858 template <typename T>
0859 struct PtrTraits< RCPtr<T> >: public PtrTraitsType {
0860 
0861   /** Template argument typedef. */
0862   typedef typename RCPtr<T>::value_type value_type;
0863   /** Template argument typedef. */
0864   typedef typename RCPtr<T>::reference reference;
0865   /** Template argument typedef. */
0866   typedef typename RCPtr<T>::const_reference const_reference;
0867   /** Template argument typedef. */
0868   typedef RCPtr<T> pointer;
0869   /** Template argument typedef. */
0870   typedef ConstRCPtr<T> const_pointer;
0871   /** Template argument typedef. */
0872   typedef TransientRCPtr<T> transient_pointer;
0873   /** Template argument typedef. */
0874   typedef TransientConstRCPtr<T> transient_const_pointer;
0875 
0876   /**
0877    * Return the bare pointer of the given pointer object.
0878    */
0879   static T * barePointer(const RCPtr<T> & p) { return p.operator->(); }
0880 
0881   /**
0882    * Create an object and return a pointer to it.
0883    */
0884   static pointer create() { return RCPtr<T>::Create(); }
0885 
0886   /**
0887    * Create an copy of an object and return a pointer to it.
0888    */
0889   static pointer create(const_reference t) { return RCPtr<T>::Create(t); }
0890 
0891   /**
0892    * Destroy the object pointed to.
0893    */
0894   static void destroy(pointer) {}
0895 
0896   /**
0897    * Cast dynamically.
0898    */
0899   template <typename UPtr>
0900   static pointer DynamicCast(const UPtr & u) {
0901     pointer t;
0902     t.assignDynamic(u);
0903     return t;
0904   }
0905 
0906   /**
0907    * Cast away constness.
0908    */
0909   template <typename UPtr>
0910   static pointer ConstCast(const UPtr & u) {
0911     pointer t;
0912     t.assignConst(u);
0913     return t;
0914   }
0915 
0916   /**
0917    * Cast from a basic pointer.
0918    */
0919   static pointer PtrCast(T * t) {
0920     return pointer(t);
0921   }
0922 
0923   /**
0924    * RCPtr is reference counted.
0925    */
0926   static const bool reference_counted = true;
0927 
0928 }; 
0929 
0930 /**
0931  * Specialization of the PtrTraits class for ConstRCPtr.
0932  */
0933 template <typename T>
0934 struct PtrTraits< ConstRCPtr<T> >: public PtrTraitsType {
0935 
0936   /** Template argument typedef. */
0937   typedef typename ConstRCPtr<T>::value_type value_type;
0938   /** Template argument typedef. */
0939   typedef typename ConstRCPtr<T>::reference reference;
0940   /** Template argument typedef. */
0941   typedef typename ConstRCPtr<T>::const_reference const_reference;
0942   /** Template argument typedef. */
0943   typedef RCPtr<T> pointer;
0944   /** Template argument typedef. */
0945   typedef ConstRCPtr<T> const_pointer;
0946   /** Template argument typedef. */
0947   typedef TransientRCPtr<T> transient_pointer;
0948   /** Template argument typedef. */
0949   typedef TransientConstRCPtr<T> transient_const_pointer;
0950 
0951   /**
0952    * Return the bare pointer of the given pointer object.
0953    */
0954   static const T * barePointer(const ConstRCPtr<T> & p) {
0955     return p.operator->();
0956   }
0957 
0958   /**
0959    * Create an object and return a pointer to it.
0960    */
0961   static const_pointer create() {
0962     return RCPtr<T>::Create();
0963   }
0964 
0965   /**
0966    * Create an copy of an object and return a pointer to it.
0967    */
0968   static const_pointer create(const_reference t) {
0969     return RCPtr<T>::Create(t);
0970   }
0971 
0972   /**
0973    * Destroy the object pointed to.
0974    */
0975   static void destroy(const_pointer) {}
0976 
0977   /**
0978    * Cast dynamically.
0979    */
0980   template <typename UPtr>
0981   static const_pointer DynamicCast(const UPtr & u) {
0982     const_pointer t;
0983     t.assignDynamic(u);
0984     return t;
0985   }
0986 
0987   /**
0988    * Cast away constness.
0989    */
0990   template <typename UPtr>
0991   static const_pointer ConstCast(const UPtr & u) {
0992     const_pointer t;
0993     t.assignDynamic(u);
0994     return t;
0995   }
0996 
0997   /**
0998    * Cast from a basic pointer.
0999    */
1000   static const_pointer PtrCast(const T * t) {
1001     return const_pointer(t);
1002   }
1003 
1004   /**
1005    * ConstRCPtr is reference counted.
1006    */
1007   static const bool reference_counted = true;
1008 
1009 }; 
1010 
1011 /**
1012  * Specialization of the PtrTraits class for TransientRCPtr.
1013  */
1014 template <typename T>
1015 struct PtrTraits< TransientRCPtr<T> >: public PtrTraitsType {
1016 
1017   /** Template argument typedef. */
1018   typedef typename TransientRCPtr<T>::value_type value_type;
1019   /** Template argument typedef. */
1020   typedef typename TransientRCPtr<T>::reference reference;
1021   /** Template argument typedef. */
1022   typedef typename TransientRCPtr<T>::const_reference const_reference;
1023   /** Template argument typedef. */
1024   typedef RCPtr<T> pointer;
1025   /** Template argument typedef. */
1026   typedef ConstRCPtr<T> const_pointer;
1027   /** Template argument typedef. */
1028   typedef TransientRCPtr<T> transient_pointer;
1029   /** Template argument typedef. */
1030   typedef TransientConstRCPtr<T> transient_const_pointer;
1031 
1032   /**
1033    * Return the bare pointer of the given pointer object.
1034    */
1035   static T * barePointer(const TransientRCPtr<T> & p) {
1036     return p.operator->();
1037   }
1038 
1039   /**
1040    * Destroy the object pointed to.
1041    */
1042   static void destroy(transient_pointer) {}
1043 
1044   /**
1045    * Cast dynamically.
1046    */
1047   template <typename UPtr>
1048   static transient_pointer DynamicCast(const UPtr & u) {
1049     transient_pointer t;
1050     t.assignDynamic(u);
1051     return t;
1052   }
1053 
1054   /**
1055    * Cast away constness.
1056    */
1057   static transient_pointer ConstCast(transient_const_pointer c) {
1058     transient_pointer t;
1059     t.assignConst(c);
1060     return t;
1061   }
1062 
1063   /**
1064    * Cast from a basic pointer.
1065    */
1066    static transient_pointer PtrCast(T * t) {
1067     return transient_pointer(t);
1068   }
1069 
1070   /**
1071    * TransientRCPtr is not reference counted.
1072    */
1073   static const bool reference_counted = false;
1074 
1075 }; 
1076 
1077 /**
1078  * Specialization of the PtrTraits class for TransientConstRCPtr.
1079  */
1080 template <typename T>
1081 struct PtrTraits< TransientConstRCPtr<T> >: public PtrTraitsType {
1082 
1083   /** Template argument typedef. */
1084   typedef typename TransientConstRCPtr<T>::value_type value_type;
1085   /** Template argument typedef. */
1086   typedef typename TransientConstRCPtr<T>::reference reference;
1087   /** Template argument typedef. */
1088   typedef typename TransientConstRCPtr<T>::const_reference const_reference;
1089   /** Template argument typedef. */
1090   typedef RCPtr<T> pointer;
1091   /** Template argument typedef. */
1092   typedef ConstRCPtr<T> const_pointer;
1093   /** Template argument typedef. */
1094   typedef TransientRCPtr<T> transient_pointer;
1095   /** Template argument typedef. */
1096   typedef TransientConstRCPtr<T> transient_const_pointer;
1097 
1098   /**
1099    * Return the bare pointer of the given pointer object.
1100    */
1101   static const T * barePointer(const TransientConstRCPtr<T> & p) {
1102     return p.operator->();
1103   }
1104 
1105   /**
1106    * Destroy the object pointed to.
1107    */
1108   static void destroy(transient_const_pointer) {}
1109 
1110   /**
1111    * Cast dynamically.
1112    */
1113   template <typename UPtr>
1114   static transient_const_pointer DynamicCast(const UPtr & u) {
1115     transient_const_pointer t;
1116     t.assignDynamic(u);
1117     return t;
1118   }
1119 
1120   /**
1121    * Cast away constness.
1122    */
1123   template <typename UPtr>
1124   static transient_const_pointer ConstCast(const UPtr & u) {
1125     transient_const_pointer t;
1126     t.assignConst(u);
1127     return t;
1128   }
1129 
1130   /**
1131    * Cast from a basic pointer.
1132    */
1133   static transient_const_pointer PtrCast(const T * t) {
1134     return transient_const_pointer(t);
1135   }
1136 
1137   /**
1138    * TransientConstRCPtr is not reference counted.
1139    */
1140   static const bool reference_counted = false;
1141 
1142 }; 
1143 
1144 }
1145 }
1146 
1147 namespace std {
1148 
1149 /**
1150  * Specialization of std::swap to avoid unnecessary (in/de)crements of
1151  * the reference count.
1152  */
1153 template <typename T>
1154 inline void swap(ThePEG::Pointer::RCPtr<T> & t1, 
1155          ThePEG::Pointer::RCPtr<T> & t2) {
1156   t1.swap(t2);
1157 }
1158 
1159 /**
1160  * Specialization of std::swap to avoid unnecessary (in/de)crements of
1161  * the reference count.
1162  */
1163 template <typename T>
1164 inline void swap(ThePEG::Pointer::ConstRCPtr<T> & t1,
1165          ThePEG::Pointer::ConstRCPtr<T> & t2) {
1166   t1.swap(t2);
1167 }
1168 
1169 }
1170 
1171 #endif /* ThePEG_RCPtr_H */