Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-08-29 02:16:40

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   template <typename C, typename K>
0124   bool compare_key(K const& lhs, K const& rhs) {
0125     if constexpr (requires { typename C::key_compare; }) {
0126       using comparison_functor = typename C::key_compare;
0127       return comparison_functor()(lhs, rhs);
0128     } else {
0129       return lhs < rhs;
0130     }
0131   }
0132 
0133   template <typename C, typename T, typename F>
0134   class RefVector;
0135 
0136   template <typename T>
0137   class RefToBaseVector;
0138 
0139   template <typename C,
0140             typename T = typename refhelper::ValueTrait<C>::value,
0141             typename F = typename refhelper::FindTrait<C, T>::value>
0142   class Ref {
0143   private:
0144     typedef refhelper::FindRefVectorUsingAdvance<RefVector<C, T, F>> VF;
0145     typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0146     friend class RefVectorIterator<C, T, F>;
0147     friend class RefVector<C, T, F>;
0148     friend class RefVector<RefVector<C, T, F>, T, VF>;
0149     friend class RefVector<RefVector<C, T, F>, T, VBF>;
0150 
0151   public:
0152     /// for export
0153     typedef C product_type;
0154     typedef T value_type;
0155     typedef T const element_type;  //used for generic programming
0156     typedef F finder_type;
0157     typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0158     typedef typename std::remove_cv<typename std::remove_reference<argument_type>::type>::type key_type;
0159     /// C is the type of the collection
0160     /// T is the type of a member the collection
0161 
0162     static key_type invalidKey() { return key_traits<key_type>::value; }
0163 
0164     /// Default constructor needed for reading from persistent store. Not for direct use.
0165     Ref() : product_(), index_(key_traits<key_type>::value) {}
0166 
0167     /// General purpose constructor from handle.
0168     Ref(Handle<C> const& handle, key_type itemKey, bool setNow = true);
0169 
0170     /// General purpose constructor from orphan handle.
0171     Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow = true);
0172 
0173     /// Constructors for ref to object that is not in an event.
0174     //  An exception will be thrown if an attempt is made to persistify
0175     //  any object containing this Ref.  Also, in the future work will
0176     //  be done to throw an exception if an attempt is made to put any object
0177     //  containing this Ref into an event(or run or lumi).
0178     Ref(C const* product, key_type itemKey, bool setNow = true);
0179 
0180     /// Constructor from test handle.
0181     //  An exception will be thrown if an attempt is made to persistify
0182     //  any object containing this Ref.  Also, in the future work will
0183     Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow = true);
0184 
0185     /// Constructor for those users who do not have a product handle,
0186     /// but have a pointer to a product getter (such as the EventPrincipal).
0187     /// prodGetter will ususally be a pointer to the event principal.
0188     Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0189         : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {}
0190 
0191     /// Constructor for use in the various X::fillView(...) functions.
0192     //  It is an error (not diagnosable at compile- or run-time) to call
0193     //  this constructor with a pointer to a T unless the pointed-to T
0194     //  object is already in a collection of type C stored in the
0195     //  Event. The given ProductID must be the id of the collection in
0196     //  the Event.
0197 
0198     Ref(ProductID const& iProductID, T const* item, key_type itemKey, C const* /* iProduct */)
0199         : product_(iProductID, item, 0, false), index_(itemKey) {}
0200 
0201     Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0202         : product_(iProductID, item, nullptr, false), index_(itemKey) {}
0203 
0204     Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0205         : product_(iProductID, item, nullptr, transient), index_(itemKey) {}
0206 
0207     /// Constructor that creates an invalid ("null") Ref that is
0208     /// associated with a given product (denoted by that product's
0209     /// ProductID).
0210 
0211     explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false), index_(key_traits<key_type>::value) {}
0212 
0213     /// Constructor from RefProd<C> and key
0214     Ref(RefProd<C> const& refProd, key_type itemKey);
0215 
0216     /// Destructor
0217     ~Ref() {}
0218 
0219     /// Dereference operator
0220     T const& operator*() const;
0221 
0222     /// Member dereference operator
0223     T const* operator->() const;
0224 
0225     /// Returns C++ pointer to the item
0226     T const* get() const { return isNull() ? nullptr : this->operator->(); }
0227 
0228     /// Checks for null
0229     bool isNull() const { return !isNonnull(); }
0230 
0231     /// Checks for non-null
0232     bool isNonnull() const { return index_ != edm::key_traits<key_type>::value; }
0233 
0234     /// Checks for null
0235     bool operator!() const { return isNull(); }
0236 
0237     /// Accessor for product ID.
0238     ProductID id() const { return product_.id(); }
0239 
0240     /// Accessor for product getter.
0241     EDProductGetter const* productGetter() const { return product_.productGetter(); }
0242 
0243     /// Accessor for product key.
0244     key_type key() const { return index_; }
0245 
0246     // This one just for backward compatibility.  Will be removed soon.
0247     key_type index() const { return index_; }
0248 
0249     /// Returns true if container referenced by the Ref has been cached
0250     bool hasProductCache() const { return product_.productPtr() != nullptr; }
0251 
0252     /// Checks if collection is in memory or available
0253     /// in the Event. No type checking is done.
0254     /// This function is potentially costly as it might cause a disk
0255     /// read (note that it does not cause the data to be cached locally)
0256     bool isAvailable() const;
0257 
0258     /// Checks if this ref is transient (i.e. not persistable).
0259     bool isTransient() const { return product_.isTransient(); }
0260 
0261     RefCore const& refCore() const { return product_; }
0262 
0263     //Used by ROOT storage
0264     CMS_CLASS_VERSION(10)
0265     //  private:
0266     // Constructor from member of RefVector
0267     Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
0268 
0269   private:
0270     // Compile time check that the argument is a C* or C const*
0271     // or derived from it.
0272     void checkTypeAtCompileTime(C const*) {}
0273 
0274     RefCore product_;
0275     key_type index_;
0276   };
0277 
0278   //***************************
0279   //Specialization for a vector
0280   //***************************
0281 #define REF_FOR_VECTOR_ARGS                                              \
0282   std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
0283       typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0284 
0285   template <typename E>
0286   class Ref<REF_FOR_VECTOR_ARGS> {
0287   private:
0288     typedef typename refhelper::ValueTrait<std::vector<E>>::value T;
0289     typedef
0290         typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value F;
0291 
0292     typedef refhelper::FindRefVectorUsingAdvance<RefVector<std::vector<E>, T, F>> VF;
0293     typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0294     friend class RefVectorIterator<std::vector<E>, T, F>;
0295     friend class RefVector<std::vector<E>, T, F>;
0296     friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
0297     friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
0298 
0299   public:
0300     /// for export
0301     typedef std::vector<E> product_type;
0302     typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
0303     typedef value_type const element_type;  //used for generic programming
0304     typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0305         finder_type;
0306     typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0307     typedef unsigned int key_type;
0308     /// C is the type of the collection
0309     /// T is the type of a member the collection
0310 
0311     static key_type invalidKey() { return key_traits<key_type>::value; }
0312 
0313     /// Default constructor needed for reading from persistent store. Not for direct use.
0314     Ref() : product_() {}
0315 
0316     /// General purpose constructor from handle.
0317     Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
0318 
0319     /// General purpose constructor from orphan handle.
0320     Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0321 
0322     /// Constructors for ref to object that is not in an event.
0323     //  An exception will be thrown if an attempt is made to persistify
0324     //  any object containing this Ref.  Also, in the future work will
0325     //  be done to throw an exception if an attempt is made to put any object
0326     //  containing this Ref into an event(or run or lumi).
0327     Ref(product_type const* product, key_type itemKey, bool setNow = true);
0328 
0329     /// Constructor from test handle.
0330     //  An exception will be thrown if an attempt is made to persistify
0331     //  any object containing this Ref.  Also, in the future work will
0332     Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0333 
0334     /// Constructor for those users who do not have a product handle,
0335     /// but have a pointer to a product getter (such as the EventPrincipal).
0336     /// prodGetter will ususally be a pointer to the event principal.
0337     Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0338         : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
0339 
0340     /// Constructor for use in the various X::fillView(...) functions.
0341     //  It is an error (not diagnosable at compile- or run-time) to call
0342     //  this constructor with a pointer to a T unless the pointed-to T
0343     //  object is already in a collection of type C stored in the
0344     //  Event. The given ProductID must be the id of the collection in
0345     //  the Event.
0346 
0347     Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* /* iProduct */)
0348         : product_(iProductID, item, nullptr, false, itemKey) {}
0349 
0350     Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0351         : product_(iProductID, item, nullptr, false, itemKey) {}
0352 
0353     Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0354         : product_(iProductID, item, nullptr, transient, itemKey) {}
0355 
0356     /// Constructor that creates an invalid ("null") Ref that is
0357     /// associated with a given product (denoted by that product's
0358     /// ProductID).
0359 
0360     explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
0361 
0362     /// Constructor from RefProd<C> and key
0363     Ref(RefProd<product_type> const& refProd, key_type itemKey);
0364 
0365     /// Destructor
0366     ~Ref() {}
0367 
0368     /// Dereference operator
0369     T const& operator*() const;
0370 
0371     /// Member dereference operator
0372     T const* operator->() const;
0373 
0374     /// Returns C++ pointer to the item
0375     T const* get() const { return isNull() ? nullptr : this->operator->(); }
0376 
0377     /// Checks for null
0378     bool isNull() const { return !isNonnull(); }
0379 
0380     /// Checks for non-null
0381     bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
0382 
0383     /// Checks for null
0384     bool operator!() const { return isNull(); }
0385 
0386     /// Accessor for product ID.
0387     ProductID id() const { return product_.id(); }
0388 
0389     /// Accessor for product getter.
0390     EDProductGetter const* productGetter() const { return product_.productGetter(); }
0391 
0392     /// Accessor for product key.
0393     key_type key() const { return product_.index(); }
0394 
0395     // This one just for backward compatibility.  Will be removed soon.
0396     key_type index() const { return product_.index(); }
0397 
0398     /// Returns true if container referenced by the Ref has been cached
0399     bool hasProductCache() const { return product_.productPtr() != nullptr; }
0400 
0401     /// Checks if collection is in memory or available
0402     /// in the Event. No type checking is done.
0403     /// This function is potentially costly as it might cause a disk
0404     /// read (note that it does not cause the data to be cached locally)
0405     bool isAvailable() const;
0406 
0407     /// Checks if this ref is transient (i.e. not persistable).
0408     bool isTransient() const { return product_.isTransient(); }
0409 
0410     RefCore const& refCore() const { return product_.toRefCore(); }
0411 
0412     //Used by ROOT storage
0413     CMS_CLASS_VERSION(11)
0414     //  private:
0415     // Constructor from member of RefVector
0416     Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
0417 
0418   private:
0419     // Compile time check that the argument is a C* or C const*
0420     // or derived from it.
0421     void checkTypeAtCompileTime(product_type const*) {}
0422 
0423     RefCoreWithIndex product_;
0424   };
0425 }  // namespace edm
0426 
0427 #include "DataFormats/Common/interface/RefProd.h"
0428 #include "DataFormats/Common/interface/RefCoreGet.h"
0429 #include "DataFormats/Common/interface/RefItemGet.h"
0430 
0431 namespace edm {
0432 
0433   /// General purpose constructor from handle.
0434   template <typename C, typename T, typename F>
0435   inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
0436       : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0437     if (itemKey == key_traits<key_type>::value)
0438       return;
0439     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0440   }
0441 
0442   /// General purpose constructor from handle.
0443   template <typename E>
0444   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
0445       : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0446     if (itemKey == key_traits<key_type>::value)
0447       return;
0448     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0449         product_.toRefCore(), handle.product(), itemKey);
0450   }
0451 
0452   /// General purpose constructor from orphan handle.
0453   template <typename C, typename T, typename F>
0454   inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
0455       : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0456     if (itemKey == key_traits<key_type>::value)
0457       return;
0458     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0459   }
0460 
0461   /// General purpose constructor from orphan handle.
0462   template <typename E>
0463   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0464       : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0465     if (itemKey == key_traits<key_type>::value)
0466       return;
0467     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0468         product_.toRefCore(), handle.product(), itemKey);
0469   }
0470 
0471   /// Constructor for refs to object that is not in an event.
0472   //  An exception will be thrown if an attempt is made to persistify
0473   //  any object containing this Ref.  Also, in the future work will
0474   //  be done to throw an exception if an attempt is made to put any object
0475   //  containing this Ref into an event(or run or lumi).
0476   //  Note:  It is legal for the referenced object to be put into the event
0477   //  and persistified.  It is this Ref itself that cannot be persistified.
0478   template <typename C, typename T, typename F>
0479   inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
0480       : product_(ProductID(), nullptr, nullptr, true),
0481         index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0482     if (iProduct != nullptr) {
0483       refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
0484     }
0485   }
0486 
0487   template <typename E>
0488   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
0489       : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0490     if (iProduct != nullptr) {
0491       refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
0492     }
0493   }
0494 
0495   /// constructor from test handle.
0496   //  An exception will be thrown if an attempt is made to persistify any object containing this Ref.
0497   template <typename C, typename T, typename F>
0498   inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
0499       : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
0500     if (itemKey == key_traits<key_type>::value)
0501       return;
0502     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0503   }
0504 
0505   template <typename E>
0506   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0507       : product_(handle.id(), nullptr, nullptr, true, itemKey) {
0508     if (itemKey == key_traits<key_type>::value)
0509       return;
0510     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0511         product_.toRefCore(), handle.product(), itemKey);
0512   }
0513 
0514   /// Constructor from RefProd<C> and key
0515   template <typename C, typename T, typename F>
0516   inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
0517       : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
0518         index_(itemKey) {
0519     if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0520       refitem::findRefItem<C, T, F, key_type>(
0521           product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0522     }
0523   }
0524 
0525   template <typename E>
0526   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
0527       : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
0528     if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0529       refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0530           product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0531     }
0532   }
0533 
0534   template <typename C, typename T, typename F>
0535   inline bool Ref<C, T, F>::isAvailable() const {
0536     if (product_.isAvailable()) {
0537       return true;
0538     }
0539     return isThinnedAvailable<C>(product_, index_);
0540   }
0541 
0542   template <typename E>
0543   inline bool Ref<REF_FOR_VECTOR_ARGS>::isAvailable() const {
0544     if (product_.isAvailable()) {
0545       return true;
0546     }
0547     return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
0548   }
0549 
0550   /// Dereference operator
0551   template <typename C, typename T, typename F>
0552   inline T const& Ref<C, T, F>::operator*() const {
0553     return *getRefPtr<C, T, F>(product_, index_);
0554   }
0555   template <typename E>
0556   inline typename refhelper::ValueTrait<std::vector<E>>::value const& Ref<REF_FOR_VECTOR_ARGS>::operator*() const {
0557     return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0558   }
0559 
0560   /// Member dereference operator
0561   template <typename C, typename T, typename F>
0562   inline T const* Ref<C, T, F>::operator->() const {
0563     return getRefPtr<C, T, F>(product_, index_);
0564   }
0565   template <typename E>
0566   inline typename refhelper::ValueTrait<std::vector<E>>::value const* Ref<REF_FOR_VECTOR_ARGS>::operator->() const {
0567     return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0568   }
0569 
0570   template <typename C, typename T, typename F>
0571   inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0572     return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
0573   }
0574 
0575   template <typename C, typename T, typename F>
0576   inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0577     return !(lhs == rhs);
0578   }
0579 
0580   template <typename C, typename T, typename F>
0581   inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0582     /// the definition and use of compare_key<> guarantees that the ordering of Refs within
0583     /// a collection will be identical to the ordering of the referenced objects in the collection.
0584     return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
0585   }
0586 
0587 }  // namespace edm
0588 
0589 //Handle specialization here
0590 #include "DataFormats/Common/interface/HolderToVectorTrait_Ref_specialization.h"
0591 #endif