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