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