CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/DataFormats/Common/interface/FwdRef.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_FwdRef_h
00002 #define DataFormats_Common_FwdRef_h
00003 
00004 /*----------------------------------------------------------------------
00005   
00006 FwdRef: A template for a interproduct reference to a member of a product.
00007 
00008 ----------------------------------------------------------------------*/
00084 /*----------------------------------------------------------------------
00085 //  This defines the public interface to the class FwdRef<C, T, F>.
00086 //  C                         is the collection type.
00087 //  T (default C::value_type) is the type of an element in the collection.
00088 //
00089 //  ProductID productID       is the product ID of the collection.
00090 //  key_type itemKey          is the key of the element in the collection.
00091 //  C::value_type *itemPtr    is a C++ pointer to the element 
00092 //  FwdRef<C, T, F> const& ref   is another FwdRef<C, T, F>
00093 
00094 //  Constructors
00095     FwdRef(); // Default constructor
00096     FwdRef(FwdRef<C, T> const& ref);    // Copy constructor  (default, not explicitly specified)
00097 
00098     FwdRef(Ref<C,T,F> const & fwdRef, Ref<C,T,F> const & backRef);
00099 
00100 //  Destructor
00101     virtual ~FwdRef() {}
00102 
00103     // Operators and methods
00104     FwdRef<C, T>& operator=(FwdRef<C, T> const&);               // assignment (default, not explicitly specified)
00105     T const& operator*() const;                 // dereference
00106     T const* const operator->() const;          // member dereference
00107     bool operator==(FwdRef<C, T> const& ref) const; // equality
00108     bool operator!=(FwdRef<C, T> const& ref) const; // inequality
00109     bool operator<(FwdRef<C, T> const& ref) const; // ordering
00110     bool isNonnull() const;                     // true if an object is referenced
00111     bool isNull() const;                        // equivalent to !isNonnull()
00112     bool operator!() const;                     // equivalent to !isNonnull()
00113     ----------------------------------------------------------------------*/ 
00114 
00115 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00116 #include "DataFormats/Common/interface/Ref.h"
00117 
00118 namespace edm {
00119 
00120   template <typename C, 
00121             typename T = typename refhelper::ValueTrait<C>::value, 
00122             typename F = typename refhelper::FindTrait<C, T>::value>
00123   class FwdRef {
00124 
00125 
00126   public:
00128     typedef C product_type;
00129     typedef T value_type; 
00130     typedef T const element_type; //used for generic programming
00131     typedef F finder_type;
00132     typedef typename boost::binary_traits<F>::second_argument_type argument_type;
00133     typedef typename boost::remove_cv<typename boost::remove_reference<argument_type>::type>::type key_type;   
00136 
00138     FwdRef() : ref_(), backRef_() {}
00139 
00141     FwdRef(Ref<C,T,F> const & ref,
00142            Ref<C,T,F> const & backRef) :
00143         ref_(ref), backRef_(backRef) {}
00144   
00146     ~FwdRef() {}
00147 
00149     T const&
00150     operator*() const;
00151 
00153     T const*
00154     operator->() const;
00155 
00157     T const* get() const {
00158       if ( ref_.isNonnull() ) {
00159         return ref_.get();
00160       } else if ( backRef_.isNonnull() ) {
00161         return backRef_.get();
00162       } else {
00163         return 0;
00164       }
00165     }
00166 
00168     bool isNull() const {return !isNonnull(); }
00169 
00171     //bool isNonnull() const {return id().isValid(); }
00172     bool isNonnull() const { return ref_.isNonnull() || backRef_.isNonnull(); }
00173 
00175     bool operator!() const {return isNull();}
00176 
00177     Ref<C,T,F> const & ref() const { return ref_; }
00178     Ref<C,T,F> const & backRef() const { return backRef_; }
00179 
00181     EDProductGetter const* productGetter() const {
00182       if ( ref_.productGetter() ) return ref_.productGetter();
00183       else return backRef_.productGetter();
00184     }
00185 
00187     // Accessor must get the product if necessary
00188     C const* product() const;
00189 
00191     ProductID id() const {return ref_.isNonnull() ? ref_.id() : backRef_.id();}
00192 
00193 
00195     key_type key() const {return ref_.isNonnull() ? ref_.key() : backRef_.key() ;}
00196 
00197     bool hasProductCache() const {return ref_.hasProductCache() || backRef_.hasProductCache();}
00198 
00201     bool isAvailable() const {return ref_.isAvailable() || backRef_.isAvailable();}
00202 
00204     bool isTransient() const {return ref_.isTransient();}
00205 
00206     //Used by ROOT storage
00207     CMS_CLASS_VERSION(10)
00208 
00209   private:
00210     Ref<C,T,F> ref_;
00211     Ref<C,T,F> backRef_;
00212   };
00213 }
00214 
00215 #include "DataFormats/Common/interface/RefProd.h"
00216 
00217 namespace edm {
00218 
00219 
00221   // Accessor must get the product if necessary
00222   template <typename C, typename T, typename F>
00223   inline
00224   C const*
00225   FwdRef<C, T, F>::product() const {
00226     return ref_.isNonnull() && ref_.isAvailable() ? 
00227       ref_.product() :
00228       backRef_.product();
00229   }
00230 
00232   template <typename C, typename T, typename F>
00233   inline
00234   T const&
00235   FwdRef<C, T, F>::operator*() const {
00236     return ref_.isNonnull() && ref_.isAvailable() ?
00237       ref_.operator*() :
00238       backRef_.operator*();
00239   }
00240 
00242   template <typename C, typename T, typename F>
00243   inline
00244   T const*
00245   FwdRef<C, T, F>::operator->() const {
00246     return ref_.isNonnull() && ref_.isAvailable() ?
00247       ref_.operator->() :
00248       backRef_.operator->();
00249   }
00250 
00251 
00254   template <typename C, typename T, typename F>
00255   inline
00256   bool
00257   operator==(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) {
00258     return 
00259     (lhs.ref() == rhs.ref() ) &&
00260     (lhs.backRef() == rhs.backRef() )
00261     ;
00262   }
00263 
00266   template <typename C, typename T, typename F>
00267   inline
00268   bool
00269   operator==(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) {
00270     return 
00271     (lhs == rhs.ref() )    ||
00272     (lhs == rhs.backRef() )
00273     ;
00274   }
00275 
00278   template <typename C, typename T, typename F>
00279   inline
00280   bool
00281   operator==(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00282     return 
00283     (lhs.ref() == rhs )    ||
00284     (lhs.backRef() == rhs )
00285     ;
00286   }
00287 
00288 
00289 
00290   template <typename C, typename T, typename F>
00291   inline
00292   bool
00293   operator!=(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) {
00294     return !(lhs == rhs);
00295   }
00296 
00297   template <typename C, typename T, typename F>
00298   inline
00299   bool
00300   operator!=(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) {
00301     return !(lhs == rhs);
00302   }
00303 
00304   template <typename C, typename T, typename F>
00305   inline
00306   bool
00307   operator!=(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00308     return !(lhs == rhs);
00309   }
00310 
00313   template <typename C, typename T, typename F>
00314   inline
00315   bool
00316   operator<(FwdRef<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) {
00317     return (lhs.ref() < rhs.ref() );
00318   }
00319 
00320   template <typename C, typename T, typename F>
00321   inline
00322   bool
00323   operator<(Ref<C, T, F> const& lhs, FwdRef<C, T, F> const& rhs) {
00324     return (lhs < rhs.ref() );
00325   }
00326 
00327   template <typename C, typename T, typename F>
00328   inline
00329   bool
00330   operator<(FwdRef<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
00331     return (lhs.ref() < rhs );
00332   }
00333 
00334 }
00335 
00336   
00337 #endif