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