23
23
#include " Math/StaticCheck.h"
24
24
#endif
25
25
26
+ #include < cstddef>
27
+ #include < utility>
28
+ #include < type_traits>
29
+ #include < array>
30
+
26
31
namespace ROOT {
27
32
28
33
namespace Math {
@@ -142,96 +147,49 @@ namespace Math {
142
147
int fOff [D*D];
143
148
};
144
149
145
- // Make the lookup tables available at compile time:
146
- // Add them to a namespace?
147
- static const int fOff1x1 [] = {0 };
148
- static const int fOff2x2 [] = {0 , 1 , 1 , 2 };
149
- static const int fOff3x3 [] = {0 , 1 , 3 , 1 , 2 , 4 , 3 , 4 , 5 };
150
- static const int fOff4x4 [] = {0 , 1 , 3 , 6 , 1 , 2 , 4 , 7 , 3 , 4 , 5 , 8 , 6 , 7 , 8 , 9 };
151
- static const int fOff5x5 [] = {0 , 1 , 3 , 6 , 10 , 1 , 2 , 4 , 7 , 11 , 3 , 4 , 5 , 8 , 12 , 6 , 7 , 8 , 9 , 13 , 10 , 11 , 12 , 13 , 14 };
152
- static const int fOff6x6 [] = {0 , 1 , 3 , 6 , 10 , 15 , 1 , 2 , 4 , 7 , 11 , 16 , 3 , 4 , 5 , 8 , 12 , 17 , 6 , 7 , 8 , 9 , 13 , 18 , 10 , 11 , 12 , 13 , 14 , 19 , 15 , 16 , 17 , 18 , 19 , 20 };
150
+ namespace rowOffsetsUtils {
153
151
154
- static const int fOff7x7 [] = {0 , 1 , 3 , 6 , 10 , 15 , 21 , 1 , 2 , 4 , 7 , 11 , 16 , 22 , 3 , 4 , 5 , 8 , 12 , 17 , 23 , 6 , 7 , 8 , 9 , 13 , 18 , 24 , 10 , 11 , 12 , 13 , 14 , 19 , 25 , 15 , 16 , 17 , 18 , 19 , 20 , 26 , 21 , 22 , 23 , 24 , 25 , 26 , 27 };
152
+ // /////////
153
+ // Some meta template stuff
154
+ template <int ...> struct indices {};
155
155
156
- static const int fOff8x8 [] = {0 , 1 , 3 , 6 , 10 , 15 , 21 , 28 , 1 , 2 , 4 , 7 , 11 , 16 , 22 , 29 , 3 , 4 , 5 , 8 , 12 , 17 , 23 , 30 , 6 , 7 , 8 , 9 , 13 , 18 , 24 , 31 , 10 , 11 , 12 , 13 , 14 , 19 , 25 , 32 , 15 , 16 , 17 , 18 , 19 , 20 , 26 , 33 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 34 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 };
156
+ template <int I, class IndexTuple , int N>
157
+ struct make_indices_impl ;
157
158
158
- static const int fOff9x9 [] = {0 , 1 , 3 , 6 , 10 , 15 , 21 , 28 , 36 , 1 , 2 , 4 , 7 , 11 , 16 , 22 , 29 , 37 , 3 , 4 , 5 , 8 , 12 , 17 , 23 , 30 , 38 , 6 , 7 , 8 , 9 , 13 , 18 , 24 , 31 , 39 , 10 , 11 , 12 , 13 , 14 , 19 , 25 , 32 , 40 , 15 , 16 , 17 , 18 , 19 , 20 , 26 , 33 , 41 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 34 , 42 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 43 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 };
159
+ template <int I, int ... Indices, int N>
160
+ struct make_indices_impl <I, indices<Indices...>, N>
161
+ {
162
+ typedef typename make_indices_impl<I + 1 , indices<Indices..., I>,
163
+ N>::type type;
164
+ };
159
165
160
- static const int fOff10x10 [] = {0 , 1 , 3 , 6 , 10 , 15 , 21 , 28 , 36 , 45 , 1 , 2 , 4 , 7 , 11 , 16 , 22 , 29 , 37 , 46 , 3 , 4 , 5 , 8 , 12 , 17 , 23 , 30 , 38 , 47 , 6 , 7 , 8 , 9 , 13 , 18 , 24 , 31 , 39 , 48 , 10 , 11 , 12 , 13 , 14 , 19 , 25 , 32 , 40 , 49 , 15 , 16 , 17 , 18 , 19 , 20 , 26 , 33 , 41 , 50 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 34 , 42 , 51 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 43 , 52 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 53 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 };
166
+ template <int N, int ... Indices>
167
+ struct make_indices_impl <N, indices<Indices...>, N> {
168
+ typedef indices<Indices...> type;
169
+ };
161
170
162
- template <>
163
- struct RowOffsets <1 > {
164
- RowOffsets () {}
165
- int operator ()(unsigned int , unsigned int ) const { return 0 ; } // Just one element
166
- int apply (unsigned int ) const { return 0 ; }
167
- };
171
+ template <int N>
172
+ struct make_indices : make_indices_impl<0 , indices<>, N> {};
173
+ // end of stuff
168
174
169
- template <>
170
- struct RowOffsets <2 > {
171
- RowOffsets () {}
172
- int operator ()(unsigned int i, unsigned int j) const { return i+j; /* fOff2x2[i*2+j];*/ }
173
- int apply (unsigned int i) const { return fOff2x2 [i]; }
174
- };
175
175
176
- template <>
177
- struct RowOffsets <3 > {
178
- RowOffsets () {}
179
- int operator ()(unsigned int i, unsigned int j) const { return fOff3x3 [i*3 +j]; }
180
- int apply (unsigned int i) const { return fOff3x3 [i]; }
181
- };
182
176
183
- template <>
184
- struct RowOffsets <4 > {
185
- RowOffsets () {}
186
- int operator ()(unsigned int i, unsigned int j) const { return fOff4x4 [i*4 +j]; }
187
- int apply (unsigned int i) const { return fOff4x4 [i]; }
188
- };
177
+ template <int I0, class F , int ... I>
178
+ constexpr std::array<decltype (std::declval<F>()(std::declval<int >())), sizeof ...(I)>
179
+ do_make (F f, indices<I...>)
180
+ {
181
+ return std::array<decltype (std::declval<F>()(std::declval<int >())),
182
+ sizeof ...(I)>{{ f (I0 + I)... }};
183
+ }
189
184
190
- template <>
191
- struct RowOffsets <5 > {
192
- inline RowOffsets () {}
193
- inline int operator ()(unsigned int i, unsigned int j) const { return fOff5x5 [i*5 +j]; }
194
- // int operator()(unsigned int i, unsigned int j) const {
195
- // if(j <= i) return (i * (i + 1)) / 2 + j;
196
- // else return (j * (j + 1)) / 2 + i;
197
- // }
198
- inline int apply (unsigned int i) const { return fOff5x5 [i]; }
199
- };
185
+ template <int N, int I0 = 0 , class F >
186
+ constexpr std::array<decltype (std::declval<F>()(std::declval<int >())), N>
187
+ make (F f) {
188
+ return do_make<I0>(f, typename make_indices<N>::type ());
189
+ }
200
190
201
- template <>
202
- struct RowOffsets <6 > {
203
- RowOffsets () {}
204
- int operator ()(unsigned int i, unsigned int j) const { return fOff6x6 [i*6 +j]; }
205
- int apply (unsigned int i) const { return fOff6x6 [i]; }
206
- };
191
+ } // namespace rowOffsetsUtils
207
192
208
- template <>
209
- struct RowOffsets <7 > {
210
- RowOffsets () {}
211
- int operator ()(unsigned int i, unsigned int j) const { return fOff7x7 [i*7 +j]; }
212
- int apply (unsigned int i) const { return fOff7x7 [i]; }
213
- };
214
-
215
- template <>
216
- struct RowOffsets <8 > {
217
- RowOffsets () {}
218
- int operator ()(unsigned int i, unsigned int j) const { return fOff8x8 [i*8 +j]; }
219
- int apply (unsigned int i) const { return fOff8x8 [i]; }
220
- };
221
-
222
- template <>
223
- struct RowOffsets <9 > {
224
- RowOffsets () {}
225
- int operator ()(unsigned int i, unsigned int j) const { return fOff9x9 [i*9 +j]; }
226
- int apply (unsigned int i) const { return fOff9x9 [i]; }
227
- };
228
-
229
- template <>
230
- struct RowOffsets <10 > {
231
- RowOffsets () {}
232
- int operator ()(unsigned int i, unsigned int j) const { return fOff10x10 [i*10 +j]; }
233
- int apply (unsigned int i) const { return fOff10x10 [i]; }
234
- };
235
193
236
194
// _________________________________________________________________________________
237
195
/* *
@@ -257,35 +215,32 @@ template<>
257
215
258
216
public:
259
217
260
- MatRepSym () : fOff ( 0 ) { CreateOffsets (); }
218
+ /* constexpr */ inline MatRepSym (){ }
261
219
262
- typedef T value_type;
220
+ typedef T value_type;
263
221
264
- inline const T& operator ()(unsigned int i, unsigned int j) const {
265
- return fArray [Offsets ()(i,j)];
266
- }
267
- inline T& operator ()(unsigned int i, unsigned int j) {
268
- return fArray [Offsets ()(i,j)];
269
- }
270
222
271
- inline T& operator [](unsigned int i) {
272
- return fArray [Offsets ().apply (i) ];
273
- // return fArray[Offsets()(i/D, i%D)];
274
- }
223
+ inline T & operator ()(unsigned int i, unsigned int j)
224
+ { return fArray [offset (i, j)]; }
275
225
276
- inline const T& operator [](unsigned int i) const {
277
- return fArray [Offsets ().apply (i) ];
278
- // return fArray[Offsets()(i/D, i%D)];
279
- }
226
+ inline /* constexpr */ T const & operator ()(unsigned int i, unsigned int j) const
227
+ { return fArray [offset (i, j)]; }
280
228
281
- inline T apply (unsigned int i) const {
282
- return fArray [Offsets ().apply (i) ];
283
- // return operator()(i/D, i%D);
284
- }
229
+ inline T& operator [](unsigned int i) {
230
+ return fArray [off (i)];
231
+ }
285
232
286
- inline T* Array () { return fArray ; }
233
+ inline /* constexpr */ T const & operator [](unsigned int i) const {
234
+ return fArray [off (i)];
235
+ }
287
236
288
- inline const T* Array () const { return fArray ; }
237
+ inline /* constexpr */ T apply (unsigned int i) const {
238
+ return fArray [off (i)];
239
+ }
240
+
241
+ inline T* Array () { return fArray ; }
242
+
243
+ inline const T* Array () const { return fArray ; }
289
244
290
245
/* *
291
246
assignment : only symmetric to symmetric allowed
@@ -346,22 +301,26 @@ template<>
346
301
kSize = D*(D+1 )/2
347
302
};
348
303
304
+ static constexpr int off0 (int i) { return i==0 ? 0 : off0 (i-1 )+i;}
305
+ static constexpr int off2 (int i, int j) { return j<i ? off0 (i)+j : off0 (j)+i; }
306
+ static constexpr int off1 (int i) { return off2 (i/D, i%D);}
349
307
350
- void CreateOffsets ( ) {
351
- const static RowOffsets<D> off ;
352
- fOff = &off ;
353
- }
308
+ static int off ( int i ) {
309
+ static constexpr auto v = rowOffsetsUtils::make<D*D>(off1) ;
310
+ return v[i] ;
311
+ }
354
312
355
- inline const RowOffsets<D> & Offsets () const {
356
- return *fOff ;
357
- }
313
+ static inline constexpr unsigned int
314
+ offset (unsigned int i, unsigned int j)
315
+ {
316
+ // if (j > i) std::swap(i, j);
317
+ return off (i*D+j);
318
+ // return (i>j) ? (i * (i+1) / 2) + j : (j * (j+1) / 2) + i;
319
+ }
358
320
359
321
private:
360
322
// T __attribute__ ((aligned (16))) fArray[kSize];
361
323
T fArray [kSize ];
362
-
363
- const RowOffsets<D> * fOff ; // ! transient
364
-
365
324
};
366
325
367
326
0 commit comments