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