CMS 3D CMS Logo

Table.h
Go to the documentation of this file.
1 #ifndef FWCore_SOA_Table_h
2 #define FWCore_SOA_Table_h
3 // -*- C++ -*-
4 //
5 // Package: FWCore/SOA
6 // Class : Table
7 //
111 //
112 // Original Author: Chris Jones
113 // Created: Thu, 24 Aug 2017 16:18:05 GMT
114 //
115 
116 // system include files
117 #include <tuple>
118 #include <array>
119 
120 // user include files
126 
127 //The following is needed for edm::Wrapper
129 
130 // forward declarations
131 
132 namespace edm {
133 namespace soa {
134 
135  template <typename... Args>
136  class Table {
137  public:
138  static constexpr const unsigned int kNColumns = sizeof...(Args);
139  using Layout = std::tuple<Args...>;
140  using const_iterator = ConstTableItr<Args...>;
141  using iterator = TableItr<Args...>;
142 
143  template <typename T, typename... CArgs>
144  Table(T const& iContainer, CArgs... iArgs): m_size(iContainer.size()) {
145  using CtrChoice = std::conditional_t<sizeof...(CArgs)==0,
148  m_size = CtrChoice::fill(m_values,iContainer,std::forward<CArgs>(iArgs)...);
149  }
150 
151  template<typename T, typename... CArgs>
152  Table(T const& iContainer, ColumnFillers<CArgs...> iFiller) {
153  m_size = iContainer.size();
154  CtrFillerFromAOS::fillUsingFiller(iFiller,m_values, iContainer);
155  }
156 
157  Table( Table<Args...> const& iOther):m_size(iOther.m_size), m_values{{nullptr}} {
158  copyFromToWithResize<0>(m_size,iOther.m_values,m_values,std::true_type{});
159  }
160 
161  Table( Table<Args...>&& iOther):m_size(0), m_values{{nullptr}} {
162  std::swap(m_size,iOther.m_size);
163  std::swap(m_values,iOther.m_values);
164  }
165 
166  Table() : m_size(0) {
167  }
168 
169  ~Table() {
170  dtr<0>(m_values, std::true_type{});
171  }
172 
173  Table<Args...>& operator=(Table<Args...>&& iOther) {
174  Table<Args...> cp(std::move(iOther));
175  std::swap(m_size,cp.m_size);
176  std::swap(m_values, cp.m_values);
177  return *this;
178  }
179  Table<Args...>& operator=(Table<Args...> const& iOther) {
180  return operator=( Table<Args...>(iOther));
181  }
182 
183  unsigned int size() const {
184  return m_size;
185  }
186 
187  void resize(unsigned int iNewSize) {
188  if(m_size == iNewSize) { return;}
189  resizeFromTo<0>(m_size,iNewSize,m_values,std::true_type{});
190  if(m_size < iNewSize) {
191  //initialize the extra values
192  resetStartingAt<0>(m_size, iNewSize,m_values,std::true_type{});
193  }
194  m_size = iNewSize;
195  }
196 
197  template<typename U>
198  typename U::type const& get(size_t iRow) const {
199  return *(static_cast<typename U::type const*>(columnAddress<U>())+iRow);
200  }
201  template<typename U>
202  typename U::type & get(size_t iRow) {
203  return *(static_cast<typename U::type*>(columnAddress<U>())+iRow);
204  }
205 
206  template<typename U>
208  return ColumnValues<typename U::type>{static_cast<typename U::type*>(columnAddress<U>()), m_size};
209  }
210  template<typename U>
212  return MutableColumnValues<typename U::type>{static_cast<typename U::type*>(columnAddress<U>()), m_size};
213  }
214 
215  RowView<Args...> row(size_t iRow) const {
216  return *(begin()+iRow);
217  }
218  MutableRowView<Args...> row(size_t iRow) {
219  return *(begin()+iRow);
220  }
221 
223  std::array<void const*, sizeof...(Args)> t;
224  for(size_t i = 0; i<size();++i) { t[i] = m_values[i]; }
225  return const_iterator{t}; }
226  const_iterator end() const {
227  std::array<void const*, sizeof...(Args)> t;
228  for(size_t i = 0; i<size();++i) { t[i] = m_values[i]; }
229  return const_iterator{t,size()}; }
230 
232  iterator end() { return iterator{m_values,size()}; }
233 
234 
235  template<typename U>
236  void const * columnAddressWorkaround( U const*) const {
237  return columnAddress<U>();
238  }
239 
240  void const * columnAddressByIndex(unsigned int iIndex) const {
241  return m_values[iIndex];
242  }
243 
244  private:
245 
246  // Member data
247  unsigned int m_size = 0;
248  std::array<void *, sizeof...(Args)> m_values = {{nullptr}};
249 
250  template<typename U>
251  void const* columnAddress() const {
253  }
254 
255  template<typename U>
256  void * columnAddress() {
258  }
259 
260  //Recursive destructor handling
261  template <int I>
262  static void dtr(std::array<void*, sizeof...(Args)>& iArray, std::true_type) {
264  delete [] static_cast<Type*>(iArray[I]);
265  dtr<I+1>(iArray,std::conditional_t<I+1<sizeof...(Args), std::true_type, std::false_type>{});
266  }
267 
268  template <int I>
269  static void dtr(std::array<void*, sizeof...(Args)>& iArray, std::false_type) {
270  }
271 
272  //Construct the Table using a container per column
274  template<typename T, typename... U>
275  static size_t fill(std::array<void *, sizeof...(Args)>& oValues, T const& iContainer, U... iArgs) {
276  static_assert( sizeof...(Args) == sizeof...(U)+1, "Wrong number of arguments passed to Table constructor");
277  ctrFiller<0>(oValues,iContainer.size(), iContainer,std::forward<U>(iArgs)...);
278  return iContainer.size();
279  }
280  private:
281  template<int I, typename T, typename... U>
282  static void ctrFiller(std::array<void *, sizeof...(Args)>& oValues, size_t iSize, T const& iContainer, U... iU) {
283  assert(iContainer.size() == iSize);
285  Type * temp = new Type [iSize];
286  unsigned int index = 0;
287  for( auto const& v: iContainer) {
288  temp[index] = v;
289  ++index;
290  }
291  oValues[I] = temp;
292 
293  ctrFiller<I+1>(oValues, iSize, std::forward<U>(iU)... );
294  }
295 
296  template<int I>
297  static void ctrFiller(std::array<void *, sizeof...(Args)>& , size_t ) {}
298 
299  };
300 
301  //Construct the Table using one container with each entry representing a row
303  template<typename T>
304  static size_t fill(std::array<void *, sizeof...(Args)>& oValues, T const& iContainer) {
305  presize<0>(oValues,iContainer.size(),std::true_type{});
306  unsigned index=0;
307  for(auto&& item: iContainer) {
308  fillElement<0>(item,index,oValues,std::true_type{});
309  ++index;
310  }
311  return iContainer.size();
312  }
313 
314  template<typename T, typename F>
315  static size_t fillUsingFiller(F& iFiller, std::array<void *, sizeof...(Args)>& oValues, T const& iContainer) {
316  presize<0>(oValues,iContainer.size(),std::true_type{});
317  unsigned index=0;
318  for(auto&& item: iContainer) {
319  fillElementUsingFiller<0>(iFiller, item,index,oValues,std::true_type{});
320  ++index;
321  }
322  return iContainer.size();
323  }
324 
325 
326  private:
327  template<int I>
328  static void presize(std::array<void *, sizeof...(Args)>& oValues, size_t iSize, std::true_type) {
329  using Layout = std::tuple<Args...>;
331  oValues[I] = new Type[iSize];
332  presize<I+1>(oValues,iSize, std::conditional_t<I+1==sizeof...(Args),
333  std::false_type,
334  std::true_type>{});
335  }
336  template<int I>
337  static void presize(std::array<void *, sizeof...(Args)>& oValues, size_t iSize, std::false_type) {}
338 
339  template<int I, typename E>
340  static void fillElement(E const& iItem, size_t iIndex, std::array<void *, sizeof...(Args)>& oValues, std::true_type) {
341  using Layout = std::tuple<Args...>;
342  using ColumnType = typename std::tuple_element<I,Layout>::type;
343  using Type = typename ColumnType::type;
344  Type* pElement = static_cast<Type*>(oValues[I])+iIndex;
345  *pElement = value_for_column(iItem, static_cast<ColumnType*>(nullptr));
346  fillElement<I+1>(iItem, iIndex, oValues, std::conditional_t<I+1==sizeof...(Args),
347  std::false_type,
348  std::true_type>{});
349  }
350  template<int I, typename E>
351  static void fillElement(E const& iItem, size_t iIndex, std::array<void *, sizeof...(Args)>& oValues, std::false_type) {}
352 
353 
354  template<int I, typename E, typename F>
355  static void fillElementUsingFiller(F& iFiller, E const& iItem, size_t iIndex, std::array<void *, sizeof...(Args)>& oValues, std::true_type) {
356  using Layout = std::tuple<Args...>;
357  using ColumnType = typename std::tuple_element<I,Layout>::type;
358  using Type = typename ColumnType::type;
359  Type* pElement = static_cast<Type*>(oValues[I])+iIndex;
360  *pElement = iFiller.value(iItem, static_cast<ColumnType*>(nullptr));
361  fillElementUsingFiller<I+1>(iFiller,iItem, iIndex, oValues, std::conditional_t<I+1==sizeof...(Args),
362  std::false_type,
363  std::true_type>{});
364  }
365  template<int I, typename E, typename F>
366  static void fillElementUsingFiller(F&, E const& , size_t , std::array<void *, sizeof...(Args)>& oValues, std::false_type) {}
367 
368  };
369 
370 
371  template<int I>
372  static void copyFromToWithResize(size_t iNElements, std::array<void *, sizeof...(Args)> const& iFrom, std::array<void*, sizeof...(Args)>& oTo, std::true_type) {
373  using Layout = std::tuple<Args...>;
375  Type* oldPtr = static_cast<Type*>(oTo[I]);
376  Type* ptr = new Type[iNElements];
377  oTo[I]=ptr;
378  std::copy(static_cast<Type const*>(iFrom[I]), static_cast<Type const*>(iFrom[I])+iNElements, ptr);
379  delete [] oldPtr;
380  copyFromToWithResize<I+1>(iNElements, iFrom, oTo, std::conditional_t<I+1 == sizeof...(Args), std::false_type, std::true_type>{} );
381  }
382  template<int I>
383  static void copyFromToWithResize(size_t, std::array<void *, sizeof...(Args)> const& , std::array<void*, sizeof...(Args)>&, std::false_type) {}
384 
385  template<int I>
386  static void resizeFromTo(size_t iOldSize, size_t iNewSize, std::array<void *, sizeof...(Args)>& ioArray, std::true_type) {
387  using Layout = std::tuple<Args...>;
389  Type* oldPtr = static_cast<Type*>(ioArray[I]);
390  auto ptr = new Type[iNewSize];
391  auto nToCopy = std::min(iOldSize,iNewSize);
392  std::copy(static_cast<Type const*>(ioArray[I]), static_cast<Type const*>(ioArray[I])+nToCopy, ptr);
393  resizeFromTo<I+1>(iOldSize, iNewSize, ioArray, std::conditional_t<I+1 == sizeof...(Args), std::false_type, std::true_type>{} );
394 
395  delete [] oldPtr;
396  ioArray[I]=ptr;
397  }
398  template<int I>
399  static void resizeFromTo(size_t, size_t, std::array<void *, sizeof...(Args)>& , std::false_type) {}
400 
401  template<int I>
402  static void resetStartingAt(size_t iStartIndex, size_t iEndIndex,std::array<void *, sizeof...(Args)>& ioArray,std::true_type) {
403  using Layout = std::tuple<Args...>;
405  auto ptr = static_cast<Type*>(ioArray[I]);
406  auto temp = Type{};
407  std::fill(ptr+iStartIndex, ptr+iEndIndex, temp);
408  resetStartingAt<I+1>(iStartIndex, iEndIndex, ioArray,std::conditional_t<I+1 == sizeof...(Args), std::false_type, std::true_type>{} );
409  }
410 
411  template<int I>
412  static void resetStartingAt(size_t, size_t,std::array<void *, sizeof...(Args)>& ,std::false_type) {
413  }
414 
415  };
416 
417 
418  /* Table Type Manipulation */
419  template <typename T1, typename T2> struct AddColumns;
420  template <typename... T1, typename... T2>
421  struct AddColumns<Table<T1...>, std::tuple<T2...>> {
422  using type = Table<T1...,T2...>;
423  };
424 
425  template <typename T1, typename T2>
427 
428  namespace impl {
429  template <typename LHS, typename E, typename RHS> struct RemoveColumnCheck;
430  template <typename LHS, typename E, typename T, typename... U>
431  struct RemoveColumnCheck<LHS, E, std::tuple<T,U...>> {
433  typename AddColumns<LHS,std::tuple<U...>>::type,
435  };
436 
437  template <typename LHS, typename E>
438  struct RemoveColumnCheck<LHS, E, std::tuple<>> {
439  using type = LHS;
440  };
441  }
442 
443  template <typename TABLE, typename E>
444  struct RemoveColumn {
445  using type = typename impl::RemoveColumnCheck<Table<>,E, typename TABLE::Layout>::type;
446  };
447 
448  template <typename TABLE, typename E>
450 
451  //This is used by edm::Wrapper
452  template< typename T> struct MakeTableExaminer;
453 
454  template<typename... Args>
455  struct MakeTableExaminer<Table<Args...>> {
456  static std::unique_ptr<TableExaminerBase> make(const Table<Args...>* iTable) {
457  return std::make_unique<TableExaminer<Table<Args...>> >(iTable);
458  }
459  };
460 }
461 }
462 #endif
type
Definition: HCALResponse.h:21
static void fillElementUsingFiller(F &, E const &, size_t, std::array< void *, sizeof...(Args)> &oValues, std::false_type)
Definition: Table.h:366
static void fillElementUsingFiller(F &iFiller, E const &iItem, size_t iIndex, std::array< void *, sizeof...(Args)> &oValues, std::true_type)
Definition: Table.h:355
static void presize(std::array< void *, sizeof...(Args)> &oValues, size_t iSize, std::true_type)
Definition: Table.h:328
RowView< Args... > row(size_t iRow) const
Definition: Table.h:215
iterator begin()
Definition: Table.h:231
Table(Table< Args... > const &iOther)
Definition: Table.h:157
static void dtr(std::array< void *, sizeof...(Args)> &iArray, std::false_type)
Definition: Table.h:269
void const * columnAddress() const
keep ROOT from trying to store this
Definition: Table.h:251
typename std::conditional< std::is_same< E, T >::value, typename AddColumns< LHS, std::tuple< U... >>::type, typename RemoveColumnCheck< typename AddColumns< LHS, std::tuple< T >>::type, E, std::tuple< U... >>::type >::type type
Definition: Table.h:434
static void presize(std::array< void *, sizeof...(Args)> &oValues, size_t iSize, std::false_type)
Definition: Table.h:337
void * columnAddress()
Definition: Table.h:256
#define constexpr
Table< Args... > & operator=(Table< Args... > &&iOther)
Definition: Table.h:173
MutableColumnValues< typename U::type > column()
Definition: Table.h:211
Table(T const &iContainer, CArgs...iArgs)
Definition: Table.h:144
Table(T const &iContainer, ColumnFillers< CArgs... > iFiller)
Definition: Table.h:152
void resize(unsigned int iNewSize)
Definition: Table.h:187
std::tuple< Args... > Layout
Definition: Table.h:139
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
static void copyFromToWithResize(size_t, std::array< void *, sizeof...(Args)> const &, std::array< void *, sizeof...(Args)> &, std::false_type)
Definition: Table.h:383
static void resizeFromTo(size_t iOldSize, size_t iNewSize, std::array< void *, sizeof...(Args)> &ioArray, std::true_type)
Definition: Table.h:386
const std::complex< double > I
Definition: I.h:8
iterator end()
Definition: Table.h:232
static size_t fill(std::array< void *, sizeof...(Args)> &oValues, T const &iContainer, U...iArgs)
Definition: Table.h:275
T min(T a, T b)
Definition: MathUtil.h:58
void const * columnAddressWorkaround(U const *) const
Definition: Table.h:236
ColumnValues< typename U::type > column() const
Definition: Table.h:207
static size_t fill(std::array< void *, sizeof...(Args)> &oValues, T const &iContainer)
Definition: Table.h:304
unsigned int m_size
Definition: Table.h:247
std::array< void *, sizeof...(Args)> m_values
Definition: Table.h:248
static void resizeFromTo(size_t, size_t, std::array< void *, sizeof...(Args)> &, std::false_type)
Definition: Table.h:399
const_iterator end() const
Definition: Table.h:226
Table< Args... > & operator=(Table< Args... > const &iOther)
Definition: Table.h:179
typename impl::RemoveColumnCheck< Table<>, E, typename TABLE::Layout >::type type
Definition: Table.h:445
static void fillElement(E const &iItem, size_t iIndex, std::array< void *, sizeof...(Args)> &oValues, std::false_type)
Definition: Table.h:351
Table(Table< Args... > &&iOther)
Definition: Table.h:161
static void ctrFiller(std::array< void *, sizeof...(Args)> &, size_t)
Definition: Table.h:297
static size_t fillUsingFiller(F &iFiller, std::array< void *, sizeof...(Args)> &oValues, T const &iContainer)
Definition: Table.h:315
MutableRowView< Args... > row(size_t iRow)
Definition: Table.h:218
static void fillElement(E const &iItem, size_t iIndex, std::array< void *, sizeof...(Args)> &oValues, std::true_type)
Definition: Table.h:340
typename RemoveColumn< TABLE, E >::type RemoveColumn_t
Definition: Table.h:449
HLT enums.
void const * columnAddressByIndex(unsigned int iIndex) const
Definition: Table.h:240
static void copyFromToWithResize(size_t iNElements, std::array< void *, sizeof...(Args)> const &iFrom, std::array< void *, sizeof...(Args)> &oTo, std::true_type)
Definition: Table.h:372
static void ctrFiller(std::array< void *, sizeof...(Args)> &oValues, size_t iSize, T const &iContainer, U...iU)
Definition: Table.h:282
static std::unique_ptr< TableExaminerBase > make(const Table< Args... > *iTable)
Definition: Table.h:456
typename AddColumns< T1, T2 >::type AddColumns_t
Definition: Table.h:426
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
long double T
const_iterator begin() const
Definition: Table.h:222
static constexpr const unsigned int kNColumns
Definition: Table.h:138
unsigned int size() const
Definition: Table.h:183
def move(src, dest)
Definition: eostools.py:510
static void dtr(std::array< void *, sizeof...(Args)> &iArray, std::true_type)
Definition: Table.h:262
static void resetStartingAt(size_t iStartIndex, size_t iEndIndex, std::array< void *, sizeof...(Args)> &ioArray, std::true_type)
Definition: Table.h:402
static void resetStartingAt(size_t, size_t, std::array< void *, sizeof...(Args)> &, std::false_type)
Definition: Table.h:412