CMS 3D CMS Logo

DetSetRefVector.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_DetSetRefVector_h
2 #define DataFormats_Common_DetSetRefVector_h
3 
4 /*----------------------------------------------------------------------
5 
6 DetSeReftVector: A collection of homogeneous objects that can be used for
7 an EDProduct. DetSetVector is *not* designed for use as a base class
8 (it has no virtual functions).
9 
10 DetSetVector<T> contains a vector<DetSet<T> >, sorted on DetId, and
11 provides fast (O(log n)) lookups, but only O(n) insertion.
12 
13 It provides an interface such that EdmRef2 can directly reference, and
14 provide access to, individual T objects.
15 
16 The collection appears to the user as if it were a sequence of
17 DetSet<T>; e.g., operator[] returns a DetSet<T>&. However, the
18 argument to operator[] specifies the (DetId) identifier of the vector
19 to be returned, *not* the ordinal number of the T to be returned.
20 
21  ------------------
22  It is critical that users DO NOT MODIFY the id data member of a
23  DetSet object in a DetSetVector.
24  ------------------
25 
26 ----------------------------------------------------------------------*/
27 
28 #include <algorithm>
29 #include <vector>
30 
31 #include "boost/concept_check.hpp"
32 #include "boost/iterator/indirect_iterator.hpp"
33 
38 
44 
45 namespace edm {
46 
47  //------------------------------------------------------------
48  // Forward declarations
49  template <typename T, typename C> class DetSetRefVector;
50 
51  //------------------------------------------------------------
52  // Helper function, to regularize throwing of exceptions.
53  //------------------------------------------------------------
54 
55  namespace dsrvdetail
56  {
57  // Throw an edm::Exception with an appropriate message
58  inline
60  {
62  "DetSetRefVector::operator[] called with index not in collection;\nindex value: ", i);
63  }
64  }
65 
66  //------------------------------------------------------------
67  //
68  namespace refhelper {
69  template<typename T, typename C >
71 
72  using result_type = DetSet<T> const*;
73  using first_argument_type = C const&;
75 
77  return &(*(iContainer.find(iIndex)));
78  }
79  };
80  }
81 
82  //allow comparison of edm::Ref<...> to the det_it_type. This allows searching without dereferencing the edm::Ref
83  template <typename T, typename C=DetSetVector<T> >
86  bool operator()(const ref_type& iRef, det_id_type iId) {
87  return iRef.key() < iId;
88  }
89  bool operator()(det_id_type iId, const ref_type& iRef) {
90  return iId < iRef.key();
91  }
92  };
93 
94  template <typename T, typename C=DetSetVector<T> >
95  class DetSetRefVector
96  {
99  BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept);
100  public:
101 
102  typedef DetSet<T> detset;
103  typedef detset value_type;
105  typedef std::vector<ref_type> collection_type;
106 
107  typedef detset const& const_reference;
108 
109  //iterator returns a DetSet<T> instead of a Ref<...>
110  typedef boost::indirect_iterator<typename collection_type::const_iterator> const_iterator;
112 
115 
116  // Add the following only if needed.
117  //template <class InputIterator>
118  //DetSetRefVector(InputIterator b, InputIterator e);
119 
121 
122  DetSetRefVector(const Handle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
123  sets_.reserve(iDets.size());
124  det_id_type sanityCheck = 0;
125  for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(),
126  itDetIdEnd = iDets.end();
127  itDetId != itDetIdEnd;
128  ++itDetId) {
129  assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
130  sanityCheck = *itDetId;
131  //the last 'false' says to not get the data right now
132  sets_.push_back(ref_type(iHandle, *itDetId, false));
133  }
134  }
135 
136  DetSetRefVector(const OrphanHandle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
137  sets_.reserve(iDets.size());
138  det_id_type sanityCheck = 0;
139  for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(),
140  itDetIdEnd = iDets.end();
141  itDetId != itDetIdEnd;
142  ++itDetId) {
143  assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
144  sanityCheck = *itDetId;
145  //the last 'false' says to not get the data right now
146  sets_.push_back(ref_type(iHandle, *itDetId, false));
147  }
148  }
149 
150  DetSetRefVector(const TestHandle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
151  sets_.reserve(iDets.size());
152  det_id_type sanityCheck = 0;
153  for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(),
154  itDetIdEnd = iDets.end();
155  itDetId != itDetIdEnd;
156  ++itDetId) {
157  assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
158  sanityCheck = *itDetId;
159  //the last 'false' says to not get the data right now
160  sets_.push_back(ref_type(iHandle, *itDetId, false));
161  }
162  }
163 
164  void swap(DetSetRefVector& other);
165 
166  DetSetRefVector& operator=(DetSetRefVector const& rhs);
167 
169  bool empty() const;
170 
172  size_type size() const;
173 
174  // Do we need a short-hand method to return the number of T
175  // instances? If so, do we optimize for size (calculate on the
176  // fly) or speed (keep a current cache)?
177 
180  const_iterator find(det_id_type id) const;
181 
185  const_reference operator[](det_id_type i) const;
186 
188  const_iterator begin() const;
189 
191  const_iterator end() const;
192 
195  //void post_insert();
196 
197  //Needed for ROOT storage
199 
200  private:
201  collection_type sets_;
202 
203  };
204 
205  template <typename T, typename C>
206  inline
207  void
208  DetSetRefVector<T,C>::swap(DetSetRefVector<T,C>& other) {
209  sets_.swap(other.sets_);
210  }
211 
212  template <typename T, typename C>
213  inline
217  this->swap(temp);
218  return *this;
219  }
220 
221  template <typename T, typename C>
222  inline
223  bool
225  {
226  return sets_.empty();
227  }
228 
229  template <typename T, typename C>
230  inline
233  {
234  return sets_.size();
235  }
236 
237  template <typename T, typename C>
238  inline
241  {
242  if(empty()) {
243  return sets_.end();
244  }
245  std::pair<typename collection_type::const_iterator,typename collection_type::const_iterator> p =
246  std::equal_range(sets_.begin(), sets_.end(), id, CompareRefDetSet<T,C>());
247  if (p.first == p.second) return sets_.end();
248  // The range indicated by [p.first, p.second) should be exactly of
249  // length 1.
250  assert(std::distance(p.first, p.second) == 1);
251  return p.first;
252  }
253 
254  template <typename T, typename C>
255  inline
258  {
259  // Find the right DetSet, and return a reference to it. Throw if
260  // there is none.
261  const_iterator it = this->find(i);
262  if (it == this->end()) dsrvdetail::_throw_range(i);
263  return *it;
264  }
265 
266  template <typename T, typename C>
267  inline
270  {
271  return sets_.begin();
272  }
273 
274  template <typename T, typename C>
275  inline
278  {
279  return sets_.end();
280  }
281 
282  // Free swap function
283  template <typename T, typename C>
284  inline
285  void
287  a.swap(b);
288  }
289 
290 //specialize behavior of edm::Ref to get access to the 'Det'
291 
292  namespace refhelper {
293  template<typename T, typename C>
295 
296  using result_type = T const*;
299 
301  return &(*(iContainer.find(iIndex.first)->data.begin()+iIndex.second));
302  }
303  };
304 
305  template<typename T, typename C>
308  };
309  }
310 
311  //helper function to make it easier to create a edm::Ref
312 
313  template<class HandleT>
315  makeRefToDetSetRefVector(const HandleT& iHandle,
316  det_id_type iDetID,
317  typename HandleT::element_type::value_type::const_iterator itIter) {
318  typedef typename HandleT::element_type Vec;
320  typename Vec::const_iterator itFound = iHandle->find(iDetID);
321  index += (itIter- itFound->data.begin());
323  }
324 
325  template<class HandleT>
327  makeRefToDetSetRefVector(const HandleT& iHandle,
328  det_id_type iDetID,
329  typename HandleT::element_type::value_type::iterator itIter) {
330  typedef typename HandleT::element_type Vec;
331  typename Vec::detset::const_iterator itIter2 = itIter;
332  return makeRefToDetSetRefVector(iHandle,iDetID,itIter2);
333  }
334 }
335 #endif
size
Write out results.
DetSetRefVector & operator=(DetSetRefVector const &rhs)
Definition: CLHEP.h:16
Ref< typename HandleT::element_type, typename HandleT::element_type::value_type::value_type > makeRefToDetSetRefVector(const HandleT &iHandle, det_id_type iDetID, typename HandleT::element_type::value_type::const_iterator itIter)
DetSetRefVector(const OrphanHandle< C > &iHandle, const std::vector< det_id_type > &iDets)
key_type key() const
Accessor for product key.
Definition: Ref.h:263
#define CMS_CLASS_VERSION(_version_)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
const_iterator find(det_id_type id) const
result_type operator()(first_argument_type iContainer, second_argument_type iIndex)
uint16_t size_type
DetSetRefVector(const Handle< C > &iHandle, const std::vector< det_id_type > &iDets)
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
Ref< C, DetSet< T >, refhelper::FindDetSetForDetSetVector< T, C > > ref_type
void _throw_range(det_id_type i)
std::vector< ref_type > collection_type
static void throwThis(Code category, char const *message0="", char const *message1="", char const *message2="", char const *message3="", char const *message4="")
Definition: EDMException.cc:83
detset const & const_reference
const_iterator begin() const
Return an iterator to the first DetSet.
bool operator()(const ref_type &iRef, det_id_type iId)
bool empty() const
Return true if we contain no DetSets.
T operator[](int i) const
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:521
const_reference operator[](det_id_type i) const
bool operator()(det_id_type iId, const ref_type &iRef)
#define end
Definition: vmac.h:39
std::pair< det_id_type, typename DetSet< T >::collection_type::size_type > second_argument_type
collection_type::size_type size_type
uint32_t det_id_type
Definition: DetSet.h:21
Ref< C, DetSet< T >, refhelper::FindDetSetForDetSetVector< T, C > > ref_type
double b
Definition: hdecay.h:120
size_type size() const
Return the number of contained DetSets.
void swap(DetSetRefVector &other)
#define begin
Definition: vmac.h:32
HLT enums.
double a
Definition: hdecay.h:121
result_type operator()(first_argument_type iContainer, second_argument_type iIndex) const
boost::indirect_iterator< typename collection_type::const_iterator > const_iterator
const_iterator end() const
Return the off-the-end iterator.
long double T
DetSetRefVector(const TestHandle< C > &iHandle, const std::vector< det_id_type > &iDets)