File indexing completed on 2024-04-06 12:03:51
0001 #ifndef DataFormats_Common_DetSetRefVector_h
0002 #define DataFormats_Common_DetSetRefVector_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <algorithm>
0029 #include <vector>
0030
0031 #include "boost/concept_check.hpp"
0032 #include "boost/iterator/indirect_iterator.hpp"
0033
0034 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0035 #include "DataFormats/Common/interface/traits.h"
0036 #include "DataFormats/Common/interface/DetSet.h"
0037 #include "FWCore/Utilities/interface/EDMException.h"
0038
0039 #include "DataFormats/Common/interface/Ref.h"
0040 #include "DataFormats/Common/interface/DetSetVector.h"
0041 #include "DataFormats/Common/interface/Handle.h"
0042 #include "DataFormats/Common/interface/OrphanHandle.h"
0043 #include "DataFormats/Common/interface/TestHandle.h"
0044
0045 namespace edm {
0046
0047
0048
0049 template <typename T, typename C>
0050 class DetSetRefVector;
0051
0052
0053
0054
0055
0056 namespace dsrvdetail {
0057
0058 inline void _throw_range(det_id_type i) {
0059 Exception::throwThis(errors::InvalidReference,
0060 "DetSetRefVector::operator[] called with index not in collection;\nindex value: ",
0061 i);
0062 }
0063 }
0064
0065
0066
0067 namespace refhelper {
0068 template <typename T, typename C>
0069 struct FindDetSetForDetSetVector {
0070 using result_type = DetSet<T> const*;
0071 using first_argument_type = C const&;
0072 using second_argument_type = edm::det_id_type const;
0073
0074 result_type operator()(first_argument_type iContainer, second_argument_type iIndex) const {
0075 return &(*(iContainer.find(iIndex)));
0076 }
0077 };
0078 }
0079
0080
0081 template <typename T, typename C = DetSetVector<T> >
0082 struct CompareRefDetSet {
0083 typedef Ref<C, DetSet<T>, refhelper::FindDetSetForDetSetVector<T, C> > ref_type;
0084 bool operator()(const ref_type& iRef, det_id_type iId) { return iRef.key() < iId; }
0085 bool operator()(det_id_type iId, const ref_type& iRef) { return iId < iRef.key(); }
0086 };
0087
0088 template <typename T, typename C = DetSetVector<T> >
0089 class DetSetRefVector {
0090
0091
0092 BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept);
0093
0094 public:
0095 typedef DetSet<T> detset;
0096 typedef detset value_type;
0097 typedef Ref<C, DetSet<T>, refhelper::FindDetSetForDetSetVector<T, C> > ref_type;
0098 typedef std::vector<ref_type> collection_type;
0099
0100 typedef detset const& const_reference;
0101
0102
0103 typedef boost::indirect_iterator<typename collection_type::const_iterator> const_iterator;
0104 typedef typename collection_type::size_type size_type;
0105
0106
0107
0108
0109
0110
0111
0112
0113 DetSetRefVector() {}
0114
0115 DetSetRefVector(const Handle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
0116 sets_.reserve(iDets.size());
0117 det_id_type sanityCheck = 0;
0118 for (std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
0119 itDetId != itDetIdEnd;
0120 ++itDetId) {
0121 assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
0122 sanityCheck = *itDetId;
0123
0124 sets_.push_back(ref_type(iHandle, *itDetId, false));
0125 }
0126 }
0127
0128 DetSetRefVector(const OrphanHandle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
0129 sets_.reserve(iDets.size());
0130 det_id_type sanityCheck = 0;
0131 for (std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
0132 itDetId != itDetIdEnd;
0133 ++itDetId) {
0134 assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
0135 sanityCheck = *itDetId;
0136
0137 sets_.push_back(ref_type(iHandle, *itDetId, false));
0138 }
0139 }
0140
0141 DetSetRefVector(const TestHandle<C>& iHandle, const std::vector<det_id_type>& iDets) : sets_() {
0142 sets_.reserve(iDets.size());
0143 det_id_type sanityCheck = 0;
0144 for (std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
0145 itDetId != itDetIdEnd;
0146 ++itDetId) {
0147 assert(sanityCheck <= *itDetId && "vector of det_id_type was not ordered");
0148 sanityCheck = *itDetId;
0149
0150 sets_.push_back(ref_type(iHandle, *itDetId, false));
0151 }
0152 }
0153
0154 void swap(DetSetRefVector& other);
0155
0156 DetSetRefVector& operator=(DetSetRefVector const& rhs);
0157
0158
0159 bool empty() const;
0160
0161
0162 size_type size() const;
0163
0164
0165
0166
0167
0168
0169
0170 const_iterator find(det_id_type id) const;
0171
0172
0173
0174
0175 const_reference operator[](det_id_type i) const;
0176
0177
0178 const_iterator begin() const;
0179
0180
0181 const_iterator end() const;
0182
0183
0184
0185
0186
0187
0188 CMS_CLASS_VERSION(10)
0189
0190 private:
0191 collection_type sets_;
0192 };
0193
0194 template <typename T, typename C>
0195 inline void DetSetRefVector<T, C>::swap(DetSetRefVector<T, C>& other) {
0196 sets_.swap(other.sets_);
0197 }
0198
0199 template <typename T, typename C>
0200 inline DetSetRefVector<T, C>& DetSetRefVector<T, C>::operator=(DetSetRefVector<T, C> const& rhs) {
0201 DetSetRefVector<T, C> temp(rhs);
0202 this->swap(temp);
0203 return *this;
0204 }
0205
0206 template <typename T, typename C>
0207 inline bool DetSetRefVector<T, C>::empty() const {
0208 return sets_.empty();
0209 }
0210
0211 template <typename T, typename C>
0212 inline typename DetSetRefVector<T, C>::size_type DetSetRefVector<T, C>::size() const {
0213 return sets_.size();
0214 }
0215
0216 template <typename T, typename C>
0217 inline typename DetSetRefVector<T, C>::const_iterator DetSetRefVector<T, C>::find(det_id_type id) const {
0218 if (empty()) {
0219 return sets_.end();
0220 }
0221 std::pair<typename collection_type::const_iterator, typename collection_type::const_iterator> p =
0222 std::equal_range(sets_.begin(), sets_.end(), id, CompareRefDetSet<T, C>());
0223 if (p.first == p.second)
0224 return sets_.end();
0225
0226
0227 assert(std::distance(p.first, p.second) == 1);
0228 return p.first;
0229 }
0230
0231 template <typename T, typename C>
0232 inline typename DetSetRefVector<T, C>::const_reference DetSetRefVector<T, C>::operator[](det_id_type i) const {
0233
0234
0235 const_iterator it = this->find(i);
0236 if (it == this->end())
0237 dsrvdetail::_throw_range(i);
0238 return *it;
0239 }
0240
0241 template <typename T, typename C>
0242 inline typename DetSetRefVector<T, C>::const_iterator DetSetRefVector<T, C>::begin() const {
0243 return sets_.begin();
0244 }
0245
0246 template <typename T, typename C>
0247 inline typename DetSetRefVector<T, C>::const_iterator DetSetRefVector<T, C>::end() const {
0248 return sets_.end();
0249 }
0250
0251
0252 template <typename T, typename C>
0253 inline void swap(DetSetRefVector<T, C>& a, DetSetRefVector<T, C>& b) {
0254 a.swap(b);
0255 }
0256
0257
0258
0259 namespace refhelper {
0260 template <typename T, typename C>
0261 struct FindForDetSetRefVector {
0262 using result_type = T const*;
0263 using first_argument_type = DetSetRefVector<T, C> const&;
0264 using second_argument_type = std::pair<det_id_type, typename DetSet<T>::collection_type::size_type>;
0265
0266 result_type operator()(first_argument_type iContainer, second_argument_type iIndex) {
0267 return &(*(iContainer.find(iIndex.first)->data.begin() + iIndex.second));
0268 }
0269 };
0270
0271 template <typename T, typename C>
0272 struct FindTrait<DetSetRefVector<T, C>, T> {
0273 typedef FindForDetSetRefVector<T, C> value;
0274 };
0275 }
0276
0277
0278
0279 template <class HandleT>
0280 Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type> makeRefToDetSetRefVector(
0281 const HandleT& iHandle, det_id_type iDetID, typename HandleT::element_type::value_type::const_iterator itIter) {
0282 typedef typename HandleT::element_type Vec;
0283 typename Vec::value_type::collection_type::size_type index = 0;
0284 typename Vec::const_iterator itFound = iHandle->find(iDetID);
0285 index += (itIter - itFound->data.begin());
0286 return Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>(
0287 iHandle, std::make_pair(iDetID, index));
0288 }
0289
0290 template <class HandleT>
0291 Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type> makeRefToDetSetRefVector(
0292 const HandleT& iHandle, det_id_type iDetID, typename HandleT::element_type::value_type::iterator itIter) {
0293 typedef typename HandleT::element_type Vec;
0294 typename Vec::detset::const_iterator itIter2 = itIter;
0295 return makeRefToDetSetRefVector(iHandle, iDetID, itIter2);
0296 }
0297 }
0298 #endif