Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:03

0001 #ifndef DataFormats_Common_ThinnedRefSet_h
0002 #define DataFormats_Common_ThinnedRefSet_h
0003 //
0004 // Package:     DataFormats/Common
0005 // Class  :     ThinnedRefSet
0006 //
0007 /**\class ThinnedRefSet ThinnedRefSet.h "ThinnedRefSet.h"
0008 
0009  Description: A minimal set interface (insertion, contains(), clear()) for a set of Ref keys to a thinned collection
0010 
0011  Usage:
0012 
0013     A ThinnedRefSet contains Ref keys to a thinned collection. The
0014 keys are inserted as Refs to the thinned collection itself, or to any
0015 parent collections of the thinned collection.
0016 
0017 The main use case are Selector classes for edm::ThinningProducer.
0018 There, an object of the class would be stored as a member of the
0019 Selector class, filled in Selector::preChoose(), calling contains() in
0020 Selector::choose(), and cleared in Selector::reset().
0021 
0022 Example of filling
0023 \code
0024 class ExampleSelector {
0025   ...
0026   edm::ThinnedRefSet<ThingCollection> keysToSave_;
0027 };
0028 
0029 void ExampleSelector::preChoose(edm::Handle<ThingCollection> tc, edm::Event const& e, edm::EventSetup const&) {
0030   auto filler = keysToSave_.fill(edm::RefProd(tc), event.productGetter());
0031   for (auto const& object : event.get(objectCollectionToken_) {
0032     filler.insert(object.refToThing());
0033   }
0034 }
0035 \endcode
0036 
0037 Example of querying if a key is present
0038 \code
0039 bool ExampleSelector::choose(unsigned int iIndex, Thing const& iItem) const {
0040   return keysToSave_.contains(iIndex);
0041 }
0042 \endcode
0043  */
0044 
0045 #include "DataFormats/Common/interface/Handle.h"
0046 #include "DataFormats/Common/interface/Ref.h"
0047 #include "DataFormats/Common/interface/RefItemGet.h"
0048 
0049 #include <unordered_set>
0050 
0051 namespace edm {
0052   class EDProductGetter;
0053 
0054   enum class ThinnedRefSetMode { throwOnInvalidParentRef, ignoreInvalidParentRef };
0055 
0056   template <typename C>
0057   class ThinnedRefSet {
0058   public:
0059     class Filler {
0060     public:
0061       explicit Filler(ThinnedRefSet<C>* set, RefProd<C> thinned, edm::EDProductGetter const& prodGetter)
0062           : set_(set), thinnedRefProd_(thinned), prodGetter_(prodGetter) {}
0063 
0064       template <typename T, typename F>
0065       void insert(Ref<C, T, F> const& ref) {
0066         if (ref.isNonnull()) {
0067           Ref<C, T, F> thinnedRef;
0068           if (set_->invalidParentRefMode_ == ThinnedRefSetMode::ignoreInvalidParentRef) {
0069             thinnedRef = tryThinnedRefFrom(ref, thinnedRefProd_, prodGetter_);
0070           } else {
0071             thinnedRef = thinnedRefFrom(ref, thinnedRefProd_, prodGetter_);
0072           }
0073           if (thinnedRef.isNonnull()) {
0074             set_->keys_.insert(thinnedRef.key());
0075           }
0076         }
0077       }
0078 
0079     private:
0080       ThinnedRefSet<C>* set_;
0081       RefProd<C> thinnedRefProd_;
0082       edm::EDProductGetter const& prodGetter_;
0083     };
0084 
0085     explicit ThinnedRefSet(ThinnedRefSetMode mode = ThinnedRefSetMode::throwOnInvalidParentRef)
0086         : invalidParentRefMode_(mode) {}
0087 
0088     Filler fill(RefProd<C> thinned, edm::EDProductGetter const& prodGetter) {
0089       return Filler(this, thinned, prodGetter);
0090     }
0091 
0092     void clear() { keys_.clear(); }
0093 
0094     bool contains(unsigned int key) const { return keys_.find(key) != keys_.end(); }
0095 
0096   private:
0097     std::unordered_set<unsigned int> keys_;
0098     ThinnedRefSetMode invalidParentRefMode_;
0099   };
0100 }  // namespace edm
0101 
0102 #endif