/
ESConsumesCollector.h
211 lines (178 loc) · 8.6 KB
/
ESConsumesCollector.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#ifndef FWCore_Framework_ESConsumesCollector_h
#define FWCore_Framework_ESConsumesCollector_h
// -*- C++ -*-
//
// Package: FWCore/Framework
// Class : edm::ConsumesCollector
//
/**\class edm::ESConsumesCollector ESConsumesCollector.h "FWCore/Framework/interface/ESConsumesCollector.h"
Description: Helper class to gather consumes information for the EventSetup.
Usage: The constructor of an ESProducer module can get an instance of
edm::ESConsumesCollector by calling consumesCollector()
method. This instance can then be passed to helper classes in
order to register the event-setup data the helper will request
from an Event, LuminosityBlock or Run on behalf of the module.
Caveat: The ESConsumesCollector should be used during the time that
modules are being constructed. It should not be saved and
used later. It will not work if it is used to call the
consumes function during beginJob, beginRun, beginLuminosity
block, event processing or at any later time. As of now, an
ESConsumesCollector is provided for only ESProducer
subclasses--i.e. those that call setWhatProduced(this, ...).
*/
//
// Original Author: Kyle Knoepfel
// Created: Fri, 02 Oct 2018 12:44:47 GMT
//
#include "FWCore/Framework/interface/EventSetupRecordKey.h"
#include "FWCore/Framework/interface/DataKey.h"
#include "FWCore/Framework/interface/es_impl/MayConsumeChooser.h"
#include "FWCore/Utilities/interface/ESGetToken.h"
#include "FWCore/Utilities/interface/ESInputTag.h"
#include "FWCore/Utilities/interface/propagate_const.h"
#include "FWCore/Utilities/interface/Transition.h"
#include <vector>
#include <memory>
class testEventsetupRecord;
namespace edm {
class ESConsumesCollectorAdaptor;
class ESConsumesCollectorWithTagAdaptor;
struct ESConsumesInfoEntry {
ESConsumesInfoEntry(edm::eventsetup::EventSetupRecordKey const& iRecord,
edm::eventsetup::DataKey const& iProduct,
std::string moduleLabel,
std::unique_ptr<edm::eventsetup::impl::MayConsumeChooserCore> chooser)
: recordKey_{iRecord},
productKey_{iProduct},
moduleLabel_{std::move(moduleLabel)},
chooser_{std::move(chooser)} {}
edm::eventsetup::EventSetupRecordKey recordKey_;
edm::eventsetup::DataKey productKey_;
std::string moduleLabel_;
std::unique_ptr<edm::eventsetup::impl::MayConsumeChooserCore> chooser_;
};
using ESConsumesInfo = std::vector<ESConsumesInfoEntry>;
class ESConsumesCollector {
public:
ESConsumesCollector() = delete;
ESConsumesCollector(ESConsumesCollector const&) = delete;
ESConsumesCollector(ESConsumesCollector&&) = default;
ESConsumesCollector& operator=(ESConsumesCollector const&) = delete;
ESConsumesCollector& operator=(ESConsumesCollector&&) = default;
// ---------- member functions ---------------------------
template <typename Product, typename Record>
auto consumesFrom(ESInputTag const& tag) {
using namespace edm::eventsetup;
ESTokenIndex index{static_cast<ESTokenIndex::Value_t>(m_consumer->size())};
m_consumer->emplace_back(EventSetupRecordKey::makeKey<Record>(),
DataKey(DataKey::makeTypeTag<Product>(), tag.data().c_str()),
tag.module(),
nullptr);
//even though m_consumer may expand, the address for
// name().value() remains the same since it is 'moved'.
return ESGetToken<Product, Record>{m_transitionID, index, m_consumer->back().productKey_.name().value()};
}
template <typename Product, typename Record>
auto consumesFrom() {
using namespace edm::eventsetup;
ESTokenIndex index{static_cast<ESTokenIndex::Value_t>(m_consumer->size())};
m_consumer->emplace_back(
EventSetupRecordKey::makeKey<Record>(), DataKey(DataKey::makeTypeTag<Product>(), ""), "", nullptr);
//even though m_consumer may expand, the address for
// name().value() remains the same since it is 'moved'.
return ESGetToken<Product, Record>{m_transitionID, index, m_consumer->back().productKey_.name().value()};
}
ESConsumesCollectorAdaptor consumes();
ESConsumesCollectorWithTagAdaptor consumes(ESInputTag tag);
protected:
explicit ESConsumesCollector(ESConsumesInfo* const iConsumer, unsigned int iTransitionID)
: m_consumer{iConsumer}, m_transitionID{iTransitionID} {}
template <typename Product, typename Record, typename Collector, typename PTag>
auto registerMayConsume(std::unique_ptr<Collector> iCollector, PTag const& productTag) {
//NOTE: for now, just treat like standard consumes request for the product needed to
// do the decision
iCollector->token() = consumes(productTag.inputTag());
using namespace edm::eventsetup;
ESTokenIndex index{static_cast<ESTokenIndex::Value_t>(m_consumer->size())};
m_consumer->emplace_back(EventSetupRecordKey::makeKey<Record>(),
DataKey(DataKey::makeTypeTag<Product>(), "@mayConsume"),
"@mayConsume",
std::move(iCollector));
//even though m_consumer may expand, the address for
// name().value() remains the same since it is 'moved'.
return ESGetToken<Product, Record>{m_transitionID, index, m_consumer->back().productKey_.name().value()};
}
private:
// ---------- member data --------------------------------
edm::propagate_const<ESConsumesInfo*> m_consumer{nullptr};
unsigned int m_transitionID{0};
};
template <typename RECORD>
class ESConsumesCollectorT : public ESConsumesCollector {
public:
ESConsumesCollectorT() = delete;
ESConsumesCollectorT(ESConsumesCollectorT<RECORD> const&) = default;
ESConsumesCollectorT(ESConsumesCollectorT<RECORD>&&) = default;
ESConsumesCollectorT<RECORD>& operator=(ESConsumesCollectorT<RECORD> const&) = default;
ESConsumesCollectorT<RECORD>& operator=(ESConsumesCollectorT<RECORD>&&) = default;
// ---------- member functions ---------------------------
using ESConsumesCollector::consumes;
template <typename Product>
auto consumes(ESInputTag const& tag) {
return consumesFrom<Product, RECORD>(tag);
}
template <typename Product>
auto consumes() {
return consumesFrom<Product, RECORD>();
}
template <typename Product, typename FromRecord, typename Func, typename PTag>
auto mayConsumeFrom(Func&& func, PTag const& productTag) {
return registerMayConsume<Product, FromRecord>(
std::make_unique<eventsetup::impl::MayConsumeChooser<RECORD, Product, FromRecord, Func, PTag>>(
std::forward<Func>(func)),
productTag);
}
template <typename Product, typename FromRecord, typename Func, typename PTag>
ESConsumesCollector& setMayConsume(ESGetToken<Product, FromRecord>& token, Func&& func, PTag const& productTag) {
token = mayConsumeFrom<Product, FromRecord>(std::forward<Func>(func), productTag);
return *this;
}
private:
//only ESProducer is allowed to make an instance of this class
friend class ESProducer;
friend class ::testEventsetupRecord;
explicit ESConsumesCollectorT(ESConsumesInfo* const iConsumer, unsigned int iTransitionID)
: ESConsumesCollector(iConsumer, iTransitionID) {}
};
class ESConsumesCollectorAdaptor {
public:
template <typename TYPE, typename REC>
ESGetToken<TYPE, REC> consumes() {
return m_consumer->template consumesFrom<TYPE, REC>();
}
private:
//only ESConsumesCollector is allowed to make an instance of this class
friend class ESConsumesCollector;
explicit ESConsumesCollectorAdaptor(ESConsumesCollector* iBase) : m_consumer(iBase) {}
ESConsumesCollector* m_consumer;
};
class ESConsumesCollectorWithTagAdaptor {
public:
template <typename TYPE, typename REC>
ESGetToken<TYPE, REC> consumes() {
return m_consumer->template consumesFrom<TYPE, REC>(m_tag);
}
private:
//only ESConsumesCollector is allowed to make an instance of this class
friend class ESConsumesCollector;
ESConsumesCollectorWithTagAdaptor(ESConsumesCollector* iBase, ESInputTag iTag)
: m_consumer(iBase), m_tag(std::move(iTag)) {}
ESConsumesCollector* m_consumer;
ESInputTag const m_tag;
};
inline ESConsumesCollectorAdaptor ESConsumesCollector::consumes() { return ESConsumesCollectorAdaptor(this); }
inline ESConsumesCollectorWithTagAdaptor ESConsumesCollector::consumes(ESInputTag tag) {
return ESConsumesCollectorWithTagAdaptor(this, std::move(tag));
}
} // namespace edm
#endif