CMS 3D CMS Logo

ESProductHost.h
Go to the documentation of this file.
1 #ifndef FWCore_Framework_ESProductHost_h
2 #define FWCore_Framework_ESProductHost_h
3 // -*- C++ -*-
4 //
5 // Package: Framework
6 // Class: ESProductHost
7 //
70 //
71 // Author: W. David Dagenhart
72 // Created: 28 August 2018
73 //
74 
75 #include <cstddef>
76 #include <type_traits>
77 #include <vector>
78 
79 namespace edm {
80 
81  // The parameter pack RecordTypes should contain all the
82  // record types which you want to use when calling the
83  // function "ifRecordChanges" as the first template parameter
84  // to that function (the RecordType). The list of types in
85  // RecordTypes is used only to size the vector of cacheIDs_ and
86  // to establish an order of the types in RecordTypes. The
87  // order is only used to establish a one to one correspondence
88  // between cacheIDs_ and the types. The particular order
89  // selected does not mattter, just that some order exists
90  // so we know which cacheID corresponds to which type.
91 
92  template <typename Product, typename... RecordTypes>
93  class ESProductHost final : public Product {
94  public:
95  template <typename... Args>
96  ESProductHost(Args&&... args) : Product(std::forward<Args>(args)...), cacheIDs_(numberOfRecordTypes(), 0) {}
97 
98  // Execute FUNC if the cacheIdentifier in the EventSetup RecordType
99  // has changed since the last time we called FUNC for
100  // this EventSetup product.
101 
102  template <typename RecordType, typename ContainingRecordType, typename FUNC>
103  void ifRecordChanges(ContainingRecordType const& containingRecord, FUNC func) {
104  RecordType const& record = containingRecord.template getRecord<RecordType>();
105  unsigned long long cacheIdentifier = record.cacheIdentifier();
106  std::size_t iRecord = index<RecordType>();
107  if (cacheIdentifier != cacheIDs_[iRecord]) {
108  cacheIDs_[iRecord] = cacheIdentifier;
109  func(record);
110  }
111  }
112 
113  // The rest of the functions are not intended for public use.
114  // The only reason they are not private is that test code
115  // uses them.
116 
117  // Return the number of record types for which we want to check
118  // if the cache identifier changed.
119 
120  constexpr static std::size_t numberOfRecordTypes() { return sizeof...(RecordTypes); }
121 
122  // Return the index of a record type in the types in the parameter pack RecordTypes.
123  // The first type in the template parameters after the Product type
124  // will have an index of 0, the next 1, and so on.
125  // (There must be at least one type after Product if you want to call the
126  // "ifRecordChanges" function).
127 
128  template <typename U>
129  constexpr static std::size_t index() {
130  static_assert(numberOfRecordTypes() > 0, "no record types in ESProductHost");
131  return indexLoop<0, U, RecordTypes...>();
132  }
133 
134  template <std::size_t I, typename U, typename TST, typename... M>
135  constexpr static std::size_t indexLoop() {
136  if constexpr (std::is_same_v<U, TST>) {
137  return I;
138  } else {
139  static_assert(I + 1 < numberOfRecordTypes(), "unknown record type passed to ESProductHost::index");
140  return indexLoop<I + 1, U, M...>();
141  }
142  }
143 
144  private:
145  // Data member, this holds the cache identifiers from the record which
146  // are used to determine whether the EventSetup cache for that record has
147  // been updated since this Product was lasted updated.
148 
149  std::vector<unsigned long long> cacheIDs_;
150  };
151 } // namespace edm
152 #endif
static constexpr std::size_t index()
ESProductHost(Args &&... args)
Definition: ESProductHost.h:96
void ifRecordChanges(ContainingRecordType const &containingRecord, FUNC func)
static constexpr std::size_t indexLoop()
const std::complex< double > I
Definition: I.h:8
std::vector< unsigned long long > cacheIDs_
static constexpr std::size_t numberOfRecordTypes()
HLT enums.