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