File indexing completed on 2021-02-14 12:52:57
0001 #ifndef DataFormats_Common_DetSetVector_h
0002 #define DataFormats_Common_DetSetVector_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
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include <algorithm>
0039 #include <iterator>
0040 #include <vector>
0041
0042 #include <type_traits>
0043 #include "boost/concept_check.hpp"
0044
0045 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0046 #include "DataFormats/Common/interface/DetSet.h"
0047 #include "DataFormats/Common/interface/FillView.h"
0048 #include "DataFormats/Common/interface/Ref.h"
0049 #include "DataFormats/Common/interface/traits.h"
0050
0051 #include "FWCore/Utilities/interface/EDMException.h"
0052
0053 #include "DataFormats/Common/interface/BoolCache.h"
0054
0055 namespace edm {
0056 class ProductID;
0057
0058
0059
0060 template <class T>
0061 class DetSetVector;
0062
0063
0064
0065
0066
0067 namespace detail {
0068
0069 inline void _throw_range(det_id_type i) {
0070 Exception::throwThis(
0071 errors::InvalidReference, "DetSetVector::operator[] called with index not in collection;\nindex value: ", i);
0072 }
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 template <class T>
0086 class DetSetVector : public std::conditional_t<std::is_base_of<edm::DoNotSortUponInsertion, T>::value,
0087 edm::DoNotSortUponInsertion,
0088 Other> {
0089
0090
0091 BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept);
0092
0093 public:
0094 typedef DetSet<T> detset;
0095 typedef detset value_type;
0096 typedef std::vector<detset> collection_type;
0097
0098 typedef detset& reference;
0099 typedef detset const& const_reference;
0100
0101 typedef typename collection_type::iterator iterator;
0102 typedef typename collection_type::const_iterator const_iterator;
0103 typedef typename collection_type::size_type size_type;
0104
0105
0106
0107
0108
0109 DetSetVector();
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 explicit DetSetVector(std::vector<DetSet<T> >& input, bool alreadySorted = false);
0123
0124 void swap(DetSetVector& other);
0125
0126 DetSetVector& operator=(DetSetVector const& other);
0127
0128
0129
0130
0131
0132
0133 void insert(detset const& s);
0134
0135
0136
0137
0138 reference find_or_insert(det_id_type id);
0139
0140
0141 bool empty() const;
0142
0143
0144 size_type size() const;
0145
0146
0147 void reserve(size_t s) { _sets.reserve(s); }
0148
0149
0150
0151
0152
0153
0154
0155 iterator find(det_id_type id);
0156 const_iterator find(det_id_type id) const;
0157
0158
0159
0160
0161 reference operator[](det_id_type i);
0162 const_reference operator[](det_id_type i) const;
0163
0164
0165 iterator begin();
0166 const_iterator begin() const;
0167
0168
0169 iterator end();
0170 const_iterator end() const;
0171
0172
0173
0174 void getIds(std::vector<det_id_type>& result) const;
0175
0176
0177
0178 void post_insert();
0179
0180 void fillView(ProductID const& id, std::vector<void const*>& pointers, FillViewHelperVector& helpers) const;
0181
0182
0183 CMS_CLASS_VERSION(10)
0184
0185 private:
0186 collection_type _sets;
0187 edm::BoolCache _alreadySorted;
0188
0189
0190 void _sort();
0191 };
0192
0193 template <class T>
0194 inline DetSetVector<T>::DetSetVector() : _sets() {}
0195
0196 template <class T>
0197 inline DetSetVector<T>::DetSetVector(std::vector<DetSet<T> >& input, bool alreadySorted)
0198 : _sets(), _alreadySorted(alreadySorted) {
0199 _sets.swap(input);
0200 if (!alreadySorted)
0201 _sort();
0202 }
0203
0204 template <class T>
0205 inline void DetSetVector<T>::swap(DetSetVector<T>& other) {
0206 _sets.swap(other._sets);
0207 bool tmp = _alreadySorted;
0208 _alreadySorted = other._alreadySorted;
0209 other._alreadySorted = tmp;
0210 }
0211
0212 template <class T>
0213 inline DetSetVector<T>& DetSetVector<T>::operator=(DetSetVector<T> const& other) {
0214 DetSetVector<T> temp(other);
0215 swap(temp);
0216 return *this;
0217 }
0218
0219 template <class T>
0220 inline void DetSetVector<T>::insert(detset const& t) {
0221 _alreadySorted = false;
0222
0223 _sets.insert(std::lower_bound(_sets.begin(), _sets.end(), t), t);
0224 #if 0
0225
0226
0227 _sets.push_back(t);
0228
0229 _sort();
0230 #endif
0231 }
0232
0233 template <class T>
0234 inline typename DetSetVector<T>::reference DetSetVector<T>::find_or_insert(det_id_type id) {
0235
0236
0237 std::pair<iterator, iterator> p = std::equal_range(_sets.begin(), _sets.end(), id);
0238
0239
0240
0241 if (p.first != p.second)
0242 return *p.first;
0243
0244
0245
0246 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
0247 return *(_sets.emplace(p.first, id));
0248 #else
0249 return *(_sets.insert(p.first, detset(id)));
0250 #endif
0251 }
0252
0253 template <class T>
0254 inline bool DetSetVector<T>::empty() const {
0255 return _sets.empty();
0256 }
0257
0258 template <class T>
0259 inline typename DetSetVector<T>::size_type DetSetVector<T>::size() const {
0260 return _sets.size();
0261 }
0262
0263 template <class T>
0264 inline typename DetSetVector<T>::iterator DetSetVector<T>::find(det_id_type id) {
0265 _alreadySorted = false;
0266 std::pair<iterator, iterator> p = std::equal_range(_sets.begin(), _sets.end(), id);
0267 if (p.first == p.second)
0268 return _sets.end();
0269
0270
0271
0272
0273
0274 #if 0
0275 assert(std::distance(p.first, p.second) == 1);
0276 #endif
0277
0278 return p.first;
0279 }
0280
0281 template <class T>
0282 inline typename DetSetVector<T>::const_iterator DetSetVector<T>::find(det_id_type id) const {
0283 std::pair<const_iterator, const_iterator> p = std::equal_range(_sets.begin(), _sets.end(), id);
0284 if (p.first == p.second)
0285 return _sets.end();
0286
0287
0288 assert(std::distance(p.first, p.second) == 1);
0289 return p.first;
0290 }
0291
0292 template <class T>
0293 inline typename DetSetVector<T>::reference DetSetVector<T>::operator[](det_id_type i) {
0294 _alreadySorted = false;
0295
0296
0297 iterator it = this->find(i);
0298 if (it == this->end())
0299 detail::_throw_range(i);
0300 return *it;
0301 }
0302
0303 template <class T>
0304 inline typename DetSetVector<T>::const_reference DetSetVector<T>::operator[](det_id_type i) const {
0305
0306
0307 const_iterator it = this->find(i);
0308 if (it == this->end())
0309 detail::_throw_range(i);
0310 return *it;
0311 }
0312
0313 template <class T>
0314 inline typename DetSetVector<T>::iterator DetSetVector<T>::begin() {
0315 _alreadySorted = false;
0316 return _sets.begin();
0317 }
0318
0319 template <class T>
0320 inline typename DetSetVector<T>::const_iterator DetSetVector<T>::begin() const {
0321 return _sets.begin();
0322 }
0323
0324 template <class T>
0325 inline typename DetSetVector<T>::iterator DetSetVector<T>::end() {
0326 _alreadySorted = false;
0327 return _sets.end();
0328 }
0329
0330 template <class T>
0331 inline typename DetSetVector<T>::const_iterator DetSetVector<T>::end() const {
0332 return _sets.end();
0333 }
0334
0335 template <class T>
0336 inline void DetSetVector<T>::getIds(std::vector<det_id_type>& result) const {
0337 std::transform(
0338 this->begin(), this->end(), std::back_inserter(result), std::bind(&DetSet<T>::id, std::placeholders::_1));
0339 }
0340
0341 template <class T>
0342 inline void DetSetVector<T>::post_insert() {
0343 _sets.shrink_to_fit();
0344 if (_alreadySorted)
0345 return;
0346 typename collection_type::iterator i = _sets.begin();
0347 typename collection_type::iterator e = _sets.end();
0348
0349 for (; i != e; ++i) {
0350 i->data.shrink_to_fit();
0351
0352 std::sort(i->data.begin(), i->data.end());
0353 }
0354 }
0355
0356 template <class T>
0357 inline void DetSetVector<T>::_sort() {
0358 std::sort(_sets.begin(), _sets.end());
0359 }
0360
0361 template <class T>
0362 void DetSetVector<T>::fillView(ProductID const& id,
0363 std::vector<void const*>& pointers,
0364 FillViewHelperVector& helpers) const {
0365 detail::reallyFillView(*this, id, pointers, helpers);
0366 }
0367
0368
0369
0370
0371
0372 template <class T>
0373 inline void fillView(DetSetVector<T> const& obj,
0374 ProductID const& id,
0375 std::vector<void const*>& pointers,
0376 FillViewHelperVector& helpers) {
0377 obj.fillView(id, pointers, helpers);
0378 }
0379
0380 template <class T>
0381 struct has_fillView<edm::DetSetVector<T> > {
0382 static bool const value = true;
0383 };
0384
0385
0386 template <class T>
0387 inline void swap(DetSetVector<T>& a, DetSetVector<T>& b) {
0388 a.swap(b);
0389 }
0390
0391 }
0392
0393
0394 namespace edm {
0395
0396 namespace refhelper {
0397 template <typename T>
0398 class FindForDetSetVector {
0399 public:
0400 using first_argument_type = const DetSetVector<T>&;
0401 using second_argument_type = std::pair<det_id_type, typename DetSet<T>::collection_type::size_type>;
0402 using result_type = const T*;
0403
0404 result_type operator()(first_argument_type iContainer, second_argument_type iIndex) {
0405 return &(*(iContainer.find(iIndex.first)->data.begin() + iIndex.second));
0406 }
0407 };
0408
0409 template <typename T>
0410 struct FindTrait<DetSetVector<T>, T> {
0411 typedef FindForDetSetVector<T> value;
0412 };
0413 }
0414
0415
0416
0417 template <class HandleT>
0418 inline Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type> makeRefTo(
0419 const HandleT& iHandle, det_id_type iDetID, typename HandleT::element_type::value_type::const_iterator itIter) {
0420 typedef typename HandleT::element_type Vec;
0421 typename Vec::value_type::collection_type::size_type index = 0;
0422 typename Vec::const_iterator itFound = iHandle->find(iDetID);
0423 if (itFound == iHandle->end()) {
0424 Exception::throwThis(errors::InvalidReference,
0425 "an edm::Ref to an edm::DetSetVector was given a DetId, ",
0426 iDetID,
0427 ", that is not in the DetSetVector");
0428 }
0429 index += (itIter - itFound->data.begin());
0430 if (index >= itFound->data.size()) {
0431 Exception::throwThis(errors::InvalidReference,
0432 "an edm::Ref to a edm::DetSetVector is being made with an interator that is not part of the "
0433 "edm::DetSet itself");
0434 }
0435 return Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>(
0436 iHandle, std::make_pair(iDetID, index));
0437 }
0438
0439 template <class HandleT>
0440 inline Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>
0441 makeRefToDetSetVector(const HandleT& iHandle,
0442 det_id_type iDetID,
0443 typename HandleT::element_type::value_type::iterator itIter) {
0444 typedef typename HandleT::element_type Vec;
0445 typename Vec::detset::const_iterator itIter2 = itIter;
0446 return makeRefTo(iHandle, iDetID, itIter2);
0447 }
0448 }
0449 #endif