File indexing completed on 2024-04-06 12:03:51
0001 #ifndef DataFormats_Common_DetSetVectorNew_h
0002 #define DataFormats_Common_DetSetVectorNew_h
0003
0004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0005 #include "DataFormats/Common/interface/DetSetNew.h"
0006 #include "DataFormats/Common/interface/traits.h"
0007
0008 #include <boost/iterator/transform_iterator.hpp>
0009 #include "FWCore/Utilities/interface/Exception.h"
0010 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0011
0012 #include <atomic>
0013 #include <memory>
0014 #include <vector>
0015 #include <cassert>
0016
0017 #include <algorithm>
0018 #include <functional>
0019 #include <iterator>
0020 #include <utility>
0021
0022 class TestDetSet;
0023
0024 namespace edm {
0025 namespace refhelper {
0026 template <typename T>
0027 struct FindForNewDetSetVector;
0028 }
0029 }
0030
0031
0032 namespace edmNew {
0033 typedef uint32_t det_id_type;
0034
0035 struct CapacityExaustedException : public cms::Exception {
0036 CapacityExaustedException() : cms::Exception("Capacity exausted in DetSetVectorNew") {}
0037 };
0038
0039 namespace dslv {
0040 template <typename T>
0041 class LazyGetter;
0042
0043 }
0044
0045
0046
0047
0048 namespace dstvdetails {
0049
0050 void errorFilling();
0051 void notSafe();
0052 void errorIdExists(det_id_type iid);
0053 void throw_range(det_id_type iid);
0054
0055 struct DetSetVectorTrans {
0056 typedef unsigned int size_type;
0057 typedef unsigned int id_type;
0058
0059 DetSetVectorTrans() : m_filling(false), m_dataSize(0) {}
0060 DetSetVectorTrans& operator=(const DetSetVectorTrans&) = delete;
0061
0062 DetSetVectorTrans(const DetSetVectorTrans& rh)
0063 :
0064 m_filling(false) {
0065
0066 assert(rh.m_filling == false);
0067 m_getter = rh.m_getter;
0068 m_dataSize.store(rh.m_dataSize.load());
0069 }
0070
0071 DetSetVectorTrans(DetSetVectorTrans&& rh)
0072 :
0073 m_filling(false) {
0074
0075 assert(rh.m_filling == false);
0076 m_getter = std::move(rh.m_getter);
0077 m_dataSize.store(rh.m_dataSize.exchange(m_dataSize.load()));
0078 }
0079 DetSetVectorTrans& operator=(DetSetVectorTrans&& rh) {
0080
0081 assert(m_filling == false);
0082 assert(rh.m_filling == false);
0083 m_getter = std::move(rh.m_getter);
0084 m_dataSize.store(rh.m_dataSize.exchange(m_dataSize.load()));
0085 return *this;
0086 }
0087 mutable std::atomic<bool> m_filling;
0088 std::shared_ptr<void const> m_getter;
0089 mutable std::atomic<size_type> m_dataSize;
0090
0091 void swap(DetSetVectorTrans& rh) {
0092
0093 assert(m_filling == false);
0094 assert(rh.m_filling == false);
0095
0096 std::swap(m_getter, rh.m_getter);
0097 m_dataSize.store(rh.m_dataSize.exchange(m_dataSize.load()));
0098 }
0099
0100 struct Item {
0101 Item(id_type i = 0, int io = -1, size_type is = 0) : id(i), offset(io), size(is) {}
0102
0103 Item(Item const& rh) noexcept : id(rh.id), offset(int(rh.offset)), size(rh.size) {}
0104 Item& operator=(Item const& rh) noexcept {
0105 id = rh.id;
0106 offset = int(rh.offset);
0107 size = rh.size;
0108 return *this;
0109 }
0110 Item(Item&& rh) noexcept : id(rh.id), offset(int(rh.offset)), size(rh.size) {}
0111 Item& operator=(Item&& rh) noexcept {
0112 id = rh.id;
0113 offset = int(rh.offset);
0114 size = rh.size;
0115 return *this;
0116 }
0117
0118 id_type id;
0119 mutable std::atomic<int> offset;
0120 bool initialize() const {
0121 int expected = -1;
0122 return offset.compare_exchange_strong(expected, -2);
0123 }
0124 CMS_THREAD_GUARD(offset) mutable size_type size;
0125
0126 bool uninitialized() const { return (-1) == offset; }
0127 bool initializing() const { return (-2) == offset; }
0128 bool isValid() const { return offset >= 0; }
0129 bool operator<(Item const& rh) const { return id < rh.id; }
0130 operator id_type() const { return id; }
0131 };
0132
0133 bool ready() const {
0134 bool expected = false;
0135 if (!m_filling.compare_exchange_strong(expected, true))
0136 errorFilling();
0137 return true;
0138 }
0139 };
0140
0141 inline void throwCapacityExausted() { throw CapacityExaustedException(); }
0142 }
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 template <typename T>
0155 class DetSetVector : private dstvdetails::DetSetVectorTrans {
0156 public:
0157 typedef dstvdetails::DetSetVectorTrans Trans;
0158 typedef Trans::Item Item;
0159 typedef unsigned int size_type;
0160 typedef unsigned int id_type;
0161 typedef T data_type;
0162 typedef edmNew::DetSetVector<T> self;
0163 typedef edmNew::DetSet<T> DetSet;
0164 typedef dslv::LazyGetter<T> Getter;
0165
0166 typedef DetSet value_type;
0167 typedef id_type key_type;
0168
0169 typedef std::vector<Item> IdContainer;
0170 typedef std::vector<data_type> DataContainer;
0171 typedef typename IdContainer::iterator IdIter;
0172 typedef typename std::vector<data_type>::iterator DataIter;
0173 typedef std::pair<IdIter, DataIter> IterPair;
0174 typedef typename IdContainer::const_iterator const_IdIter;
0175 typedef typename std::vector<data_type>::const_iterator const_DataIter;
0176 typedef std::pair<const_IdIter, const_DataIter> const_IterPair;
0177
0178 typedef typename edm::refhelper::FindForNewDetSetVector<data_type> RefFinder;
0179
0180 struct IterHelp {
0181 typedef DetSet result_type;
0182
0183 IterHelp() : m_v(nullptr), m_update(false) {}
0184 IterHelp(DetSetVector<T> const& iv, bool iup) : m_v(&iv), m_update(iup) {}
0185
0186 result_type operator()(Item const& item) const { return result_type(*m_v, item, m_update); }
0187
0188 private:
0189 DetSetVector<T> const* m_v;
0190 bool m_update;
0191 };
0192
0193 typedef boost::transform_iterator<IterHelp, const_IdIter> const_iterator;
0194 typedef std::pair<const_iterator, const_iterator> Range;
0195
0196
0197
0198 class FastFiller {
0199 public:
0200 typedef typename DetSetVector<T>::data_type value_type;
0201 typedef typename DetSetVector<T>::id_type key_type;
0202 typedef typename DetSetVector<T>::id_type id_type;
0203 typedef typename DetSetVector<T>::size_type size_type;
0204
0205
0206 static DetSetVector<T>::Item& dummy() {
0207 assert(false);
0208 static DetSetVector<T>::Item d;
0209 return d;
0210 }
0211
0212 FastFiller(DetSetVector<T>& iv, id_type id, bool isaveEmpty = false)
0213 : m_v(iv), m_item(m_v.ready() ? m_v.push_back(id) : dummy()), m_saveEmpty(isaveEmpty) {
0214 if (m_v.onDemand())
0215 dstvdetails::notSafe();
0216 }
0217
0218 FastFiller(DetSetVector<T>& iv, typename DetSetVector<T>::Item& it, bool isaveEmpty = false)
0219 : m_v(iv), m_item(it), m_saveEmpty(isaveEmpty) {
0220 if (m_v.onDemand())
0221 dstvdetails::notSafe();
0222 if (m_v.ready())
0223 m_item.offset = int(m_v.m_data.size());
0224 }
0225 ~FastFiller() {
0226 if (!m_saveEmpty && m_item.size == 0) {
0227 m_v.pop_back(m_item.id);
0228 }
0229 assert(m_v.m_filling == true);
0230 m_v.m_filling = false;
0231 }
0232
0233 void abort() {
0234 m_v.pop_back(m_item.id);
0235 m_saveEmpty = true;
0236 }
0237
0238 void checkCapacityExausted() const {
0239 if (m_v.onDemand() && m_v.m_data.size() == m_v.m_data.capacity())
0240 dstvdetails::throwCapacityExausted();
0241 }
0242
0243 void checkCapacityExausted(size_type s) const {
0244 if (m_v.onDemand() && m_v.m_data.size() + s > m_v.m_data.capacity())
0245 dstvdetails::throwCapacityExausted();
0246 }
0247
0248 void reserve(size_type s) {
0249 if (m_item.offset + s <= m_v.m_data.capacity())
0250 return;
0251 if (m_v.onDemand())
0252 dstvdetails::throwCapacityExausted();
0253 m_v.m_data.reserve(m_item.offset + s);
0254 }
0255
0256 void resize(size_type s) {
0257 checkCapacityExausted(s);
0258 m_v.m_data.resize(m_item.offset + s);
0259 m_v.m_dataSize = m_v.m_data.size();
0260 m_item.size = s;
0261 }
0262
0263 id_type id() const { return m_item.id; }
0264 size_type size() const { return m_item.size; }
0265 bool empty() const { return m_item.size == 0; }
0266
0267 data_type& operator[](size_type i) { return m_v.m_data[m_item.offset + i]; }
0268 DataIter begin() { return m_v.m_data.begin() + m_item.offset; }
0269 DataIter end() { return begin() + size(); }
0270
0271 template <typename... Args>
0272 void emplace_back(Args&&... args) {
0273 checkCapacityExausted();
0274 m_v.m_data.emplace_back(args...);
0275 ++m_v.m_dataSize;
0276 m_item.size++;
0277 }
0278
0279 void push_back(data_type const& d) {
0280 checkCapacityExausted();
0281 m_v.m_data.push_back(d);
0282 ++m_v.m_dataSize;
0283 m_item.size++;
0284 }
0285
0286 void push_back(data_type&& d) {
0287 checkCapacityExausted();
0288 m_v.m_data.push_back(std::move(d));
0289 ++m_v.m_dataSize;
0290 m_item.size++;
0291 }
0292
0293 data_type& back() { return m_v.m_data.back(); }
0294
0295 private:
0296
0297 friend class ::TestDetSet;
0298
0299 DetSetVector<T>& m_v;
0300 typename DetSetVector<T>::Item& m_item;
0301 bool m_saveEmpty;
0302 };
0303
0304
0305
0306 class TSFastFiller {
0307 public:
0308 typedef typename DetSetVector<T>::data_type value_type;
0309 typedef typename DetSetVector<T>::id_type key_type;
0310 typedef typename DetSetVector<T>::id_type id_type;
0311 typedef typename DetSetVector<T>::size_type size_type;
0312
0313
0314 static DetSetVector<T>::Item const& dummy() {
0315 assert(false);
0316 static DetSetVector<T>::Item const d;
0317 return d;
0318 }
0319
0320 TSFastFiller(DetSetVector<T>& iv, id_type id) : m_v(iv), m_item(m_v.ready() ? iv.push_back(id) : dummy()) {
0321 assert(m_v.m_filling == true);
0322 m_v.m_filling = false;
0323 }
0324
0325 TSFastFiller(DetSetVector<T> const& iv, typename DetSetVector<T>::Item const& it) : m_v(iv), m_item(it) {}
0326 ~TSFastFiller() {
0327 bool expected = false;
0328 while (!m_v.m_filling.compare_exchange_weak(expected, true)) {
0329 expected = false;
0330 nanosleep(nullptr, nullptr);
0331 }
0332 int offset = m_v.m_data.size();
0333 if (m_v.onDemand() && full()) {
0334 m_v.m_filling = false;
0335 dstvdetails::throwCapacityExausted();
0336 }
0337 std::move(m_lv.begin(), m_lv.end(), std::back_inserter(m_v.m_data));
0338 m_item.size = m_lv.size();
0339 m_item.offset = offset;
0340
0341 m_v.m_dataSize = m_v.m_data.size();
0342 assert(m_v.m_filling == true);
0343 m_v.m_filling = false;
0344 }
0345
0346 bool full() const {
0347 int offset = m_v.m_dataSize;
0348 return m_v.m_data.capacity() < offset + m_lv.size();
0349 }
0350
0351 void abort() { m_lv.clear(); }
0352
0353 void reserve(size_type s) { m_lv.reserve(s); }
0354
0355 void resize(size_type s) { m_lv.resize(s); }
0356
0357 id_type id() const { return m_item.id; }
0358 size_type size() const { return m_lv.size(); }
0359 bool empty() const { return m_lv.empty(); }
0360
0361 data_type& operator[](size_type i) { return m_lv[i]; }
0362 DataIter begin() { return m_lv.begin(); }
0363 DataIter end() { return m_lv.end(); }
0364
0365 template <typename... Args>
0366 void emplace_back(Args&&... args) {
0367 m_lv.emplace_back(args...);
0368 }
0369
0370 void push_back(data_type const& d) { m_lv.push_back(d); }
0371 void push_back(data_type&& d) { m_lv.push_back(std::move(d)); }
0372
0373 data_type& back() { return m_lv.back(); }
0374
0375 private:
0376
0377 friend class ::TestDetSet;
0378
0379 std::vector<T> m_lv;
0380 DetSetVector<T> const& m_v;
0381 typename DetSetVector<T>::Item const& m_item;
0382 };
0383
0384 friend class FastFiller;
0385 friend class TSFastFiller;
0386 friend class edmNew::DetSet<T>;
0387
0388 class FindForDetSetVector {
0389 public:
0390 using first_argument_type = const edmNew::DetSetVector<T>&;
0391 using second_argument_type = unsigned int;
0392 using result_type = const T*;
0393
0394 result_type operator()(first_argument_type iContainer, second_argument_type iIndex) {
0395 bool expected = false;
0396 while (!iContainer.m_filling.compare_exchange_weak(expected, true, std::memory_order_acq_rel)) {
0397 expected = false;
0398 nanosleep(nullptr, nullptr);
0399 }
0400 result_type item = &(iContainer.m_data[iIndex]);
0401 assert(iContainer.m_filling == true);
0402 iContainer.m_filling = false;
0403 return item;
0404 }
0405 };
0406 friend class FindForDetSetVector;
0407
0408 explicit DetSetVector(int isubdet = 0) : m_subdetId(isubdet) {}
0409
0410 DetSetVector(std::shared_ptr<dslv::LazyGetter<T>> iGetter, const std::vector<det_id_type>& iDets, int isubdet = 0);
0411
0412 ~DetSetVector() {
0413
0414 }
0415
0416
0417 DetSetVector& operator=(const DetSetVector&) = delete;
0418
0419
0420
0421
0422 DetSetVector(const DetSetVector&) = default;
0423 DetSetVector(DetSetVector&&) = default;
0424 DetSetVector& operator=(DetSetVector&&) = default;
0425
0426 bool onDemand() const { return static_cast<bool>(m_getter); }
0427
0428 void swap(DetSetVector& rh) {
0429 DetSetVectorTrans::swap(rh);
0430 std::swap(m_subdetId, rh.m_subdetId);
0431 std::swap(m_ids, rh.m_ids);
0432 std::swap(m_data, rh.m_data);
0433 }
0434
0435 void swap(IdContainer& iic, DataContainer& idc) {
0436 std::swap(m_ids, iic);
0437 std::swap(m_data, idc);
0438 }
0439
0440 void reserve(size_t isize, size_t dsize) {
0441 m_ids.reserve(isize);
0442 m_data.reserve(dsize);
0443 }
0444
0445 void shrink_to_fit() {
0446 clean();
0447 m_ids.shrink_to_fit();
0448 m_data.shrink_to_fit();
0449 }
0450
0451 void resize(size_t isize, size_t dsize) {
0452 m_ids.resize(isize);
0453 m_data.resize(dsize);
0454 m_dataSize = m_data.size();
0455 }
0456
0457 void clean() {
0458 m_ids.erase(std::remove_if(m_ids.begin(), m_ids.end(), [](Item const& m) { return 0 == m.size; }), m_ids.end());
0459 }
0460
0461
0462 DetSet insert(id_type iid, data_type const* idata, size_type isize) {
0463 Item& item = addItem(iid, isize);
0464 m_data.resize(m_data.size() + isize);
0465 std::copy(idata, idata + isize, m_data.begin() + item.offset);
0466 m_dataSize = m_data.size();
0467 return DetSet(*this, item, false);
0468 }
0469
0470 DetSet insert(id_type iid, size_type isize) {
0471 Item& item = addItem(iid, isize);
0472 m_data.resize(m_data.size() + isize);
0473 m_dataSize = m_data.size();
0474 return DetSet(*this, item, false);
0475 }
0476
0477
0478 Item& push_back(id_type iid) { return addItem(iid, 0); }
0479
0480
0481 void pop_back(id_type iid) {
0482 const_IdIter p = findItem(iid);
0483 if (p == m_ids.end())
0484 return;
0485
0486 if ((*p).isValid() && (*p).size > 0 && m_data.size() == (*p).offset + (*p).size) {
0487 m_data.resize((*p).offset);
0488 m_dataSize = m_data.size();
0489 }
0490 m_ids.erase(m_ids.begin() + (p - m_ids.begin()));
0491 }
0492
0493 private:
0494 Item& addItem(id_type iid, size_type isize) {
0495 Item it(iid, size_type(m_data.size()), isize);
0496 IdIter p = std::lower_bound(m_ids.begin(), m_ids.end(), it);
0497 if (p != m_ids.end() && !(it < *p))
0498 dstvdetails::errorIdExists(iid);
0499 return *m_ids.insert(p, std::move(it));
0500 }
0501
0502 public:
0503
0504
0505 bool exists(id_type i) const { return findItem(i) != m_ids.end(); }
0506
0507 bool isValid(id_type i) const {
0508 const_IdIter p = findItem(i);
0509 return p != m_ids.end() && (*p).isValid();
0510 }
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520 DetSet operator[](id_type i) const {
0521 const_IdIter p = findItem(i);
0522 if (p == m_ids.end())
0523 dstvdetails::throw_range(i);
0524 return DetSet(*this, *p, true);
0525 }
0526
0527
0528
0529 const_iterator find(id_type i, bool update = false) const {
0530 const_IdIter p = findItem(i);
0531 return (p == m_ids.end()) ? end() : boost::make_transform_iterator(p, IterHelp(*this, update));
0532 }
0533
0534
0535 const_IdIter findItem(id_type i) const {
0536 std::pair<const_IdIter, const_IdIter> p = std::equal_range(m_ids.begin(), m_ids.end(), Item(i));
0537 return (p.first != p.second) ? p.first : m_ids.end();
0538 }
0539
0540
0541 const_iterator begin(bool update = false) const {
0542 return boost::make_transform_iterator(m_ids.begin(), IterHelp(*this, update));
0543 }
0544
0545
0546 const_iterator end(bool update = false) const {
0547 return boost::make_transform_iterator(m_ids.end(), IterHelp(*this, update));
0548 }
0549
0550
0551 template <typename CMP>
0552
0553 Range equal_range(id_type i, CMP cmp, bool update = false) const {
0554 std::pair<const_IdIter, const_IdIter> p = std::equal_range(m_ids.begin(), m_ids.end(), i, cmp);
0555 return Range(boost::make_transform_iterator(p.first, IterHelp(*this, update)),
0556 boost::make_transform_iterator(p.second, IterHelp(*this, update)));
0557 }
0558
0559 int subdetId() const { return m_subdetId; }
0560
0561 bool empty() const { return m_ids.empty(); }
0562
0563 size_type dataSize() const { return onDemand() ? size_type(m_dataSize) : size_type(m_data.size()); }
0564
0565 size_type size() const { return m_ids.size(); }
0566
0567
0568
0569 data_type operator()(size_t cell, size_t frame) const { return m_data[m_ids[cell].offset + frame]; }
0570
0571 data_type const* data(size_t cell) const { return &m_data[m_ids[cell].offset]; }
0572
0573 size_type detsetSize(size_t cell) const { return m_ids[cell].size; }
0574
0575 id_type id(size_t cell) const { return m_ids[cell].id; }
0576
0577 Item const& item(size_t cell) const { return m_ids[cell]; }
0578
0579
0580
0581 IdContainer const& ids() const { return m_ids; }
0582 DataContainer const& data() const { return m_data; }
0583
0584
0585 CMS_CLASS_VERSION(10)
0586
0587 private:
0588
0589 friend class ::TestDetSet;
0590
0591 void update(Item const& item) const;
0592
0593
0594 int m_subdetId;
0595
0596
0597
0598
0599 std::vector<Trans::Item> m_ids;
0600 CMS_THREAD_GUARD(dstvdetails::DetSetVectorTrans::m_filling) mutable DataContainer m_data;
0601 };
0602
0603 namespace dslv {
0604 template <typename T>
0605 class LazyGetter {
0606 public:
0607 virtual ~LazyGetter() {}
0608 virtual void fill(typename DetSetVector<T>::TSFastFiller&) const = 0;
0609 };
0610 }
0611
0612 template <typename T>
0613 inline DetSetVector<T>::DetSetVector(std::shared_ptr<Getter> iGetter,
0614 const std::vector<det_id_type>& iDets,
0615 int isubdet)
0616 : m_subdetId(isubdet) {
0617 m_getter = iGetter;
0618
0619 m_ids.reserve(iDets.size());
0620 det_id_type sanityCheck = 0;
0621 for (std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
0622 itDetId != itDetIdEnd;
0623 ++itDetId) {
0624 assert(sanityCheck < *itDetId && "vector of det_id_type was not ordered");
0625 sanityCheck = *itDetId;
0626 m_ids.push_back(*itDetId);
0627 }
0628 }
0629
0630 template <typename T>
0631 inline void DetSetVector<T>::update(const Item& item) const {
0632
0633 if (!m_getter) {
0634 assert(item.isValid());
0635 return;
0636 }
0637 if (item.initialize()) {
0638 assert(item.initializing());
0639 {
0640 TSFastFiller ff(*this, item);
0641 static_cast<Getter const*>(m_getter.get())->fill(ff);
0642 }
0643 assert(item.isValid());
0644 }
0645 }
0646
0647 template <typename T>
0648 inline void DetSet<T>::set(DetSetVector<T> const& icont, typename Container::Item const& item, bool update) {
0649
0650 if (update)
0651 icont.update(item);
0652 while (item.initializing())
0653 nanosleep(nullptr, nullptr);
0654 m_data = &icont.data();
0655 m_id = item.id;
0656 m_offset = item.offset;
0657 m_size = item.size;
0658 }
0659 }
0660
0661 #include "DataFormats/Common/interface/Ref.h"
0662 #include <type_traits>
0663
0664
0665 namespace edm {
0666
0667 namespace refhelper {
0668 template <typename T>
0669 struct FindTrait<typename edmNew::DetSetVector<T>, T> {
0670 typedef typename edmNew::DetSetVector<T>::FindForDetSetVector value;
0671 };
0672 }
0673
0674
0675
0676 namespace refhelper {
0677 template <typename T>
0678 struct FindSetForNewDetSetVector {
0679 using first_argument_type = const edmNew::DetSetVector<T>&;
0680 using second_argument_type = unsigned int;
0681 using result_type = edmNew::DetSet<T>;
0682
0683 result_type operator()(first_argument_type iContainer, second_argument_type iIndex) {
0684 return &(iContainer[iIndex]);
0685 }
0686 };
0687
0688 template <typename T>
0689 struct FindTrait<edmNew::DetSetVector<T>, edmNew::DetSet<T>> {
0690 typedef FindSetForNewDetSetVector<T> value;
0691 };
0692 }
0693
0694 }
0695
0696 namespace edmNew {
0697
0698 template <class HandleT>
0699
0700 edm::Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type> makeRefTo(
0701 const HandleT& iHandle, typename HandleT::element_type::value_type::const_iterator itIter) {
0702 static_assert(std::is_same<typename HandleT::element_type,
0703 DetSetVector<typename HandleT::element_type::value_type::value_type>>::value,
0704 "Handle and DetSetVector do not have compatible types.");
0705 auto index = itIter - &iHandle->data().front();
0706 return edm::Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>(
0707 iHandle.id(), &(*itIter), index);
0708 }
0709 }
0710
0711 #include "DataFormats/Common/interface/ContainerMaskTraits.h"
0712
0713 namespace edm {
0714 template <typename T>
0715 class ContainerMaskTraits<edmNew::DetSetVector<T>> {
0716 public:
0717 typedef T value_type;
0718
0719 static size_t size(const edmNew::DetSetVector<T>* iContainer) { return iContainer->dataSize(); }
0720 static unsigned int indexFor(const value_type* iElement, const edmNew::DetSetVector<T>* iContainer) {
0721 return iElement - &(iContainer->data().front());
0722 }
0723 };
0724 }
0725
0726
0727 #include "DataFormats/Common/interface/fillCollectionForThinning.h"
0728 namespace edm::detail {
0729 template <typename T>
0730 struct ElementType<edmNew::DetSetVector<T>> {
0731 using type = typename edmNew::DetSetVector<T>::data_type;
0732 };
0733 }
0734 namespace edmNew {
0735 template <typename T, typename Selector>
0736 void fillCollectionForThinning(edmNew::DetSet<T> const& detset,
0737 Selector& selector,
0738 unsigned int& iIndex,
0739 edmNew::DetSetVector<T>& output,
0740 edm::ThinnedAssociation& association) {
0741 typename edmNew::DetSetVector<T>::FastFiller ff(output, detset.detId());
0742 for (auto iter = detset.begin(), end = detset.end(); iter != end; ++iter, ++iIndex) {
0743 edm::detail::fillCollectionForThinning(*iter, selector, iIndex, ff, association);
0744 }
0745 if (detset.begin() != detset.end()) {
0746
0747 --iIndex;
0748 }
0749 }
0750 }
0751
0752 #endif