1 | #ifndef GRID_KEY_DX |
2 | #define GRID_KEY_DX |
3 | |
4 | #include "Grid/comb.hpp" |
5 | #include "Grid/grid_key_expression.hpp" |
6 | #include "Space/Shape/Point.hpp" |
7 | |
8 | /*! \brief grid_key_dx is the key to access any element in the grid |
9 | * |
10 | * Given a grid in general a set of indexes define one element in the grid |
11 | * For example 2 indexes identify one element on a two dimensional grid, |
12 | * 3 indexes on a 3 dimensional grid ... |
13 | * |
14 | * \tparam dim dimensionality of the grid |
15 | * |
16 | */ |
17 | template<unsigned int dim, typename index_type> |
18 | class grid_key_dx |
19 | { |
20 | public: |
21 | |
22 | /*! \brief Constructor from expression |
23 | * |
24 | * \param exp grid_key_dx expression |
25 | * |
26 | */ |
27 | template<typename exp1> |
28 | __device__ __host__ inline grid_key_dx(const grid_key_dx_expression<dim,exp1> & exp) |
29 | { |
30 | for (size_t i = 0 ; i < dim ; i++) |
31 | this->k[i] = exp.value(i); |
32 | } |
33 | |
34 | //! Constructor |
35 | __device__ __host__ inline grid_key_dx() |
36 | {} |
37 | |
38 | /*! \brief Constructor from initializer list |
39 | * |
40 | * \param p1 initializer list |
41 | * |
42 | */ |
43 | __device__ __host__ inline grid_key_dx(std::initializer_list<long int> p1) |
44 | { |
45 | size_t i = 0; |
46 | for(long int x : p1) |
47 | { |
48 | set_d(i,x); |
49 | i++; |
50 | if (i >= dim) |
51 | break; |
52 | } |
53 | } |
54 | |
55 | /*! \brief Constructor from an other key |
56 | * |
57 | * \param key copy constructor |
58 | * |
59 | */ |
60 | __device__ __host__ inline grid_key_dx(const grid_key_dx<dim,index_type> & key) |
61 | :grid_key_dx(key.k) |
62 | { |
63 | } |
64 | |
65 | /*! \brief Constructor from buffer reference |
66 | * |
67 | * \param k reference buffer |
68 | * |
69 | */ |
70 | __device__ __host__ inline grid_key_dx(const size_t (&k)[dim]) |
71 | { |
72 | for (size_t i = 0 ; i < dim ; i++) |
73 | this->k[i] = k[i]; |
74 | } |
75 | |
76 | /*! \brief Constructor from buffer reference |
77 | * |
78 | * \param k reference buffer |
79 | * |
80 | */ |
81 | __device__ __host__ inline grid_key_dx(const long int (&k)[dim]) |
82 | { |
83 | for (size_t i = 0 ; i < dim ; i++) |
84 | {this->k[i] = k[i];} |
85 | } |
86 | |
87 | /*! \brief Constructor from buffer reference |
88 | * |
89 | * \param k reference buffer |
90 | * |
91 | */ |
92 | __device__ __host__ inline grid_key_dx(const short (&k)[dim]) |
93 | { |
94 | for (size_t i = 0 ; i < dim ; i++) |
95 | {this->k[i] = k[i];} |
96 | } |
97 | |
98 | /*! \brief Constructor from buffer reference |
99 | * |
100 | * \param k reference buffer |
101 | * |
102 | */ |
103 | __device__ __host__ inline grid_key_dx(const unsigned short (&k)[dim]) |
104 | { |
105 | for (size_t i = 0 ; i < dim ; i++) |
106 | {this->k[i] = k[i];} |
107 | } |
108 | |
109 | /*! \brief Constructor from buffer reference |
110 | * |
111 | * \param k reference buffer |
112 | * |
113 | */ |
114 | __device__ __host__ inline grid_key_dx(const int (&k)[dim]) |
115 | { |
116 | for (size_t i = 0 ; i < dim ; i++) |
117 | {this->k[i] = k[i];} |
118 | } |
119 | |
120 | /*! \brief Constructor from buffer reference |
121 | * |
122 | * \param k reference buffer |
123 | * |
124 | */ |
125 | __device__ __host__ inline grid_key_dx(const unsigned int (&k)[dim]) |
126 | { |
127 | for (size_t i = 0 ; i < dim ; i++) |
128 | {this->k[i] = k[i];} |
129 | } |
130 | |
131 | /*! \brief Construct a grid key from a list of numbers |
132 | * |
133 | * \param cmb combination |
134 | * |
135 | */ |
136 | template<typename ...T> inline grid_key_dx(const comb<dim> & cmb) |
137 | { |
138 | for (size_t i = 0 ; i < dim ; i++) |
139 | k[i] = cmb[i]; |
140 | } |
141 | |
142 | /*! \brief Construct a grid key from a list of numbers |
143 | * |
144 | * \param v number |
145 | * \param t the other numbers |
146 | * |
147 | */ |
148 | template<typename ...T> __device__ __host__ inline grid_key_dx(const size_t v,const T...t) |
149 | { |
150 | #if defined(SE_CLASS1) && !defined(__NVCC__) |
151 | if (sizeof...(t) != dim -1) |
152 | {std::cerr << "Error grid_key: " << __FILE__ << " " << __LINE__ << " creating a key of dimension " << dim << " require " << dim << " numbers " << sizeof...(t) + 1 << " provided" << "\n" ;} |
153 | #endif |
154 | k[dim-1] = v; |
155 | invert_assign(t...); |
156 | } |
157 | |
158 | __device__ __host__ inline grid_key_dx<dim,index_type> move(int i, int m) const |
159 | { |
160 | grid_key_dx<dim,index_type> tmp = *this; |
161 | |
162 | tmp.k[i] += m; |
163 | |
164 | return tmp; |
165 | } |
166 | |
167 | /*! \brief Set to zero the key |
168 | * |
169 | */ |
170 | inline void zero() |
171 | { |
172 | for (size_t i = 0 ; i < dim ; i++) |
173 | k[i] = 0; |
174 | } |
175 | |
176 | /*! \brief Set to one the key |
177 | * |
178 | */ |
179 | inline void one() |
180 | { |
181 | for (size_t i = 0 ; i < dim ; i++) |
182 | k[i] = 1; |
183 | } |
184 | |
185 | /*! \brief Set to invalid the key |
186 | * |
187 | */ |
188 | inline void invalid() |
189 | { |
190 | for (size_t i = 0 ; i < dim ; i++) |
191 | k[i] = -1; |
192 | } |
193 | |
194 | /*! \brief Check if the key is invalid (all components set to -1) |
195 | * |
196 | * \return true if it is valid |
197 | * |
198 | */ |
199 | inline bool isValid() |
200 | { |
201 | for (size_t i = 0 ; i < dim ; i++) |
202 | { |
203 | if (k[i] != -1) |
204 | return true; |
205 | } |
206 | |
207 | return false; |
208 | } |
209 | |
210 | /*! \brief sum a grid_key |
211 | * |
212 | * \param p comb combination (or relative movement) |
213 | * |
214 | * \return a grid_key_dx_expression that encapsulate the expression |
215 | * |
216 | */ |
217 | __device__ __host__ |
218 | inline grid_key_dx<dim,index_type> & operator+=(const grid_key_dx<dim,index_type> & p) |
219 | { |
220 | for (size_t i = 0 ; i < dim ; i++) |
221 | k[i] += p.k[i]; |
222 | |
223 | return *this; |
224 | } |
225 | |
226 | /*! \brief sum a grid_key |
227 | * |
228 | * \param p comb combination (or relative movement) |
229 | * |
230 | * \return a grid_key_dx_expression that encapsulate the expression |
231 | * |
232 | */ |
233 | __device__ __host__ |
234 | inline grid_key_dx<dim,index_type> & operator-=(const grid_key_dx<dim,index_type> & p) |
235 | { |
236 | for (size_t i = 0 ; i < dim ; i++) |
237 | k[i] -= p.k[i]; |
238 | |
239 | return *this; |
240 | } |
241 | |
242 | /*! \brief sum a grid_key to the grid_key |
243 | * |
244 | * \param p grid_key to sum |
245 | * |
246 | * \return a grid_key_dx_expression that encapsulate the expression |
247 | * |
248 | */ |
249 | __device__ __host__ |
250 | inline grid_key_dx_sum<dim,grid_key_dx<dim,index_type>,grid_key_dx<dim,index_type>> |
251 | operator+(const grid_key_dx<dim,index_type> & p) const |
252 | { |
253 | grid_key_dx_sum<dim,grid_key_dx<dim,index_type>,grid_key_dx<dim,index_type>> exp_sum(*this,p); |
254 | |
255 | return exp_sum; |
256 | } |
257 | |
258 | /*! \brief sum a point to the grid_key |
259 | * |
260 | * \param p point (or relative movement) |
261 | * |
262 | * \return a grid_key_dx_expression that encapsulate the expression |
263 | * |
264 | */ |
265 | __device__ __host__ |
266 | inline grid_key_dx_sum<dim,grid_key_dx<dim>,Point<dim,long int>> |
267 | operator+(const Point<dim,long int> & p) const |
268 | { |
269 | grid_key_dx_sum<dim,grid_key_dx<dim>,Point<dim,long int>> exp_sum(*this,p); |
270 | |
271 | return exp_sum; |
272 | } |
273 | |
274 | /*! \brief sum an a combination to the grid_key |
275 | * |
276 | * \param cmb combination (or relative movement) |
277 | * |
278 | * \return a grid_key_dx_expression that encapsulate the expression |
279 | * |
280 | */ |
281 | __device__ __host__ |
282 | inline grid_key_dx_sum<dim,grid_key_dx<dim>,comb<dim>> operator+(const comb<dim> & cmb) const |
283 | { |
284 | grid_key_dx_sum<dim,grid_key_dx<dim>,comb<dim>> exp_sum(*this,cmb); |
285 | |
286 | return exp_sum; |
287 | } |
288 | |
289 | /*! \brief sum an a combination to the grid_key |
290 | * |
291 | * \param cmb combination (or relative movement) |
292 | * |
293 | * \return a grid_key_dx_expression that encapsulate the expression |
294 | * |
295 | */ |
296 | __device__ __host__ |
297 | inline grid_key_dx_sub<dim,grid_key_dx<dim,index_type>,grid_key_dx<dim,index_type>> |
298 | operator-(const grid_key_dx<dim,index_type> & cmb) const |
299 | { |
300 | grid_key_dx_sub<dim,grid_key_dx<dim,index_type>,grid_key_dx<dim,index_type>> exp_sum(*this,cmb); |
301 | |
302 | return exp_sum; |
303 | } |
304 | |
305 | /*! \brief sum this key to another grid expression |
306 | * |
307 | * \param cmb expression |
308 | * |
309 | * \return a grid_key_dx_expression that encapsulate the expression |
310 | * |
311 | */ |
312 | template <typename T> |
313 | __device__ __host__ inline grid_key_dx_sub<dim,grid_key_dx<dim,index_type>,grid_key_dx_expression<dim,T>> operator-(const grid_key_dx_expression<dim,T> & cmb) const |
314 | { |
315 | grid_key_dx_sub<dim,grid_key_dx<dim,index_type>,grid_key_dx_expression<dim,T>> exp_sum(*this,cmb); |
316 | |
317 | return exp_sum; |
318 | } |
319 | |
320 | /*! \brief Check if two key are the same |
321 | * |
322 | * \param key_t key to check |
323 | * |
324 | * \return true if the two key are equal |
325 | * |
326 | */ |
327 | template<unsigned int dim_t> bool operator==(const grid_key_dx<dim_t,index_type> & key_t) const |
328 | { |
329 | if (dim != dim_t) |
330 | { |
331 | return false; |
332 | } |
333 | |
334 | // Check the two key index by index |
335 | |
336 | for (size_t i = 0 ; i < dim ; i++) |
337 | { |
338 | if (k[i] != key_t.k[i]) |
339 | { |
340 | return false; |
341 | } |
342 | } |
343 | |
344 | // identical key |
345 | return true; |
346 | } |
347 | |
348 | |
349 | /*! \brief Check if two key are the same |
350 | * |
351 | * \param key_t key to check |
352 | * |
353 | * \return true if the two key are equal |
354 | * |
355 | */ |
356 | template<unsigned int dim_t> bool operator!=(const grid_key_dx<dim_t,index_type> & key_t) |
357 | { |
358 | return !this->operator==(key_t); |
359 | } |
360 | |
361 | /*! \brief Check order of two keys |
362 | * |
363 | * \param key_t key to check |
364 | * |
365 | * \return true if this is lexicographically less than other key |
366 | * |
367 | */ |
368 | bool operator<(const grid_key_dx<dim,index_type> & key_t) const |
369 | { |
370 | // Check the two key index by index |
371 | |
372 | for (long int i = dim-1 ; i >= 0; --i) |
373 | { |
374 | if (k[i] < key_t.k[i]) |
375 | { |
376 | return true; |
377 | } |
378 | else if (k[i] > key_t.k[i]) |
379 | { |
380 | return false; |
381 | } |
382 | } |
383 | |
384 | // identical key |
385 | return false; |
386 | } |
387 | |
388 | static bool noPointers() |
389 | { |
390 | return true; |
391 | } |
392 | |
393 | /*! \brief set the Key from a list of numbers |
394 | * |
395 | * \param v list of number |
396 | * \param t list of number |
397 | * |
398 | */ |
399 | template<typename a, typename ...T> |
400 | inline void set(a v, T...t) |
401 | { |
402 | #ifdef SE_CLASS1 |
403 | if (sizeof...(t) != dim -1) |
404 | std::cerr << "Error grid_key: " << __FILE__ << " " << __LINE__ << "setting a key of dimension " << dim << " require " << dim << " numbers " << sizeof...(t) + 1 << " provided" << std::endl; |
405 | #endif |
406 | k[dim-1] = v; |
407 | invert_assign(t...); |
408 | } |
409 | |
410 | /*! \brief Return the internal k structure |
411 | * |
412 | * \return k |
413 | * |
414 | */ |
415 | const long int(& get_k() const)[dim] |
416 | { |
417 | return k; |
418 | } |
419 | |
420 | /*! \brief Convert to a point the grid_key_dx |
421 | * |
422 | * \see toPoint |
423 | * |
424 | * \return a point long int |
425 | * |
426 | */ |
427 | Point<dim,long int> toPointS() const |
428 | { |
429 | Point<dim,long int> p; |
430 | |
431 | for (size_t i = 0; i < dim ; i++) |
432 | { |
433 | p.get(i) = get(i); |
434 | } |
435 | |
436 | return p; |
437 | } |
438 | |
439 | /*! \brief convert the information into a string |
440 | * |
441 | * \return a string |
442 | * |
443 | */ |
444 | std::string to_string() |
445 | { |
446 | return this->toPointS().toString(); |
447 | } |
448 | |
449 | /*! \brief Convert to a point the grid_key_dx |
450 | * |
451 | * \see toPointS |
452 | * |
453 | * \return a point unsigned long int |
454 | * |
455 | */ |
456 | template<typename typeT = size_t> |
457 | __host__ __device__ inline Point<dim,typeT> toPoint() const |
458 | { |
459 | Point<dim,typeT> p; |
460 | |
461 | for (size_t i = 0; i < dim ; i++) |
462 | { |
463 | p.get(i) = get(i); |
464 | } |
465 | |
466 | return p; |
467 | } |
468 | |
469 | |
470 | /*! \brief Get the i index |
471 | * |
472 | * \param i index to get |
473 | * |
474 | * \return the index value |
475 | * |
476 | */ |
477 | __device__ __host__ inline mem_id value(size_t i) const |
478 | { |
479 | return k[i]; |
480 | } |
481 | |
482 | /*! \brief Get the i index |
483 | * |
484 | * |
485 | * \param i index to get |
486 | * |
487 | * \return the index value |
488 | * |
489 | */ |
490 | __device__ __host__ index_type get(index_type i) const |
491 | { |
492 | return k[i]; |
493 | } |
494 | |
495 | /*! \brief Set the i index |
496 | * |
497 | * Set the i index |
498 | * |
499 | * \param i index to set |
500 | * \param id value to set |
501 | * |
502 | */ |
503 | __device__ __host__ void set_d(index_type i, index_type id) |
504 | { |
505 | #if defined(SE_CLASS1) && !defined(__NVCC__) |
506 | |
507 | if (i >= dim) |
508 | std::cerr << "grid_key_dx error: " << __FILE__ << " " << __LINE__ << " try to access dimension " << i << " on a grid_key_dx of size " << dim << "\n" ; |
509 | |
510 | #endif |
511 | k[i] = id; |
512 | } |
513 | |
514 | private: |
515 | |
516 | //! structure that store all the index |
517 | index_type k[dim]; |
518 | |
519 | /*! \brief Recursively invert the assignment |
520 | * |
521 | * Recursively invert the assignment at compile-time (hopefully) |
522 | * |
523 | * \param v list of numbers |
524 | * \param t list of numbers |
525 | * |
526 | */ |
527 | template<typename a, typename ...T> __device__ __host__ void invert_assign(a v,T...t) |
528 | { |
529 | k[sizeof...(T)] = v; |
530 | invert_assign(t...); |
531 | } |
532 | |
533 | /*! \brief assignment |
534 | * |
535 | * \param v list of number |
536 | * |
537 | */ |
538 | template<typename a, typename ...T> __device__ __host__ void invert_assign(a v) |
539 | { |
540 | k[0] = v; |
541 | } |
542 | |
543 | //! Constructor |
544 | __device__ __host__ void invert_assign() |
545 | { |
546 | } |
547 | |
548 | }; |
549 | |
550 | |
551 | /*! \brief grid_key_d is the key to access any element in the grid |
552 | * |
553 | * grid_key_d is the key to access any element in the grid |
554 | * |
555 | * \param dim dimensionality of the grid |
556 | * \param p object property to get from the element of the grid |
557 | * |
558 | */ |
559 | |
560 | template<unsigned int dim, unsigned int p> |
561 | class grid_key_d |
562 | { |
563 | public: |
564 | |
565 | |
566 | template<typename a, typename ...T>grid_key_d(a v,T...t) |
567 | { |
568 | k[dim-1] = v; |
569 | invert_assign(t...); |
570 | } |
571 | |
572 | template<typename a, typename ...T>void invert_assign(a v,T...t) |
573 | { |
574 | k[sizeof...(T)] = v; |
575 | invert_assign(t...); |
576 | } |
577 | |
578 | template<typename a, typename ...T>void invert_assign(a v) |
579 | { |
580 | k[0] = v; |
581 | } |
582 | |
583 | mem_id k[dim]; |
584 | }; |
585 | |
586 | |
587 | #endif |
588 | |