00001 #ifndef DataFormats_Common_DetSetVector_h
00002 #define DataFormats_Common_DetSetVector_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <algorithm>
00039 #include <iterator>
00040 #include <vector>
00041
00042 #include "boost/concept_check.hpp"
00043 #include "boost/mpl/if.hpp"
00044 #include "boost/bind.hpp"
00045
00046
00047 #include "DataFormats/Common/interface/DetSet.h"
00048 #include "DataFormats/Common/interface/FillView.h"
00049 #include "DataFormats/Common/interface/Ref.h"
00050 #include "DataFormats/Common/interface/traits.h"
00051
00052 #include "FWCore/Utilities/interface/EDMException.h"
00053
00054 #include "DataFormats/Common/interface/BoolCache.h"
00055
00056 namespace edm {
00057 class ProductID;
00058
00059
00060
00061 template <class T> class DetSetVector;
00062
00063
00064
00065
00066
00067 namespace detail {
00068
00069 inline
00070 void _throw_range(det_id_type i) {
00071 Exception::throwThis(errors::InvalidReference,
00072 "DetSetVector::operator[] called with index not in collection;\nindex value: ", i);
00073 }
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 template <class T>
00087 class DetSetVector :
00088 public boost::mpl::if_c<boost::is_base_of<edm::DoNotSortUponInsertion, T>::value,
00089 edm::DoNotSortUponInsertion,
00090 Other>::type
00091 {
00094 BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept);
00095 public:
00096
00097 typedef DetSet<T> detset;
00098 typedef detset value_type;
00099 typedef std::vector<detset> collection_type;
00100
00101 typedef detset& reference;
00102 typedef detset const& const_reference;
00103
00104 typedef typename collection_type::iterator iterator;
00105 typedef typename collection_type::const_iterator const_iterator;
00106 typedef typename collection_type::size_type size_type;
00107
00110
00112 DetSetVector();
00113
00125 explicit DetSetVector(std::vector<DetSet<T> > & input, bool alreadySorted=false);
00126
00127
00128 void swap(DetSetVector& other);
00129
00130 DetSetVector& operator= (DetSetVector const& other);
00131
00133
00134
00135
00136
00137 void insert(detset const& s);
00138
00142 reference find_or_insert(det_id_type id);
00143
00145 bool empty() const;
00146
00148 size_type size() const;
00149
00150
00151
00152
00153
00156 iterator find(det_id_type id);
00157 const_iterator find(det_id_type id) const;
00158
00162 reference operator[](det_id_type i);
00163 const_reference operator[](det_id_type i) const;
00164
00166 iterator begin();
00167 const_iterator begin() const;
00168
00170 iterator end();
00171 const_iterator end() const;
00172
00175 void getIds(std::vector<det_id_type> & result) const;
00176
00179 void post_insert();
00180
00181 void fillView(ProductID const& id,
00182 std::vector<void const*>& pointers,
00183 helper_vector& helpers) const;
00184
00185 private:
00186 collection_type _sets;
00187 edm::BoolCache _alreadySorted;
00188
00190 void _sort();
00191
00192 };
00193
00194 template <class T>
00195 inline
00196 DetSetVector<T>::DetSetVector() :
00197 _sets()
00198 { }
00199
00200 template <class T>
00201 inline
00202 DetSetVector<T>::DetSetVector(std::vector<DetSet<T> > & input, bool alreadySorted) :
00203 _sets(), _alreadySorted(alreadySorted)
00204 {
00205 _sets.swap(input);
00206 if (!alreadySorted) _sort();
00207 }
00208
00209 template <class T>
00210 inline
00211 void
00212 DetSetVector<T>::swap(DetSetVector<T>& other) {
00213 _sets.swap(other._sets);
00214 bool tmp = _alreadySorted; _alreadySorted = other._alreadySorted; other._alreadySorted = tmp;
00215 }
00216
00217 template <class T>
00218 inline
00219 DetSetVector<T>&
00220 DetSetVector<T>::operator= (DetSetVector<T> const& other)
00221 {
00222 DetSetVector<T> temp(other);
00223 swap(temp);
00224 return *this;
00225 }
00226
00227 template <class T>
00228 inline
00229 void
00230 DetSetVector<T>::insert(detset const& t) {
00231 _alreadySorted = false;
00232
00233 _sets.insert(std::lower_bound(_sets.begin(),
00234 _sets.end(),
00235 t),
00236 t);
00237 #if 0
00238
00239
00240 _sets.push_back(t);
00241
00242 _sort();
00243 #endif
00244 }
00245
00246 template <class T>
00247 inline
00248 typename DetSetVector<T>::reference
00249 DetSetVector<T>::find_or_insert(det_id_type id) {
00250
00251
00252 std::pair<iterator,iterator> p =
00253 std::equal_range(_sets.begin(), _sets.end(), id);
00254
00255
00256
00257 if (p.first != p.second) return *p.first;
00258
00259
00260
00261 return *(_sets.insert(p.first, detset(id)));
00262 }
00263
00264 template <class T>
00265 inline
00266 bool
00267 DetSetVector<T>::empty() const {
00268 return _sets.empty();
00269 }
00270
00271 template <class T>
00272 inline
00273 typename DetSetVector<T>::size_type
00274 DetSetVector<T>::size() const {
00275 return _sets.size();
00276 }
00277
00278 template <class T>
00279 inline
00280 typename DetSetVector<T>::iterator
00281 DetSetVector<T>::find(det_id_type id) {
00282 _alreadySorted = false;
00283 std::pair<iterator,iterator> p =
00284 std::equal_range(_sets.begin(), _sets.end(), id);
00285 if (p.first == p.second) return _sets.end();
00286
00287
00288
00289
00290
00291 #if 0
00292 assert(std::distance(p.first, p.second) == 1);
00293 #endif
00294
00295 return p.first;
00296 }
00297
00298 template <class T>
00299 inline
00300 typename DetSetVector<T>::const_iterator
00301 DetSetVector<T>::find(det_id_type id) const {
00302 std::pair<const_iterator,const_iterator> p =
00303 std::equal_range(_sets.begin(), _sets.end(), id);
00304 if (p.first == p.second) return _sets.end();
00305
00306
00307 assert(std::distance(p.first, p.second) == 1);
00308 return p.first;
00309 }
00310
00311 template <class T>
00312 inline
00313 typename DetSetVector<T>::reference
00314 DetSetVector<T>::operator[](det_id_type i) {
00315 _alreadySorted = false;
00316
00317
00318 iterator it = this->find(i);
00319 if (it == this->end()) detail::_throw_range(i);
00320 return *it;
00321 }
00322
00323 template <class T>
00324 inline
00325 typename DetSetVector<T>::const_reference
00326 DetSetVector<T>::operator[](det_id_type i) const {
00327
00328
00329 const_iterator it = this->find(i);
00330 if (it == this->end()) detail::_throw_range(i);
00331 return *it;
00332 }
00333
00334 template <class T>
00335 inline
00336 typename DetSetVector<T>::iterator
00337 DetSetVector<T>::begin() {
00338 _alreadySorted = false;
00339 return _sets.begin();
00340 }
00341
00342 template <class T>
00343 inline
00344 typename DetSetVector<T>::const_iterator
00345 DetSetVector<T>::begin() const {
00346 return _sets.begin();
00347 }
00348
00349 template <class T>
00350 inline
00351 typename DetSetVector<T>::iterator
00352 DetSetVector<T>::end() {
00353 _alreadySorted = false;
00354 return _sets.end();
00355 }
00356
00357 template <class T>
00358 inline
00359 typename DetSetVector<T>::const_iterator
00360 DetSetVector<T>::end() const {
00361 return _sets.end();
00362 }
00363
00364
00365 template <class T>
00366 inline
00367 void
00368 DetSetVector<T>::getIds(std::vector<det_id_type> & result) const
00369 {
00370 std::transform(this->begin(), this->end(),
00371 std::back_inserter(result),
00372 boost::bind(&DetSet<T>::id,_1));
00373 }
00374
00375 template <class T>
00376 inline
00377 void
00378 DetSetVector<T>::post_insert() {
00379 if (_alreadySorted) return;
00380 typename collection_type::iterator i = _sets.begin();
00381 typename collection_type::iterator e = _sets.end();
00382
00383 for (; i != e; ++i) {
00384
00385 std::sort(i->data.begin(), i->data.end());
00386 }
00387 }
00388
00389 template <class T>
00390 inline
00391 void
00392 DetSetVector<T>::_sort() {
00393 std::sort(_sets.begin(), _sets.end());
00394 }
00395
00396 template<class T>
00397 void DetSetVector<T>::fillView(ProductID const& id,
00398 std::vector<void const*>& pointers,
00399 helper_vector& helpers) const
00400 {
00401 detail::reallyFillView(*this, id, pointers, helpers);
00402 }
00403
00404
00405
00406
00407
00408 template <class T>
00409 inline
00410 void
00411 fillView(DetSetVector<T> const& obj,
00412 ProductID const& id,
00413 std::vector<void const*>& pointers,
00414 helper_vector& helpers)
00415 {
00416 obj.fillView(id, pointers, helpers);
00417 }
00418
00419 template <class T>
00420 struct has_fillView<edm::DetSetVector<T> >
00421 {
00422 static bool const value = true;
00423 };
00424
00425
00426
00427 template <class T>
00428 inline
00429 void
00430 swap(DetSetVector<T>& a, DetSetVector<T>& b)
00431 {
00432 a.swap(b);
00433 }
00434
00435 }
00436
00437
00438
00439 namespace edm {
00440
00441 namespace refhelper {
00442 template<typename T>
00443 class FindForDetSetVector : public std::binary_function<const DetSetVector<T>&, std::pair<det_id_type, typename DetSet<T>::collection_type::size_type>, const T*> {
00444 public:
00445 typedef FindForDetSetVector<T> self;
00446 typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
00447 return &(*(iContainer.find(iIndex.first)->data.begin()+iIndex.second));
00448 }
00449 };
00450
00451 template<typename T>
00452 struct FindTrait<DetSetVector<T>,T> {
00453 typedef FindForDetSetVector<T> value;
00454 };
00455 }
00456
00457
00458
00459 template<class HandleT>
00460 Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>
00461 makeRefTo(const HandleT& iHandle,
00462 det_id_type iDetID,
00463 typename HandleT::element_type::value_type::const_iterator itIter) {
00464 typedef typename HandleT::element_type Vec;
00465 typename Vec::value_type::collection_type::size_type index=0;
00466 typename Vec::const_iterator itFound = iHandle->find(iDetID);
00467 if(itFound == iHandle->end()) {
00468 Exception::throwThis(errors::InvalidReference,
00469 "an edm::Ref to an edm::DetSetVector was given a DetId, ", iDetID, ", that is not in the DetSetVector");
00470 }
00471 index += (itIter- itFound->data.begin());
00472 if(index >= itFound->data.size()) {
00473 Exception::throwThis(errors::InvalidReference,
00474 "an edm::Ref to a edm::DetSetVector is being made with an interator that is not part of the edm::DetSet itself");
00475 }
00476 return Ref<typename HandleT::element_type,
00477 typename HandleT::element_type::value_type::value_type>
00478 (iHandle,std::make_pair(iDetID,index));
00479 }
00480
00481 template<class HandleT>
00482 Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>
00483 makeRefToDetSetVector(const HandleT& iHandle,
00484 det_id_type iDetID,
00485 typename HandleT::element_type::value_type::iterator itIter) {
00486 typedef typename HandleT::element_type Vec;
00487 typename Vec::detset::const_iterator itIter2 = itIter;
00488 return makeRefTo(iHandle,iDetID,itIter2);
00489 }
00490 }
00491 #endif