CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SoATuple.h
Go to the documentation of this file.
1 #ifndef FWCore_Utilities_SoATuple_h
2 #define FWCore_Utilities_SoATuple_h
3 // -*- C++ -*-
4 //
5 // Package: FWCore/Utilities
6 // Class : SoATuple
7 //
81 //
82 // Original Author: Chris Jones
83 // Created: Tue, 16 Apr 2013 20:34:31 GMT
84 // $Id: SoATuple.h,v 1.4 2013/04/23 20:07:48 chrjones Exp $
85 //
86 
87 // system include files
88 #include <algorithm>
89 #include <tuple>
90 #include <cassert>
91 
92 // user include files
95 
96 
97 // forward declarations
98 
99 namespace edm {
100 
101  //The class Aligned is used to specify a non-default alignment for a class
103 
104  //Proper alignment for doing vectorized operations on CPU
105  template<typename T> using AlignedVec = Aligned<T,16>;
106 
107  template <typename... Args>
108  class SoATuple
109  {
110 
111  public:
112  typedef typename std::tuple<Args...> element;
113 
115  for(auto& v : m_values) {
116  v = nullptr;
117  }
118  }
120  for(auto& v : m_values) {
121  v = nullptr;
122  }
123  reserve(iOther.m_size);
124  soahelper::SoATupleHelper<sizeof...(Args),Args...>::copyToNew(static_cast<char*>(m_values[0]),iOther.m_size,m_reserved,iOther.m_values,m_values);
125  m_size = iOther.m_size;
126  }
127 
129  for(auto& v : m_values) {
130  v = nullptr;
131  }
132  this->swap(iOther);
133  }
134 
135  const SoATuple<Args...>& operator=(const SoATuple<Args...>& iRHS) {
136  SoATuple<Args...> temp(iRHS);
137  this->swap(temp);
138  return *this;
139  }
140 
142  soahelper::SoATupleHelper<sizeof...(Args),Args...>::destroy(m_values,m_size);
143  typedef std::aligned_storage<soahelper::SoATupleHelper<sizeof...(Args),Args...>::max_alignment,
144  soahelper::SoATupleHelper<sizeof...(Args),Args...>::max_alignment> AlignedType;
145 
146  delete [] static_cast<AlignedType*>(m_values[0]);
147  }
148 
149  // ---------- const member functions ---------------------
150  size_t size() const { return m_size;}
151  size_t capacity() const {return m_reserved;}
152 
154  template<unsigned int I>
155  typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type const& get(unsigned int iIndex) const {
156  typedef typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type ReturnType;
157  return *(static_cast<ReturnType const*>(m_values[I])+iIndex);
158  }
159 
161  template<unsigned int I>
162  typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type const* begin() const {
163  typedef soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type> Helper;
164  typedef typename Helper::Type ReturnType;
165 #if GCC_PREREQUISITE(4,7,0)
166  return static_cast<ReturnType const*>(__builtin_assume_aligned(m_values[I],Helper::kAlignment));
167 #else
168  return static_cast<ReturnType const*>(m_values[I]);
169 #endif
170  }
172  template<unsigned int I>
173  typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type const* end() const {
174  typedef typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type ReturnType;
175  return static_cast<ReturnType const*>(m_values[I])+m_size;
176  }
177 
178  // ---------- member functions ---------------------------
180  void reserve(unsigned int iToSize) {
181  if(iToSize > m_reserved) {
182  changeSize(iToSize);
183  }
184  }
185 
187  void shrink_to_fit() {
188  if(m_reserved > m_size) {
190  }
191  }
192 
194  void push_back(element const& values) {
195  if(size()+1>capacity()) {
196  reserve(size()*2+1);
197  }
198  soahelper::SoATupleHelper<sizeof...(Args),Args...>::push_back(m_values,m_size,values);
199  ++m_size;
200  }
201 
203  template< typename... FArgs>
204  void emplace_back(FArgs&&... values) {
205  if(size()+1>capacity()) {
206  reserve(size()*2+1);
207  }
208  soahelper::SoATupleHelper<sizeof...(Args),Args...>::emplace_back(m_values,m_size,std::forward<FArgs>(values)...);
209  ++m_size;
210  }
211 
213  template<unsigned int I>
214  typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type& get(unsigned int iIndex) {
215  typedef typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type ReturnType;
216  return *(static_cast<ReturnType*>(m_values[I])+iIndex);
217  }
218 
220  template<unsigned int I>
221  typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type* begin() {
222  typedef soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type> Helper;
223  typedef typename Helper::Type ReturnType;
224 #if GCC_PREREQUISITE(4,7,0)
225  return static_cast<ReturnType*>(__builtin_assume_aligned(m_values[I],Helper::kAlignment));
226 #else
227  return static_cast<ReturnType*>(m_values[I]);
228 #endif
229  }
231  template<unsigned int I>
232  typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type* end() {
233  typedef typename soahelper::AlignmentHelper<typename std::tuple_element<I, std::tuple<Args...>>::type>::Type ReturnType;
234  return static_cast<ReturnType*>(m_values[I])+m_size;
235  }
236 
237  void swap(SoATuple<Args...>& iOther) {
238  std::swap(m_size,iOther.m_size);
240  for(unsigned int i=0; i<sizeof...(Args);++i) {
241  std::swap(m_values[i],iOther.m_values[i]);
242  }
243  }
244  private:
245 
246  void changeSize(unsigned int iToSize) {
247  assert(m_size<=iToSize);
248  const size_t memoryNeededInBytes = soahelper::SoATupleHelper<sizeof...(Args),Args...>::spaceNeededFor(iToSize);
249  //align memory of the array to be on the strictest alignment boundary for any type in the Tuple
250  // This is done by creating an array of a type that has that same alignment restriction and minimum size.
251  // This has the draw back of possibly padding the array by one extra element if the memoryNeededInBytes is not
252  // a strict multiple of max_alignment.
253  // NOTE: using new char[...] would likely cause more padding based on C++11 5.3.4 paragraph 10 where it
254  // says the alignment will be for the strictest requirement for an object whose size < size of array. So
255  // if the array were for 64 bytes and the strictest requirement of any object was 8 bytes then the entire
256  // char array would be aligned on an 8 byte boundary. However, if the SoATuple<char,char> only 1 byte alignment
257  // is needed. The following algorithm would require only 1 byte alignment
258  const std::size_t max_alignment = soahelper::SoATupleHelper<sizeof...(Args),Args...>::max_alignment;
259  typedef std::aligned_storage<soahelper::SoATupleHelper<sizeof...(Args),Args...>::max_alignment,
260  soahelper::SoATupleHelper<sizeof...(Args),Args...>::max_alignment> AlignedType;
261  //If needed, pad the number of items by 1
262  const size_t itemsNeeded = (memoryNeededInBytes+max_alignment-1)/sizeof(AlignedType);
263  char * newMemory = static_cast<char*>(static_cast<void*>(new AlignedType[itemsNeeded]));
264  void * oldMemory =m_values[0];
265  soahelper::SoATupleHelper<sizeof...(Args),Args...>::moveToNew(newMemory,m_size, iToSize, m_values);
266  m_reserved = iToSize;
267  delete [] static_cast<AlignedType*>(oldMemory);
268  }
269  // ---------- member data --------------------------------
270  //Pointers to where each column starts in the shared memory array
271  //m_values[0] also points to the beginning of the shared memory area
272  void* m_values[sizeof...(Args)];
273  size_t m_size;
274  size_t m_reserved;
275  };
276 }
277 
278 
279 #endif
type
Definition: HCALResponse.h:21
soahelper::AlignmentHelper< typename std::tuple_element< I, std::tuple< Args...> >::type >::Type const * begin() const
Definition: SoATuple.h:162
int i
Definition: DBlmapReader.cc:9
void changeSize(unsigned int iToSize)
Definition: SoATuple.h:246
SoATuple(const SoATuple< Args...> &iOther)
Definition: SoATuple.h:119
std::tuple< Args...> element
Definition: SoATuple.h:112
void swap(SoATuple< Args...> &iOther)
Definition: SoATuple.h:237
size_t m_reserved
Definition: SoATuple.h:274
size_t m_size
Definition: SoATuple.h:273
void emplace_back(FArgs &&...values)
Definition: SoATuple.h:204
void push_back(element const &values)
Definition: SoATuple.h:194
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
size_t size() const
Definition: SoATuple.h:150
const std::complex< double > I
Definition: I.h:8
soahelper::AlignmentHelper< typename std::tuple_element< I, std::tuple< Args...> >::type >::Type * begin()
Definition: SoATuple.h:221
size_t capacity() const
Definition: SoATuple.h:151
SoATuple(SoATuple< Args...> &&iOther)
Definition: SoATuple.h:128
const SoATuple< Args...> & operator=(const SoATuple< Args...> &iRHS)
Definition: SoATuple.h:135
string const
Definition: compareJSON.py:14
soahelper::AlignmentHelper< typename std::tuple_element< I, std::tuple< Args...> >::type >::Type const * end() const
Definition: SoATuple.h:173
soahelper::AlignmentHelper< typename std::tuple_element< I, std::tuple< Args...> >::type >::Type * end()
Definition: SoATuple.h:232
void shrink_to_fit()
Definition: SoATuple.h:187
void reserve(unsigned int iToSize)
Definition: SoATuple.h:180
void * m_values[sizeof...(Args)]
Definition: SoATuple.h:272