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