00001 #ifndef DataFormats_Common_DetSetRefVector_h
00002 #define DataFormats_Common_DetSetRefVector_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 #include <algorithm>
00029 #include <vector>
00030
00031 #include "boost/concept_check.hpp"
00032 #include "boost/iterator/indirect_iterator.hpp"
00033
00034 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00035 #include "DataFormats/Common/interface/traits.h"
00036 #include "DataFormats/Common/interface/DetSet.h"
00037 #include "FWCore/Utilities/interface/EDMException.h"
00038
00039 #include "DataFormats/Common/interface/Ref.h"
00040 #include "DataFormats/Common/interface/DetSetVector.h"
00041 #include "DataFormats/Common/interface/Handle.h"
00042 #include "DataFormats/Common/interface/OrphanHandle.h"
00043 #include "DataFormats/Common/interface/TestHandle.h"
00044
00045 namespace edm {
00046
00047
00048
00049 template <typename T, typename C> class DetSetRefVector;
00050
00051
00052
00053
00054
00055 namespace dsrvdetail
00056 {
00057
00058 inline
00059 void _throw_range(det_id_type i)
00060 {
00061 Exception::throwThis(errors::InvalidReference,
00062 "DetSetRefVector::operator[] called with index not in collection;\nindex value: ", i);
00063 }
00064 }
00065
00066
00067
00068 namespace refhelper {
00069 template<typename T, typename C >
00070 struct FindDetSetForDetSetVector : public std::binary_function<const C &, edm::det_id_type, const DetSet<T>*> {
00071 typedef FindDetSetForDetSetVector<T,C> self;
00072 typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) const {
00073 return &(*(iContainer.find(iIndex)));
00074 }
00075 };
00076 }
00077
00078
00079 template <typename T, typename C=DetSetVector<T> >
00080 struct CompareRefDetSet {
00081 typedef Ref<C, DetSet<T>, refhelper::FindDetSetForDetSetVector<T,C> > ref_type;
00082 bool operator()(const ref_type& iRef, det_id_type iId) {
00083 return iRef.key() < iId;
00084 }
00085 bool operator()(det_id_type iId, const ref_type& iRef) {
00086 return iId < iRef.key();
00087 }
00088 };
00089
00090 template <typename T, typename C=DetSetVector<T> >
00091 class DetSetRefVector
00092 {
00095 BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept);
00096 public:
00097
00098 typedef DetSet<T> detset;
00099 typedef detset value_type;
00100 typedef Ref<C, DetSet<T>, refhelper::FindDetSetForDetSetVector<T,C> > ref_type;
00101 typedef std::vector<ref_type> collection_type;
00102
00103 typedef detset const& const_reference;
00104
00105
00106 typedef boost::indirect_iterator<typename collection_type::const_iterator> const_iterator;
00107 typedef typename collection_type::size_type size_type;
00108
00111
00112
00113
00114
00115
00116 DetSetRefVector() {}
00117
00118 DetSetRefVector(const Handle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
00119 sets_.reserve(iDets.size());
00120 det_id_type sanityCheck = 0;
00121 for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(),
00122 itDetIdEnd = iDets.end();
00123 itDetId != itDetIdEnd;
00124 ++itDetId) {
00125 assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
00126 sanityCheck = *itDetId;
00127
00128 sets_.push_back(ref_type(iHandle, *itDetId, false));
00129 }
00130 }
00131
00132 DetSetRefVector(const OrphanHandle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
00133 sets_.reserve(iDets.size());
00134 det_id_type sanityCheck = 0;
00135 for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(),
00136 itDetIdEnd = iDets.end();
00137 itDetId != itDetIdEnd;
00138 ++itDetId) {
00139 assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
00140 sanityCheck = *itDetId;
00141
00142 sets_.push_back(ref_type(iHandle, *itDetId, false));
00143 }
00144 }
00145
00146 DetSetRefVector(const TestHandle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
00147 sets_.reserve(iDets.size());
00148 det_id_type sanityCheck = 0;
00149 for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(),
00150 itDetIdEnd = iDets.end();
00151 itDetId != itDetIdEnd;
00152 ++itDetId) {
00153 assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
00154 sanityCheck = *itDetId;
00155
00156 sets_.push_back(ref_type(iHandle, *itDetId, false));
00157 }
00158 }
00159
00160 void swap(DetSetRefVector& other);
00161
00162 DetSetRefVector& operator=(DetSetRefVector const& rhs);
00163
00165 bool empty() const;
00166
00168 size_type size() const;
00169
00170
00171
00172
00173
00176 const_iterator find(det_id_type id) const;
00177
00181 const_reference operator[](det_id_type i) const;
00182
00184 const_iterator begin() const;
00185
00187 const_iterator end() const;
00188
00191
00192
00193
00194 CMS_CLASS_VERSION(10)
00195
00196 private:
00197 collection_type sets_;
00198
00199 };
00200
00201 template <typename T, typename C>
00202 inline
00203 void
00204 DetSetRefVector<T,C>::swap(DetSetRefVector<T,C>& other) {
00205 sets_.swap(other.sets_);
00206 }
00207
00208 template <typename T, typename C>
00209 inline
00210 DetSetRefVector<T ,C>&
00211 DetSetRefVector<T, C>::operator=(DetSetRefVector<T,C> const& rhs) {
00212 DetSetRefVector<T, C> temp(rhs);
00213 this->swap(temp);
00214 return *this;
00215 }
00216
00217 template <typename T, typename C>
00218 inline
00219 bool
00220 DetSetRefVector<T,C>::empty() const
00221 {
00222 return sets_.empty();
00223 }
00224
00225 template <typename T, typename C>
00226 inline
00227 typename DetSetRefVector<T,C>::size_type
00228 DetSetRefVector<T,C>::size() const
00229 {
00230 return sets_.size();
00231 }
00232
00233 template <typename T, typename C>
00234 inline
00235 typename DetSetRefVector<T,C>::const_iterator
00236 DetSetRefVector<T,C>::find(det_id_type id) const
00237 {
00238 if(empty()) {
00239 return sets_.end();
00240 }
00241 std::pair<typename collection_type::const_iterator,typename collection_type::const_iterator> p =
00242 std::equal_range(sets_.begin(), sets_.end(), id, CompareRefDetSet<T,C>());
00243 if (p.first == p.second) return sets_.end();
00244
00245
00246 assert(std::distance(p.first, p.second) == 1);
00247 return p.first;
00248 }
00249
00250 template <typename T, typename C>
00251 inline
00252 typename DetSetRefVector<T,C>::const_reference
00253 DetSetRefVector<T,C>::operator[](det_id_type i) const
00254 {
00255
00256
00257 const_iterator it = this->find(i);
00258 if (it == this->end()) dsrvdetail::_throw_range(i);
00259 return *it;
00260 }
00261
00262 template <typename T, typename C>
00263 inline
00264 typename DetSetRefVector<T,C>::const_iterator
00265 DetSetRefVector<T,C>::begin() const
00266 {
00267 return sets_.begin();
00268 }
00269
00270 template <typename T, typename C>
00271 inline
00272 typename DetSetRefVector<T,C>::const_iterator
00273 DetSetRefVector<T,C>::end() const
00274 {
00275 return sets_.end();
00276 }
00277
00278
00279 template <typename T, typename C>
00280 inline
00281 void
00282 swap(DetSetRefVector<T, C>& a, DetSetRefVector<T, C>& b) {
00283 a.swap(b);
00284 }
00285
00286
00287
00288 namespace refhelper {
00289 template<typename T, typename C>
00290 struct FindForDetSetRefVector : public std::binary_function<const DetSetRefVector<T,C>&, std::pair<det_id_type, typename DetSet<T>::collection_type::size_type>, const T*> {
00291 typedef FindForDetSetRefVector<T,C> self;
00292 typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
00293 return &(*(iContainer.find(iIndex.first)->data.begin()+iIndex.second));
00294 }
00295 };
00296
00297 template<typename T, typename C>
00298 struct FindTrait<DetSetRefVector<T,C>,T> {
00299 typedef FindForDetSetRefVector<T,C> value;
00300 };
00301 }
00302
00303
00304
00305 template<class HandleT>
00306 Ref< typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>
00307 makeRefToDetSetRefVector(const HandleT& iHandle,
00308 det_id_type iDetID,
00309 typename HandleT::element_type::value_type::const_iterator itIter) {
00310 typedef typename HandleT::element_type Vec;
00311 typename Vec::value_type::collection_type::size_type index=0;
00312 typename Vec::const_iterator itFound = iHandle->find(iDetID);
00313 index += (itIter- itFound->data.begin());
00314 return Ref< typename HandleT::element_type, typename HandleT::element_type::value_type::value_type> (iHandle,std::make_pair(iDetID,index));
00315 }
00316
00317 template<class HandleT>
00318 Ref< typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>
00319 makeRefToDetSetRefVector(const HandleT& iHandle,
00320 det_id_type iDetID,
00321 typename HandleT::element_type::value_type::iterator itIter) {
00322 typedef typename HandleT::element_type Vec;
00323 typename Vec::detset::const_iterator itIter2 = itIter;
00324 return makeRefToDetSetRefVector(iHandle,iDetID,itIter2);
00325 }
00326 }
00327 #endif