Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-06-11 04:36:58

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     bool isAvailable() const;
0261 
0262     /// Checks if this ref is transient (i.e. not persistable).
0263     bool isTransient() const { return product_.isTransient(); }
0264 
0265     RefCore const& refCore() const { return product_; }
0266 
0267     //Used by ROOT storage
0268     CMS_CLASS_VERSION(10)
0269     //  private:
0270     // Constructor from member of RefVector
0271     Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
0272 
0273   private:
0274     // Compile time check that the argument is a C* or C const*
0275     // or derived from it.
0276     void checkTypeAtCompileTime(C const*) {}
0277 
0278     RefCore product_;
0279     key_type index_;
0280   };
0281 
0282   //***************************
0283   //Specialization for a vector
0284   //***************************
0285 #define REF_FOR_VECTOR_ARGS                                              \
0286   std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
0287       typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0288 
0289   template <typename E>
0290   class Ref<REF_FOR_VECTOR_ARGS> {
0291   private:
0292     typedef typename refhelper::ValueTrait<std::vector<E>>::value T;
0293     typedef
0294         typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value F;
0295 
0296     typedef refhelper::FindRefVectorUsingAdvance<RefVector<std::vector<E>, T, F>> VF;
0297     typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0298     friend class RefVectorIterator<std::vector<E>, T, F>;
0299     friend class RefVector<std::vector<E>, T, F>;
0300     friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
0301     friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
0302 
0303   public:
0304     /// for export
0305     typedef std::vector<E> product_type;
0306     typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
0307     typedef value_type const element_type;  //used for generic programming
0308     typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0309         finder_type;
0310     typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0311     typedef unsigned int key_type;
0312     /// C is the type of the collection
0313     /// T is the type of a member the collection
0314 
0315     static key_type invalidKey() { return key_traits<key_type>::value; }
0316 
0317     /// Default constructor needed for reading from persistent store. Not for direct use.
0318     Ref() : product_() {}
0319 
0320     /// General purpose constructor from handle.
0321     Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
0322 
0323     /// General purpose constructor from orphan handle.
0324     Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0325 
0326     /// Constructors for ref to object that is not in an event.
0327     //  An exception will be thrown if an attempt is made to persistify
0328     //  any object containing this Ref.  Also, in the future work will
0329     //  be done to throw an exception if an attempt is made to put any object
0330     //  containing this Ref into an event(or run or lumi).
0331     Ref(product_type const* product, key_type itemKey, bool setNow = true);
0332 
0333     /// Constructor from test handle.
0334     //  An exception will be thrown if an attempt is made to persistify
0335     //  any object containing this Ref.  Also, in the future work will
0336     Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0337 
0338     /// Constructor for those users who do not have a product handle,
0339     /// but have a pointer to a product getter (such as the EventPrincipal).
0340     /// prodGetter will ususally be a pointer to the event principal.
0341     Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0342         : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
0343 
0344     /// Constructor for use in the various X::fillView(...) functions.
0345     //  It is an error (not diagnosable at compile- or run-time) to call
0346     //  this constructor with a pointer to a T unless the pointed-to T
0347     //  object is already in a collection of type C stored in the
0348     //  Event. The given ProductID must be the id of the collection in
0349     //  the Event.
0350 
0351     Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* /* iProduct */)
0352         : product_(iProductID, item, nullptr, false, itemKey) {}
0353 
0354     Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0355         : product_(iProductID, item, nullptr, false, itemKey) {}
0356 
0357     Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0358         : product_(iProductID, item, nullptr, transient, itemKey) {}
0359 
0360     /// Constructor that creates an invalid ("null") Ref that is
0361     /// associated with a given product (denoted by that product's
0362     /// ProductID).
0363 
0364     explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
0365 
0366     /// Constructor from RefProd<C> and key
0367     Ref(RefProd<product_type> const& refProd, key_type itemKey);
0368 
0369     /// Destructor
0370     ~Ref() {}
0371 
0372     /// Dereference operator
0373     T const& operator*() const;
0374 
0375     /// Member dereference operator
0376     T const* operator->() const;
0377 
0378     /// Returns C++ pointer to the item
0379     T const* get() const { return isNull() ? nullptr : this->operator->(); }
0380 
0381     /// Checks for null
0382     bool isNull() const { return !isNonnull(); }
0383 
0384     /// Checks for non-null
0385     bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
0386 
0387     /// Checks for null
0388     bool operator!() const { return isNull(); }
0389 
0390     /// Accessor for product ID.
0391     ProductID id() const { return product_.id(); }
0392 
0393     /// Accessor for product getter.
0394     EDProductGetter const* productGetter() const { return product_.productGetter(); }
0395 
0396     /// Accessor for product key.
0397     key_type key() const { return product_.index(); }
0398 
0399     // This one just for backward compatibility.  Will be removed soon.
0400     key_type index() const { return product_.index(); }
0401 
0402     /// Returns true if container referenced by the Ref has been cached
0403     bool hasProductCache() const { return product_.productPtr() != nullptr; }
0404 
0405     /// Checks if collection is in memory or available
0406     /// in the Event. No type checking is done.
0407     bool isAvailable() const;
0408 
0409     /// Checks if this ref is transient (i.e. not persistable).
0410     bool isTransient() const { return product_.isTransient(); }
0411 
0412     RefCore const& refCore() const { return product_.toRefCore(); }
0413 
0414     //Used by ROOT storage
0415     CMS_CLASS_VERSION(11)
0416     //  private:
0417     // Constructor from member of RefVector
0418     Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
0419 
0420   private:
0421     // Compile time check that the argument is a C* or C const*
0422     // or derived from it.
0423     void checkTypeAtCompileTime(product_type const*) {}
0424 
0425     RefCoreWithIndex product_;
0426   };
0427 }  // namespace edm
0428 
0429 #include "DataFormats/Common/interface/RefProd.h"
0430 #include "DataFormats/Common/interface/RefCoreGet.h"
0431 #include "DataFormats/Common/interface/RefItemGet.h"
0432 
0433 namespace edm {
0434 
0435   /// General purpose constructor from handle.
0436   template <typename C, typename T, typename F>
0437   inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
0438       : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0439     if (itemKey == key_traits<key_type>::value)
0440       return;
0441     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0442   }
0443 
0444   /// General purpose constructor from handle.
0445   template <typename E>
0446   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
0447       : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0448     if (itemKey == key_traits<key_type>::value)
0449       return;
0450     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0451         product_.toRefCore(), handle.product(), itemKey);
0452   }
0453 
0454   /// General purpose constructor from orphan handle.
0455   template <typename C, typename T, typename F>
0456   inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
0457       : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0458     if (itemKey == key_traits<key_type>::value)
0459       return;
0460     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0461   }
0462 
0463   /// General purpose constructor from orphan handle.
0464   template <typename E>
0465   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0466       : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0467     if (itemKey == key_traits<key_type>::value)
0468       return;
0469     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0470         product_.toRefCore(), handle.product(), itemKey);
0471   }
0472 
0473   /// Constructor for refs to object that is not in an event.
0474   //  An exception will be thrown if an attempt is made to persistify
0475   //  any object containing this Ref.  Also, in the future work will
0476   //  be done to throw an exception if an attempt is made to put any object
0477   //  containing this Ref into an event(or run or lumi).
0478   //  Note:  It is legal for the referenced object to be put into the event
0479   //  and persistified.  It is this Ref itself that cannot be persistified.
0480   template <typename C, typename T, typename F>
0481   inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
0482       : product_(ProductID(), nullptr, nullptr, true),
0483         index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0484     if (iProduct != nullptr) {
0485       refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
0486     }
0487   }
0488 
0489   template <typename E>
0490   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
0491       : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0492     if (iProduct != nullptr) {
0493       refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
0494     }
0495   }
0496 
0497   /// constructor from test handle.
0498   //  An exception will be thrown if an attempt is made to persistify any object containing this Ref.
0499   template <typename C, typename T, typename F>
0500   inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
0501       : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
0502     if (itemKey == key_traits<key_type>::value)
0503       return;
0504     refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0505   }
0506 
0507   template <typename E>
0508   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0509       : product_(handle.id(), nullptr, nullptr, true, itemKey) {
0510     if (itemKey == key_traits<key_type>::value)
0511       return;
0512     refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0513         product_.toRefCore(), handle.product(), itemKey);
0514   }
0515 
0516   /// Constructor from RefProd<C> and key
0517   template <typename C, typename T, typename F>
0518   inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
0519       : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
0520         index_(itemKey) {
0521     if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0522       refitem::findRefItem<C, T, F, key_type>(
0523           product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0524     }
0525   }
0526 
0527   template <typename E>
0528   inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
0529       : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
0530     if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0531       refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0532           product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0533     }
0534   }
0535 
0536   template <typename C, typename T, typename F>
0537   inline bool Ref<C, T, F>::isAvailable() const {
0538     if (product_.isAvailable()) {
0539       return true;
0540     }
0541     return isThinnedAvailable<C>(product_, index_);
0542   }
0543 
0544   template <typename E>
0545   inline bool Ref<REF_FOR_VECTOR_ARGS>::isAvailable() const {
0546     if (product_.isAvailable()) {
0547       return true;
0548     }
0549     return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
0550   }
0551 
0552   /// Dereference operator
0553   template <typename C, typename T, typename F>
0554   inline T const& Ref<C, T, F>::operator*() const {
0555     return *getRefPtr<C, T, F>(product_, index_);
0556   }
0557   template <typename E>
0558   inline typename refhelper::ValueTrait<std::vector<E>>::value const& Ref<REF_FOR_VECTOR_ARGS>::operator*() const {
0559     return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0560   }
0561 
0562   /// Member dereference operator
0563   template <typename C, typename T, typename F>
0564   inline T const* Ref<C, T, F>::operator->() const {
0565     return getRefPtr<C, T, F>(product_, index_);
0566   }
0567   template <typename E>
0568   inline typename refhelper::ValueTrait<std::vector<E>>::value const* Ref<REF_FOR_VECTOR_ARGS>::operator->() const {
0569     return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0570   }
0571 
0572   template <typename C, typename T, typename F>
0573   inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0574     return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
0575   }
0576 
0577   template <typename C, typename T, typename F>
0578   inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0579     return !(lhs == rhs);
0580   }
0581 
0582   template <typename C, typename T, typename F>
0583   inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0584     /// the definition and use of compare_key<> guarantees that the ordering of Refs within
0585     /// a collection will be identical to the ordering of the referenced objects in the collection.
0586     return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
0587   }
0588 
0589 }  // namespace edm
0590 
0591 //Handle specialization here
0592 #include "DataFormats/Common/interface/HolderToVectorTrait_Ref_specialization.h"
0593 #endif