CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 // $Id: SoATupleHelper.h,v 1.4 2013/04/23 20:07:48 chrjones Exp $
20 //
21 
22 // system include files
23 #include <tuple>
24 #include <algorithm>
25 
26 // user include files
27 
28 // forward declarations
29 namespace edm {
30  namespace soahelper {
31 
34  constexpr unsigned int padding_needed(size_t iSizeSoFar, unsigned int iBoundary) {
35  return (iBoundary - iSizeSoFar % iBoundary) % iBoundary;
36  }
37 
43  template<unsigned int I, unsigned int J, typename Ret, typename... Args>
44  struct arg_puller;
45 
47  template<unsigned int I, unsigned int J, typename Ret, typename F, typename... Args>
48  struct arg_puller<I,J,Ret,F, Args...> {
49  static Ret pull(F const&, const Args&... args) {
51  }
52  };
53 
55  template<unsigned int I, typename Ret, typename F, typename... Args>
56  struct arg_puller<I,I,Ret,F, Args...> {
57  static Ret pull(F const& iV, const Args&...) {
58  return iV;
59  }
60  };
61 
66  template<typename T, unsigned int ALIGNMENT>
67  struct Aligned {
68  static const unsigned int kAlignment = ALIGNMENT;
69  typedef T Type;
70  };
71 
72 
77  template<typename T>
78  struct AlignmentHelper {
79  static const std::size_t kAlignment = alignof(T);
80  typedef T Type;
81  };
82 
86  template<typename T, unsigned int ALIGNMENT>
87  struct AlignmentHelper<Aligned<T,ALIGNMENT>> {
88  static const std::size_t kAlignment = ALIGNMENT;
89  typedef T Type;
90  };
91 
96  template<unsigned int I, typename... Args>
98  {
99  typedef AlignmentHelper<typename std::tuple_element<I-1, std::tuple<Args...>>::type> AlignmentInfo;
100  typedef typename AlignmentInfo::Type Type;
102 
105 
106  // ---------- static member functions --------------------
107  static size_t moveToNew(char* iNewMemory, size_t iSize, size_t iReserve, void** oToSet);
108  static size_t copyToNew(char* iNewMemory, size_t iSize, size_t iReserve, void* const* iFrom, void** oToSet);
109  static size_t spaceNeededFor(unsigned int iNElements);
110  static void push_back(void** iToSet, size_t iSize, std::tuple<Args...> const& iValues);
111  template<typename... FArgs>
112  static void emplace_back(void** iToSet, size_t iSize, FArgs... iValues);
113  static void destroy(void** iToSet, size_t iSize);
114 
115  // ---------- member functions ---------------------------
116  SoATupleHelper(const SoATupleHelper&) = delete; // stop default
117 
118  const SoATupleHelper& operator=(const SoATupleHelper&) = delete; // stop default
119 
120  };
121 
122  //Specialization used to stop recursion
123  template<typename... Args>
124  struct SoATupleHelper<0,Args...> {
125  static const std::size_t max_alignment = 0;
126  static void destroy(void** /*iToSet*/, size_t /*iSize*/) {
127  }
128 
129  static void push_back(void** /*iToSet*/, size_t /*iSize*/, std::tuple<Args...> const& /*values*/) {
130  }
131 
132  template<typename... FArgs>
133  static void emplace_back(void** iToSet, size_t iSize, FArgs... iValues) {}
134 
135  static size_t spaceNeededFor(unsigned int /*iNElements*/) {
136  return 0;
137  }
138 
139  static size_t moveToNew(char* /*iNewMemory*/, size_t /*iSize*/, size_t /*iReserve*/, void** /*oToSet*/) {
140  return 0;
141  }
142 
143  static size_t copyToNew(char* /*iNewMemory*/, size_t /*iSize*/, size_t /*iReserve*/, void* const* /*iFrom*/, void** /*oToSet*/) {
144  return 0;
145  }
146  };
147 
148  template<unsigned int I, typename... Args>
149  size_t SoATupleHelper<I,Args...>::moveToNew(char* iNewMemory, size_t iSize, size_t iReserve, void** oToSet) {
150  size_t usedSoFar = NextHelper::moveToNew(iNewMemory,iSize, iReserve, oToSet);
151 
152  //find new start
153  const unsigned int boundary = AlignmentInfo::kAlignment;
154 
155  Type* newStart = reinterpret_cast<Type*>(iNewMemory+usedSoFar+padding_needed(usedSoFar,boundary));
156 
157  void** oldStart = oToSet+I-1;
158 
159  Type* oldValues = static_cast<Type*>(*oldStart);
160  if(oldValues != nullptr ) {
161  auto ptr = newStart;
162  for(auto it = oldValues; it != oldValues+iSize; ++it,++ptr) {
163  new (ptr) Type(std::move(*it));
164  }
165  for(auto it = oldValues; it != oldValues+iSize; ++it) {
166  it->~Type();
167  }
168  }
169  *oldStart = newStart;
170  unsigned int additionalSize = padding_needed(usedSoFar,boundary) + iReserve*sizeof(Type);
171  return usedSoFar+additionalSize;
172  }
173 
174  template<unsigned int I, typename... Args>
175  size_t SoATupleHelper<I,Args...>::copyToNew(char* iNewMemory, size_t iSize, size_t iReserve, void* const* iFrom, void** oToSet) {
176  size_t usedSoFar = NextHelper::copyToNew(iNewMemory,iSize, iReserve, iFrom, oToSet);
177 
178  //find new start
179  const unsigned int boundary = AlignmentInfo::kAlignment;
180 
181  Type* newStart = reinterpret_cast<Type*>(iNewMemory+usedSoFar+padding_needed(usedSoFar,boundary));
182 
183  void* const* oldStart = iFrom+I-1;
184 
185  Type* oldValues = static_cast<Type*>(*oldStart);
186  if(oldValues != nullptr ) {
187  auto ptr = newStart;
188  for(auto it = oldValues; it != oldValues+iSize; ++it,++ptr) {
189  new (ptr) Type(*it);
190  }
191  }
192  *(oToSet+I-1) = newStart;
193  unsigned int additionalSize = padding_needed(usedSoFar,boundary) + iReserve*sizeof(Type);
194  return usedSoFar+additionalSize;
195  }
196 
197 
198  template<unsigned int I, typename... Args>
199  size_t SoATupleHelper<I,Args...>::spaceNeededFor(unsigned int iNElements) {
200  size_t usedSoFar = NextHelper::spaceNeededFor(iNElements);
201  const unsigned int boundary = AlignmentInfo::kAlignment;
202  unsigned int additionalSize = padding_needed(usedSoFar,boundary) + iNElements*sizeof(Type);
203  return usedSoFar+additionalSize;
204  }
205 
206  template<unsigned int I, typename... Args>
207  void SoATupleHelper<I,Args...>::push_back(void** iToSet, size_t iSize, std::tuple<Args...> const& iValues) {
208  new (static_cast<Type*>(*(iToSet+I-1))+iSize) Type(std::get<I-1>(iValues));
209 
210  NextHelper::push_back(iToSet,iSize,iValues);
211  }
212 
213  template<unsigned int I, typename... Args>
214  template<typename ... FArgs>
215  void SoATupleHelper<I,Args...>::emplace_back(void** iToSet, size_t iSize, FArgs... iValues) {
216  new (static_cast<Type*>(*(iToSet+I-1))+iSize) Type(arg_puller<0,I-1,Type const&, FArgs...>::pull(std::forward<FArgs>(iValues)...));
217 
218  NextHelper::emplace_back(iToSet,iSize,std::forward<FArgs>(iValues)...);
219  }
220 
221  template<unsigned int I, typename... Args>
222  void SoATupleHelper<I,Args...>::destroy(void** iToSet, size_t iSize) {
223  void** start = iToSet+I-1;
224  Type* values = static_cast<Type*>(*start);
225 
226  for(auto it = values; it != values+iSize; ++it) {
227  it->~Type();
228  }
229 
230  NextHelper::destroy(iToSet,iSize);
231  }
232 
233  }
234 }
235 
236 #endif
static size_t moveToNew(char *iNewMemory, size_t iSize, size_t iReserve, void **oToSet)
type
Definition: HCALResponse.h:21
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
static void destroy(void **, size_t)
static void push_back(void **iToSet, size_t iSize, std::tuple< Args...> const &iValues)
SoATupleHelper< I-1, Args...> NextHelper
static size_t copyToNew(char *, size_t, size_t, void *const *, void **)
static void emplace_back(void **iToSet, size_t iSize, FArgs...iValues)
static size_t copyToNew(char *iNewMemory, size_t iSize, size_t iReserve, void *const *iFrom, void **oToSet)
static size_t spaceNeededFor(unsigned int)
const SoATupleHelper & operator=(const SoATupleHelper &)=delete
const std::complex< double > I
Definition: I.h:8
static Ret pull(F const &, const Args &...args)
static void emplace_back(void **iToSet, size_t iSize, FArgs...iValues)
static const std::size_t max_alignment
SoATupleHelper(const SoATupleHelper &)=delete
dictionary args
static Ret pull(F const &iV, const Args &...)
AlignmentHelper< typename std::tuple_element< I-1, std::tuple< Args...> >::type > AlignmentInfo
static const unsigned int kAlignment
static void push_back(void **, size_t, std::tuple< Args...> const &)
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 moveToNew(char *, size_t, size_t, void **)
constexpr unsigned int padding_needed(size_t iSizeSoFar, unsigned int iBoundary)
#define constexpr
static void destroy(void **iToSet, size_t iSize)
static const std::size_t kAlignment