CMS 3D CMS Logo

SoATupleHelper.h
Go to the documentation of this file.
1 #ifndef FWCore_Utilities_SoATupleHelper_h
2 #define FWCore_Utilities_SoATupleHelper_h
3 // -*- C++ -*-
4 //
5 // Package: Package
6 // Class : SoATupleHelper
7 //
16 //
17 // Original Author: Chris Jones
18 // Created: Tue, 16 Apr 2013 21:06:08 GMT
19 //
20 
21 // system include files
22 #include <tuple>
23 #include <algorithm>
24 
25 // user include files
26 
27 // forward declarations
28 namespace edm {
29  namespace soahelper {
30 
33  constexpr unsigned int padding_needed(size_t iSizeSoFar, unsigned int iBoundary) {
34  return (iBoundary - iSizeSoFar % iBoundary) % iBoundary;
35  }
36 
42  template<unsigned int I, unsigned int J, typename Ret, typename... Args>
43  struct arg_puller;
44 
46  template<unsigned int I, unsigned int J, typename Ret, typename F, typename... Args>
47  struct arg_puller<I,J,Ret,F, Args...> {
48  static Ret pull(F const&, const Args&... args) {
50  }
51  };
52 
54  template<unsigned int I, typename Ret, typename F, typename... Args>
55  struct arg_puller<I,I,Ret,F, Args...> {
56  static Ret pull(F const& iV, const Args&...) {
57  return iV;
58  }
59  };
60 
65  template<typename T, unsigned int ALIGNMENT>
66  struct Aligned {
67  static const unsigned int kAlignment = ALIGNMENT;
68  typedef T Type;
69  };
70 
71 
76  template<typename T>
77  struct AlignmentHelper {
78  static const std::size_t kAlignment = alignof(T);
79  typedef T Type;
80  };
81 
85  template<typename T, unsigned int ALIGNMENT>
86  struct AlignmentHelper<Aligned<T,ALIGNMENT>> {
87  static const std::size_t kAlignment = ALIGNMENT;
88  typedef T Type;
89  };
90 
95  template<unsigned int I, typename... Args>
97  {
98  typedef AlignmentHelper<typename std::tuple_element<I-1, std::tuple<Args...>>::type> AlignmentInfo;
99  typedef typename AlignmentInfo::Type Type;
100  typedef SoATupleHelper<I-1,Args...> NextHelper;
101 
102  static const std::size_t max_alignment = AlignmentInfo::kAlignment > NextHelper::max_alignment ?
103  AlignmentInfo::kAlignment: NextHelper::max_alignment;
104 
105  // ---------- static member functions --------------------
106  static size_t moveToNew(char* iNewMemory, size_t iSize, size_t iReserve, void** oToSet);
107  static size_t copyToNew(char* iNewMemory, size_t iSize, size_t iReserve, void* const* iFrom, void** oToSet);
108  static size_t spaceNeededFor(unsigned int iNElements);
109  static void push_back(void** iToSet, size_t iSize, std::tuple<Args...> const& iValues);
110  template<typename... FArgs>
111  static void emplace_back(void** iToSet, size_t iSize, FArgs... iValues);
112  static void destroy(void** iToSet, size_t iSize);
113 
114  // ---------- member functions ---------------------------
115  SoATupleHelper(const SoATupleHelper&) = delete; // stop default
116 
117  const SoATupleHelper& operator=(const SoATupleHelper&) = delete; // stop default
118 
119  };
120 
121  //Specialization used to stop recursion
122  template<typename... Args>
123  struct SoATupleHelper<0,Args...> {
124  static const std::size_t max_alignment = 0;
125  static void destroy(void** /*iToSet*/, size_t /*iSize*/) {
126  }
127 
128  static void push_back(void** /*iToSet*/, size_t /*iSize*/, std::tuple<Args...> const& /*values*/) {
129  }
130 
131  template<typename... FArgs>
132  static void emplace_back(void** iToSet, size_t iSize, FArgs... iValues) {}
133 
134  static size_t spaceNeededFor(unsigned int /*iNElements*/) {
135  return 0;
136  }
137 
138  static size_t moveToNew(char* /*iNewMemory*/, size_t /*iSize*/, size_t /*iReserve*/, void** /*oToSet*/) {
139  return 0;
140  }
141 
142  static size_t copyToNew(char* /*iNewMemory*/, size_t /*iSize*/, size_t /*iReserve*/, void* const* /*iFrom*/, void** /*oToSet*/) {
143  return 0;
144  }
145  };
146 
147  template<unsigned int I, typename... Args>
148  size_t SoATupleHelper<I,Args...>::moveToNew(char* iNewMemory, size_t iSize, size_t iReserve, void** oToSet) {
149  size_t usedSoFar = NextHelper::moveToNew(iNewMemory,iSize, iReserve, oToSet);
150 
151  //find new start
152  const unsigned int boundary = AlignmentInfo::kAlignment;
153 
154  Type* newStart = reinterpret_cast<Type*>(iNewMemory+usedSoFar+padding_needed(usedSoFar,boundary));
155 
156  void** oldStart = oToSet+I-1;
157 
158  Type* oldValues = static_cast<Type*>(*oldStart);
159  if(oldValues != nullptr ) {
160  auto ptr = newStart;
161  for(auto it = oldValues; it != oldValues+iSize; ++it,++ptr) {
162  new (ptr) Type(std::move(*it));
163  }
164  for(auto it = oldValues; it != oldValues+iSize; ++it) {
165  it->~Type();
166  }
167  }
168  *oldStart = newStart;
169  unsigned int additionalSize = padding_needed(usedSoFar,boundary) + iReserve*sizeof(Type);
170  return usedSoFar+additionalSize;
171  }
172 
173  template<unsigned int I, typename... Args>
174  size_t SoATupleHelper<I,Args...>::copyToNew(char* iNewMemory, size_t iSize, size_t iReserve, void* const* iFrom, void** oToSet) {
175  size_t usedSoFar = NextHelper::copyToNew(iNewMemory,iSize, iReserve, iFrom, oToSet);
176 
177  //find new start
178  const unsigned int boundary = AlignmentInfo::kAlignment;
179 
180  Type* newStart = reinterpret_cast<Type*>(iNewMemory+usedSoFar+padding_needed(usedSoFar,boundary));
181 
182  void* const* oldStart = iFrom+I-1;
183 
184  Type* oldValues = static_cast<Type*>(*oldStart);
185  if(oldValues != nullptr ) {
186  auto ptr = newStart;
187  for(auto it = oldValues; it != oldValues+iSize; ++it,++ptr) {
188  new (ptr) Type(*it);
189  }
190  }
191  *(oToSet+I-1) = newStart;
192  unsigned int additionalSize = padding_needed(usedSoFar,boundary) + iReserve*sizeof(Type);
193  return usedSoFar+additionalSize;
194  }
195 
196 
197  template<unsigned int I, typename... Args>
198  size_t SoATupleHelper<I,Args...>::spaceNeededFor(unsigned int iNElements) {
199  size_t usedSoFar = NextHelper::spaceNeededFor(iNElements);
200  const unsigned int boundary = AlignmentInfo::kAlignment;
201  unsigned int additionalSize = padding_needed(usedSoFar,boundary) + iNElements*sizeof(Type);
202  return usedSoFar+additionalSize;
203  }
204 
205  template<unsigned int I, typename... Args>
206  void SoATupleHelper<I,Args...>::push_back(void** iToSet, size_t iSize, std::tuple<Args...> const& iValues) {
207  new (static_cast<Type*>(*(iToSet+I-1))+iSize) Type(std::get<I-1>(iValues));
208 
209  NextHelper::push_back(iToSet,iSize,iValues);
210  }
211 
212  template<unsigned int I, typename... Args>
213  template<typename ... FArgs>
214  void SoATupleHelper<I,Args...>::emplace_back(void** iToSet, size_t iSize, FArgs... iValues) {
215  new (static_cast<Type*>(*(iToSet+I-1))+iSize) Type(arg_puller<0,I-1,Type const&, FArgs...>::pull(std::forward<FArgs>(iValues)...));
216 
217  NextHelper::emplace_back(iToSet,iSize,std::forward<FArgs>(iValues)...);
218  }
219 
220  template<unsigned int I, typename... Args>
221  void SoATupleHelper<I,Args...>::destroy(void** iToSet, size_t iSize) {
222  void** start = iToSet+I-1;
223  Type* values = static_cast<Type*>(*start);
224 
225  for(auto it = values; it != values+iSize; ++it) {
226  it->~Type();
227  }
228 
229  NextHelper::destroy(iToSet,iSize);
230  }
231 
232  }
233 }
234 
235 #endif
Definition: start.py:1
static size_t moveToNew(char *iNewMemory, size_t iSize, size_t iReserve, void **oToSet)
type
Definition: HCALResponse.h:21
static size_t moveToNew(char *, size_t, size_t, void **)
def destroy(e)
Definition: pyrootRender.py:14
SoATupleHelper< I-1, Args... > NextHelper
static size_t copyToNew(char *, size_t, size_t, void *const *, void **)
#define constexpr
static void emplace_back(void **iToSet, size_t iSize, FArgs...iValues)
static void push_back(void **iToSet, size_t iSize, std::tuple< Args... > const &iValues)
static size_t copyToNew(char *iNewMemory, size_t iSize, size_t iReserve, void *const *iFrom, void **oToSet)
static Ret pull(F const &, const Args &...args)
const std::complex< double > I
Definition: I.h:8
HLT enums.
static void push_back(void **, size_t, std::tuple< Args... > const &)
AlignmentHelper< typename std::tuple_element< I-1, std::tuple< Args... > >::type > AlignmentInfo
static void emplace_back(void **iToSet, size_t iSize, FArgs...iValues)
static Ret pull(F const &iV, const Args &...)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
static size_t spaceNeededFor(unsigned int iNElements)
long double T
static size_t spaceNeededFor(unsigned int)
def move(src, dest)
Definition: eostools.py:511
constexpr unsigned int padding_needed(size_t iSizeSoFar, unsigned int iBoundary)
static void destroy(void **iToSet, size_t iSize)