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