CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RefHelper.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_PatUtils_RefHelper_h
2 #define PhysicsTools_PatUtils_RefHelper_h
3 
6 namespace pat { namespace helper {
7 /*** \brief A class to help manage references and associative containers in some tricky cases (e.g. selection by copy)
8 */
9 template<typename T>
10 class RefHelper {
11  public:
12  typedef typename edm::Ptr<T> Ref;
13 
15  RefHelper(const edm::ValueMap< Ref > &backRefMap) : backRefMap_(backRefMap) { }
16 
18  Ref parentOrNull(const Ref &ref) const ;
19 
21  Ref parentOrSelf(const Ref &ref) const ;
22 
24  Ref ancestorOrSelf(const Ref &ref) const ;
25 
26  bool isRoot(const Ref &ref) const ;
27 
29  bool isAncestorOf(const Ref &old, const Ref &young) const ;
30 
32  bool sharedAncestor(const Ref &ref1, const Ref &ref2) const ;
33 
36  template<typename V, typename SomeRef>
37  V recursiveLookup(const SomeRef &ref, const edm::ValueMap<V> &map) const ;
38 
41  template<typename V, typename SomeRef>
42  V ancestorLookup(const SomeRef &ref, const edm::ValueMap<V> &map) const ;
43 
44  private:
46 };
47 
48 template<typename T>
50  if (backRefMap_.contains(ref.id())) {
51  try {
52  return backRefMap_[ref];
53  } catch (edm::Exception &e) {
55  return Ref();
56  } else {
57  throw;
58  }
59  }
60  } else {
61  return Ref();
62  }
63 }
64 
65 template<typename T>
67  Ref ret = parentOrNull(ref);
68  return ret.isNonnull() ? ret : ref;
69 }
70 
71 template<typename T>
73  Ref ret = ref;
74  do {
75  Ref test = parentOrNull(ret);
76  if (test.isNull()) return ret;
77  ret = test;
78  } while (true);
79 }
80 
81 
82 template<typename T>
83 bool RefHelper<T>::isRoot(const RefHelper<T>::Ref &ref) const {
84  return parentOrNull(ref).isNull();
85 }
86 
87 template<typename T>
88 bool RefHelper<T>::isAncestorOf(const RefHelper<T>::Ref &old, const RefHelper<T>::Ref &young) const {
89  Ref test = young;
90  do {
91  if (test == old) return true;
92  test = parentOrNull(test);
93  } while (test.isNonnull());
94  return false;
95 }
96 
97 template<typename T>
98 bool RefHelper<T>::sharedAncestor(const RefHelper<T>::Ref &ref1, const RefHelper<T>::Ref &ref2) const {
99  return ( ancestorOrSelf(ref1) == ancestorOrSelf(ref2) );
100 }
101 
102 template<typename T>
103 template<typename V, typename SomeRef>
104 V RefHelper<T>::recursiveLookup(const SomeRef &ref, const edm::ValueMap<V> &map) const {
105  Ref test(ref);
106  do {
107  if (map.contains(test.id())) {
108  try {
109  return map[test];
110  } catch (edm::Exception &e) {
112  throw;
113  }
114  }
115  }
116  test = parentOrNull(test);
117  } while (test.isNonnull());
119  "RefHelper: recursive Lookup failed: neither the specified ref nor any of its parents are in the map.\n";
120 }
121 
122 template<typename T>
123 template<typename V, typename SomeRef>
124 V RefHelper<T>::ancestorLookup(const SomeRef &ref, const edm::ValueMap<V> &map) const {
125  Ref tref(ref);
126  return map[ancestorOrSelf(tref)];
127 }
128 
129 } } // namespace
130 #endif
Code categoryCode() const
Definition: EDMException.h:96
edm::Ptr< T > Ref
Definition: RefHelper.h:12
const edm::ValueMap< Ref > & backRefMap_
Definition: RefHelper.h:45
bool sharedAncestor(const Ref &ref1, const Ref &ref2) const
true if the two share the same root
Definition: RefHelper.h:98
Ref parentOrSelf(const Ref &ref) const
Returns a Ref to the direct parent of &quot;ref&quot;, or &quot;ref&quot; itself if it&#39;s already root.
Definition: RefHelper.h:66
RefHelper(const edm::ValueMap< Ref > &backRefMap)
Constructor taking a ValueMap of back-references daughter =&gt; mother.
Definition: RefHelper.h:15
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:152
bool contains(ProductID id) const
Definition: ValueMap.h:148
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:164
Ref parentOrNull(const Ref &ref) const
Returns a Ref to the direct parent of &quot;ref&quot;, or a null Ref if &quot;ref&quot; is already root.
Definition: RefHelper.h:49
bool isAncestorOf(const Ref &old, const Ref &young) const
true if old is some ancestor of young (it does not have to be the root)
Definition: RefHelper.h:88
bool isRoot(const Ref &ref) const
Definition: RefHelper.h:83
V ancestorLookup(const SomeRef &ref, const edm::ValueMap< V > &map) const
Definition: RefHelper.h:124
bool isNull() const
Checks for null.
Definition: Ptr.h:148
V recursiveLookup(const SomeRef &ref, const edm::ValueMap< V > &map) const
Definition: RefHelper.h:104
Ref ancestorOrSelf(const Ref &ref) const
Climbs back the Ref chain and returns the root of the branch starting from &quot;ref&quot;. ...
Definition: RefHelper.h:72