Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:53

0001 #ifndef DataFormats_Common_Ref_h
0002 #define DataFormats_Common_Ref_h
0003 
0004 /*----------------------------------------------------------------------
0005   
0006 Ref: A template for a interproduct reference to a member of a product_.
0007 
0008 ----------------------------------------------------------------------*/
0009 /**
0010   \b Summary
0011 
0012   The edm::Ref<> is a storable reference to an item in a stored
0013   container.  For example, you could use one to hold a reference back
0014   to one particular track within an std::vector<> of tracks.
0015  
0016   \b Usage
0017  
0018   The edm::Ref<> works just like a pointer
0019   \code
0020      edm::Ref<FooCollection> fooPtr = ... //set the value
0021      functionTakingConstFoo(*fooPtr); //get the Foo object
0022      fooPtr->bar();  //call a method of the held Foo object
0023   \endcode
0024 
0025   The main purpose of an edm::Ref<> is it can be used as a member
0026   datum for a class that is to be stored in the edm::Event.
0027  
0028   \b Customization
0029  
0030    The edm::Ref<> takes three template parameters
0031 
0032      1) \b C: The type of the container which is holding the item
0033 
0034      2) \b T: The type of the item.  This defaults to C::value_type
0035 
0036      3) \b F: A helper class (a functor) which knows how to find a
0037      particular 'T' within the container given an appropriate key. The
0038      type of the key is deduced from F::second_argument. The default
0039      for F is refhelper::FindTrait<C, T>::value.  If no specialization
0040      of FindTrait<> is available for the combination (C, T) then it
0041      defaults to getting the iterator to be beginning of the container
0042      and using std::advance() to move to the appropriate key in the
0043      container.
0044  
0045      It is possible to customize the 'lookup' algorithm used.  
0046 
0047      1) The helper class F must provide `value_type`,
0048      `first_argument_type` and `second_argument_type` typedefs.
0049 
0050      2) The helper class F must define the function call operator in
0051      such a way that the following call is well-formed:
0052          // f    is an instance of type F
0053          // coll is an instance of type C
0054          // k    is an instance of type F::key_type
0055 
0056          result_type r = f(coll, k);     
0057  
0058      If one wishes to make a specialized lookup the default lookup for
0059      the container/type pair then one needs to partially specialize
0060      the templated class edm::refhelper::FindTrait<C, T> such that it
0061      has a typedef named 'value' which refers to the specialized
0062      helper class (i.e., F)
0063 
0064      The class template Ref<C, T, F> supports 'null' references.
0065 
0066      -- a default-constructed Ref is 'null'; furthermore, it also
0067         has an invalid (or 'null') ProductID.
0068      -- a Ref constructed through the single-arguement constructor
0069         that takes a ProductID is also null.        
0070 */
0071 
0072 /*----------------------------------------------------------------------
0073 //  This defines the public interface to the class Ref<C, T, F>.
0074 //  C                         is the collection type.
0075 //  T (default C::value_type) is the type of an element in the collection.
0076 //
0077 //  ProductID productID       is the product ID of the collection.
0078 //  key_type itemKey          is the key of the element in the collection.
0079 //  C::value_type *itemPtr    is a C++ pointer to the element 
0080 //  Ref<C, T, F> const& ref   is another Ref<C, T, F>
0081 
0082 //  Constructors
0083     Ref(); // Default constructor
0084     Ref(Ref<C, T> const& ref);  // Copy constructor  (default, not explicitly specified)
0085 
0086     Ref(Handle<C> const& handle, key_type itemKey);
0087     Ref(ProductID pid, key_type itemKey, EDProductGetter const* prodGetter);
0088 
0089 //  Destructor
0090     virtual ~Ref() {}
0091 
0092     // Operators and methods
0093     Ref<C, T>& operator=(Ref<C, T> const&);     // assignment (default, not explicitly specified)
0094     T const& operator*() const;         // dereference
0095     T const* const operator->() const;      // member dereference
0096     bool operator==(Ref<C, T> const& ref) const; // equality
0097     bool operator!=(Ref<C, T> const& ref) const; // inequality
0098     bool operator<(Ref<C, T> const& ref) const; // ordering
0099     bool isNonnull() const;         // true if an object is referenced
0100     bool isNull() const;            // equivalent to !isNonnull()
0101     bool operator!() const;         // equivalent to !isNonnull()
0102     ----------------------------------------------------------------------*/
0103 
0104 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0105 #include "DataFormats/Common/interface/EDProductfwd.h"
0106 #include "DataFormats/Common/interface/EDProductGetter.h"
0107 #include "DataFormats/Common/interface/Handle.h"
0108 #include "DataFormats/Common/interface/OrphanHandle.h"
0109 #include "DataFormats/Common/interface/RefCore.h"
0110 #include "DataFormats/Common/interface/RefCoreWithIndex.h"
0111 #include "DataFormats/Common/interface/TestHandle.h"
0112 #include "DataFormats/Common/interface/traits.h"
0113 #include "DataFormats/Provenance/interface/ProductID.h"
0114 
0115 #include "boost/functional.hpp"
0116 
0117 #include <vector>
0118 #include <type_traits>
0119 
0120 #include "DataFormats/Common/interface/RefTraits.h"
0121 
0122 namespace edm {
0123   //Use SFINAE to test for embedded type with name key_compare
0124   template <typename, typename = void>
0125   struct has_key_compare : std::false_type {};
0126   template <typename T>
0127   struct has_key_compare<T, std::void_t<typename T::key_compare>> : std::true_type {};
0128 
0129   template <typename C, typename K>
0130   bool compare_key(K const& lhs, K const& rhs) {
0131     if constexpr (has_key_compare<C>::value) {
0132       using comparison_functor = typename C::key_compare;
0133       return comparison_functor()(lhs, rhs);
0134     } else {
0135       return lhs < rhs;
0136     }
0137   }
0138 
0139   template <typename C, typename T, typename F>
0140   class RefVector;
0141 
0142   template <typename T>
0143   class RefToBaseVector;
0144 
0145   template <typename C,
0146             typename T = typename refhelper::ValueTrait<C>::value,
0147             typename F = typename refhelper::FindTrait<C, T>::value>
0148   class Ref {
0149   private:
0150     typedef refhelper::FindRefVectorUsingAdvance<RefVector<C, T, F>> VF;
0151     typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0152     friend class RefVectorIterator<C, T, F>;
0153     friend class RefVector<C, T, F>;
0154     friend class RefVector<RefVector<C, T, F>, T, VF>;
0155     friend class RefVector<RefVector<C, T, F>, T, VBF>;
0156 
0157   public:
0158     /// for export
0159     typedef C product_type;
0160     typedef T value_type;
0161     typedef T const element_type;  //used for generic programming
0162     typedef F finder_type;
0163     typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0164     typedef typename std::remove_cv<typename std::remove_reference<argument_type>::type>::type key_type;
0165     /// C is the type of the collection
0166     /// T is the type of a member the collection
0167 
0168     static key_type invalidKey() { return key_traits<key_type>::value; }
0169 
0170     /// Default constructor needed for reading from persistent store. Not for direct use.
0171     Ref() : product_(), index_(key_traits<key_type>::value) {}
0172 
0173     /// General purpose constructor from handle.
0174     Ref(Handle<C> const& handle, key_type itemKey, bool setNow = true);
0175 
0176     /// General purpose constructor from orphan handle.
0177     Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow = true);
0178 
0179     /// Constructors for ref to object that is not in an event.
0180     //  An exception will be thrown if an attempt is made to persistify
0181     //  any object containing this Ref.  Also, in the future work will
0182     //  be done to throw an exception if an attempt is made to put any object
0183     //  containing this Ref into an event(or run or lumi).
0184     Ref(C const* product, key_type itemKey, bool setNow = true);
0185 
0186     /// Constructor from test handle.
0187     //  An exception will be thrown if an attempt is made to persistify
0188     //  any object containing this Ref.  Also, in the future work will
0189     Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow = true);
0190 
0191     /// Constructor for those users who do not have a product handle,
0192     /// but have a pointer to a product getter (such as the EventPrincipal).
0193     /// prodGetter will ususally be a pointer to the event principal.
0194     Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0195         : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {}
0196 
0197     /// Constructor for use in the various X::fillView(...) functions.
0198     //  It is an error (not diagnosable at compile- or run-time) to call
0199     //  this constructor with a pointer to a T unless the pointed-to T
0200     //  object is already in a collection of type C stored in the
0201     //  Event. The given ProductID must be the id of the collection in
0202     //  the Event.
0203 
0204     Ref(ProductID const& iProductID, T const* item, key_type itemKey, C const* /* iProduct */)
0205         : product_(iProductID, item, 0, false), index_(itemKey) {}
0206 
0207     Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0208         : product_(iProductID, item, nullptr, false), index_(itemKey) {}
0209 
0210     Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0211         : product_(iProductID, item, nullptr, transient), index_(itemKey) {}
0212 
0213     /// Constructor that creates an invalid ("null") Ref that is
0214     /// associated with a given product (denoted by that product's
0215     /// ProductID).
0216 
0217     explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false), index_(key_traits<key_type>::value) {}
0218 
0219     /// Constructor from RefProd<C> and key
0220     Ref(RefProd<C> const& refProd, key_type itemKey);
0221 
0222     /// Destructor
0223     ~Ref() {}
0224 
0225     /// Dereference operator
0226     T const& operator*() const;
0227 
0228     /// Member dereference operator
0229     T const* operator->() const;
0230 
0231     /// Returns C++ pointer to the item
0232     T const* get() const { return isNull() ? nullptr : this->operator->(); }
0233 
0234     /// Checks for null
0235     bool isNull() const { return !isNonnull(); }
0236 
0237     /// Checks for non-null
0238     bool isNonnull() const { return index_ != edm::key_traits<key_type>::value; }
0239 
0240     /// Checks for null
0241     bool operator!() const { return isNull(); }
0242 
0243     /// Accessor for product ID.
0244     ProductID id() const { return product_.id(); }
0245 
0246     /// Accessor for product getter.
0247     EDProductGetter const* productGetter() const { return product_.productGetter(); }
0248 
0249     /// Accessor for product key.
0250     key_type key() const { return index_; }
0251 
0252     // This one just for backward compatibility.  Will be removed soon.
0253     key_type index() const { return index_; }
0254 
0255     /// Returns true if container referenced by the Ref has been cached
0256     bool hasProductCache() const { return product_.productPtr() != nullptr; }
0257 
0258     /// Checks if collection is in memory or available
0259     /// in the Event. No type checking is done.
0260     /// This function is potentially costly as it might cause a disk
0261     /// read (note that it does not cause the data to be cached locally)
0262     bool isAvailable() const;
0263 
0264     /// Checks if this ref is transient (i.e. not persistable).
0265     bool isTransient() const { return product_.isTransient(); }
0266 
0267     RefCore const& refCore() const { return product_; }
0268 
0269     //Used by ROOT storage
0270     CMS_CLASS_VERSION(10)
0271     //  private:
0272     // Constructor from member of RefVector
0273     Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
0274 
0275   private:
0276     // Compile time check that the argument is a C* or C const*
0277     // or derived from it.
0278     void checkTypeAtCompileTime(C const*) {}
0279 
0280     RefCore product_;
0281     key_type index_;
0282   };
0283 
0284   //***************************
0285   //Specialization for a vector
0286   //***************************
0287 #define REF_FOR_VECTOR_ARGS                                              \
0288   std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
0289       typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0290 
0291   template <typename E>
0292   class Ref<REF_FOR_VECTOR_ARGS> {
0293   private:
0294     typedef typename refhelper::ValueTrait<std::vector<E>>::value T;
0295     typedef
0296         typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value F;
0297 
0298     typedef refhelper::FindRefVectorUsingAdvance<RefVector<std::vector<E>, T, F>> VF;
0299     typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0300     friend class RefVectorIterator<std::vector<E>, T, F>;
0301     friend class RefVector<std::vector<E>, T, F>;
0302     friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
0303     friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
0304 
0305   public:
0306     /// for export
0307     typedef std::vector<E> product_type;
0308     typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
0309     typedef value_type const element_type;  //used for generic programming
0310     typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0311         finder_type;
0312     typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0313     typedef unsigned int key_type;
0314     /// C is the type of the collection
0315     /// T is the type of a member the collection
0316 
0317     static key_type invalidKey() { return key_traits<key_type>::value; }
0318 
0319     /// Default constructor needed for reading from persistent store. Not for direct use.
0320     Ref() : product_() {}
0321 
0322     /// General purpose constructor from handle.
0323     Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
0324 
0325     /// General purpose constructor from orphan handle.
0326     Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0327 
0328     /// Constructors for ref to object that is not in an event.
0329     //  An exception will be thrown if an attempt is made to persistify
0330     //  any object containing this Ref.  Also, in the future work will
0331     //  be done to throw an exception if an attempt is made to put any object
0332     //  containing this Ref into an event(or run or lumi).
0333     Ref(product_type const* product, key_type itemKey, bool setNow = true);
0334 
0335     /// Constructor from test handle.
0336     //  An exception will be thrown if an attempt is made to persistify
0337     //  any object containing this Ref.  Also, in the future work will
0338     Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0339 
0340     /// Constructor for those users who do not have a product handle,
0341     /// but have a pointer to a product getter (such as the EventPrincipal).
0342     /// prodGetter will ususally be a pointer to the event principal.
0343     Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0344         : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
0345 
0346     /// Constructor for use in the various X::fillView(...) functions.
0347     //  It is an error (not diagnosable at compile- or run-time) to call
0348     //  this constructor with a pointer to a T unless the pointed-to T
0349     //  object is already in a collection of type C stored in the
0350     //  Event. The given ProductID must be the id of the collection in
0351     //  the Event.
0352 
0353     Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* /* iProduct */)
0354         : product_(iProductID, item, nullptr, false, itemKey) {}
0355 
0356     Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0357         : product_(iProductID, item, nullptr, false, itemKey) {}
0358 
0359     Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0360         : product_(iProductID, item, nullptr, transient, itemKey) {}
0361 
0362     /// Constructor that creates an invalid ("null") Ref that is
0363     /// associated with a given product (denoted by that product's
0364     /// ProductID).
0365 
0366     explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
0367 
0368     /// Constructor from RefProd<C> and key
0369     Ref(RefProd<product_type> const& refProd, key_type itemKey);
0370 
0371     /// Destructor
0372     ~Ref() {}
0373 
0374     /// Dereference operator
0375     T const& operator*() const;
0376 
0377     /// Member dereference operator
0378     T const* operator->() const;
0379 
0380     /// Returns C++ pointer to the item
0381     T const* get() const { return isNull() ? nullptr : this->operator->(); }
0382 
0383     /// Checks for null
0384     bool isNull() const { return !isNonnull(); }
0385 
0386     /// Checks for non-null
0387     bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
0388 
0389     /// Checks for null
0390     bool operator!() const { return isNull(); }
0391 
0392     /// Accessor for product ID.
0393     ProductID id() const { return product_.id(); }
0394 
0395     /// Accessor for product getter.
0396     EDProductGetter const* productGetter() const { return product_.productGetter(); }
0397 
0398     /// Accessor for product key.
0399     key_type key() const { return product_.index(); }
0400 
0401     // This one just for backward compatibility.  Will be removed soon.
0402     key_type index() const { return product_.index(); }
0403 
0404     /// Returns true if container referenced by the Ref has been cached
0405     bool hasProductCache() const { return product_.productPtr() != nullptr; }
0406 
0407     /// Checks if collection is in memory or available
0408     /// in the Event. No type checking is done.
0409     /// This function is potentially costly as it might cause a disk
0410     /// read (note that it does not cause the data to be cached locally)
0411     bool isAvailable() const;
0412 
0413     /// Checks if this ref is transient (i.e. not persistable).
0414     bool isTransient() const { return product_.isTransient(); }
0415 
0416     RefCore const& refCore() const { return product_.toRefCore(); }
0417 
0418     //Used by ROOT storage
0419     CMS_CLASS_VERSION(11)
0420     //  private:
0421     // Constructor from member of RefVector
0422     Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
0423 
0424   private:
0425     // Compile time check that the argument is a C* or C const*
0426     // or derived from it.
0427     void checkTypeAtCompileTime(product_type const*) {}
0428 
0429     RefCoreWithIndex product_;
0430   };
0431 }  // namespace edm
0432 
0433 #include "DataFormats/Common/interface/RefProd.h"
0434 #include "DataFormats/Common/interface/RefCoreGet.h"
0435 #include "DataFormats/Common/interface/RefItemGet.h"
0436 
0437 namespace edm {
0438 
0439   /// General purpose constructor from handle.
0440   template <typename C, typename T, typename F>
0441   inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
0442       : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0443     if (itemKey == key_traits<key_type>::value)
0444       return;
0445     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0446   }
0447 
0448   /// General purpose constructor from handle.
0449   template <typename E>
0450   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
0451       : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0452     if (itemKey == key_traits<key_type>::value)
0453       return;
0454     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0455         product_.toRefCore(), handle.product(), itemKey);
0456   }
0457 
0458   /// General purpose constructor from orphan handle.
0459   template <typename C, typename T, typename F>
0460   inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
0461       : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0462     if (itemKey == key_traits<key_type>::value)
0463       return;
0464     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0465   }
0466 
0467   /// General purpose constructor from orphan handle.
0468   template <typename E>
0469   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0470       : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0471     if (itemKey == key_traits<key_type>::value)
0472       return;
0473     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0474         product_.toRefCore(), handle.product(), itemKey);
0475   }
0476 
0477   /// Constructor for refs to object that is not in an event.
0478   //  An exception will be thrown if an attempt is made to persistify
0479   //  any object containing this Ref.  Also, in the future work will
0480   //  be done to throw an exception if an attempt is made to put any object
0481   //  containing this Ref into an event(or run or lumi).
0482   //  Note:  It is legal for the referenced object to be put into the event
0483   //  and persistified.  It is this Ref itself that cannot be persistified.
0484   template <typename C, typename T, typename F>
0485   inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
0486       : product_(ProductID(), nullptr, nullptr, true),
0487         index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0488     if (iProduct != nullptr) {
0489       refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
0490     }
0491   }
0492 
0493   template <typename E>
0494   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
0495       : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0496     if (iProduct != nullptr) {
0497       refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
0498     }
0499   }
0500 
0501   /// constructor from test handle.
0502   //  An exception will be thrown if an attempt is made to persistify any object containing this Ref.
0503   template <typename C, typename T, typename F>
0504   inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
0505       : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
0506     if (itemKey == key_traits<key_type>::value)
0507       return;
0508     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0509   }
0510 
0511   template <typename E>
0512   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0513       : product_(handle.id(), nullptr, nullptr, true, itemKey) {
0514     if (itemKey == key_traits<key_type>::value)
0515       return;
0516     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0517         product_.toRefCore(), handle.product(), itemKey);
0518   }
0519 
0520   /// Constructor from RefProd<C> and key
0521   template <typename C, typename T, typename F>
0522   inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
0523       : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
0524         index_(itemKey) {
0525     if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0526       refitem::findRefItem<C, T, F, key_type>(
0527           product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0528     }
0529   }
0530 
0531   template <typename E>
0532   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
0533       : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
0534     if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0535       refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0536           product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0537     }
0538   }
0539 
0540   template <typename C, typename T, typename F>
0541   inline bool Ref<C, T, F>::isAvailable() const {
0542     if (product_.isAvailable()) {
0543       return true;
0544     }
0545     return isThinnedAvailable<C>(product_, index_);
0546   }
0547 
0548   template <typename E>
0549   inline bool Ref<REF_FOR_VECTOR_ARGS>::isAvailable() const {
0550     if (product_.isAvailable()) {
0551       return true;
0552     }
0553     return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
0554   }
0555 
0556   /// Dereference operator
0557   template <typename C, typename T, typename F>
0558   inline T const& Ref<C, T, F>::operator*() const {
0559     return *getRefPtr<C, T, F>(product_, index_);
0560   }
0561   template <typename E>
0562   inline typename refhelper::ValueTrait<std::vector<E>>::value const& Ref<REF_FOR_VECTOR_ARGS>::operator*() const {
0563     return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0564   }
0565 
0566   /// Member dereference operator
0567   template <typename C, typename T, typename F>
0568   inline T const* Ref<C, T, F>::operator->() const {
0569     return getRefPtr<C, T, F>(product_, index_);
0570   }
0571   template <typename E>
0572   inline typename refhelper::ValueTrait<std::vector<E>>::value const* Ref<REF_FOR_VECTOR_ARGS>::operator->() const {
0573     return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0574   }
0575 
0576   template <typename C, typename T, typename F>
0577   inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0578     return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
0579   }
0580 
0581   template <typename C, typename T, typename F>
0582   inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0583     return !(lhs == rhs);
0584   }
0585 
0586   template <typename C, typename T, typename F>
0587   inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0588     /// the definition and use of compare_key<> guarantees that the ordering of Refs within
0589     /// a collection will be identical to the ordering of the referenced objects in the collection.
0590     return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
0591   }
0592 
0593 }  // namespace edm
0594 
0595 //Handle specialization here
0596 #include "DataFormats/Common/interface/HolderToVectorTrait_Ref_specialization.h"
0597 #endif