Schnek
single-array-storage-base.hpp
1 /*
2  * single-array-storage-base.hpp
3  *
4  * Created on: 07 Nov 2022
5  * Author: Holger Schmitz
6  * Email: holger@notjustphysics.com
7  *
8  * Copyright 2012-2022 Holger Schmitz
9  *
10  * This file is part of Schnek.
11  *
12  * Schnek is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * Schnek is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with Schnek. If not, see <http://www.gnu.org/licenses/>.
24  *
25  */
26 
27 #ifndef SCHNEK_GRID_GRIDSTORAGE_SINGLESTORAGEBASE_HPP_
28 #define SCHNEK_GRID_GRIDSTORAGE_SINGLESTORAGEBASE_HPP_
29 
30 #include "../array.hpp"
31 
32 namespace schnek
33 {
41  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
42  class SingleArrayGridStorageBase : public AllocationPolicy<T, rank>
43  {
44  public:
47 
50  public:
53 
56 
62  ) = default;
63 
65  T *getRawData() const { return this->data->ptr; }
66 
68  SCHNEK_INLINE const IndexType &getLo() const { return this->range.getLo(); }
69 
71  SCHNEK_INLINE const IndexType &getHi() const { return this->range.getHi(); }
72 
74  SCHNEK_INLINE const RangeType &getRange() const { return this->range; }
75 
77  SCHNEK_INLINE const IndexType &getDims() const { return this->dims; }
78 
80  SCHNEK_INLINE int getLo(int k) const { return this->range.getLo(k); }
81 
83  SCHNEK_INLINE int getHi(int k) const { return this->range.getHi(k); }
84 
86  SCHNEK_INLINE int getDims(int k) const { return this->dims[k]; }
87 
89  SCHNEK_INLINE int getSize() const { return this->size; }
90 
91  typedef T* storage_iterator;
92  typedef const T* const_storage_iterator;
93 
94  SCHNEK_INLINE storage_iterator begin() { return this->data->ptr; }
95  SCHNEK_INLINE storage_iterator end() { return this->data->ptr + this->size; }
96 
97  SCHNEK_INLINE const_storage_iterator cbegin() const { return this->data->ptr; }
98  SCHNEK_INLINE const_storage_iterator cend() const { return this->data->ptr + this->size; }
99  };
100 
109  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
110  class SingleArrayGridCOrderStorageBase : public SingleArrayGridStorageBase<T, rank, AllocationPolicy>
111  {
112  private:
114  T *data_fast;
115  public:
118 
120  typedef typename BaseType::IndexType IndexType;
121 
123  typedef typename BaseType::RangeType RangeType;
124 
127 
130 
137  SingleArrayGridCOrderStorageBase(const IndexType &lo, const IndexType &hi);
138 
144  SingleArrayGridCOrderStorageBase(const RangeType &range);
145 
151  ) = default;
152 
159  SCHNEK_INLINE T &get(const IndexType &index);
160 
167  SCHNEK_INLINE const T &get(const IndexType &index) const;
168 
173  void resize(const IndexType &low, const IndexType &high);
174 
179  void resize(const RangeType range);
180 
184  ptrdiff_t stride(size_t dim) const;
185  private:
196  void updateDataFast();
197 
198  };
199 
208  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
209  class SingleArrayGridFortranOrderStorageBase : public SingleArrayGridStorageBase<T, rank, AllocationPolicy>
210  {
211  private:
213  T *data_fast;
214  public:
217 
219  typedef typename BaseType::IndexType IndexType;
220 
222  typedef typename BaseType::RangeType RangeType;
223 
226 
229 
236  SingleArrayGridFortranOrderStorageBase(const IndexType &lo, const IndexType &hi);
237 
243  SingleArrayGridFortranOrderStorageBase(const RangeType &range);
244 
250  ) = default;
251 
258  SCHNEK_INLINE T &get(const IndexType &index);
259 
266  SCHNEK_INLINE const T &get(const IndexType &index) const;
267 
272  void resize(const IndexType &low, const IndexType &high);
273 
278  void resize(const RangeType range);
279 
283  ptrdiff_t stride(size_t dim) const;
284  private:
285  void updateDataFast();
286  };
287 
288  //=================================================================
289  //================== SingleArrayGridStorageBase ===================
290  //=================================================================
291 
292  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
294  : AllocationPolicy<T, rank>()
295  {
296  }
297 
298  //=================================================================
299  //=============== SingleArrayGridCOrderStorageBase ================
300  //=================================================================
301 
302  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
304  : BaseType(), data_fast(NULL)
305  {
306  this->onUpdate([this](){ updateDataFast(); });
307  }
308 
309  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
311  : BaseType(other), data_fast(other.data_fast)
312  {
313  this->onUpdate([this](){ updateDataFast(); });
314  }
315 
316  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
318  const IndexType &lo,
319  const IndexType &hi
320  ) : BaseType(), data_fast(NULL)
321  {
322  this->onUpdate([this](){ updateDataFast(); });
323  resize(lo, hi);
324  }
325 
326  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
328  const RangeType &range
329  ) : BaseType(), data_fast(NULL)
330  {
331  this->onUpdate([this](){ updateDataFast(); });
332  resize(range.getLo(), range.getHi());
333  }
334 
335  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
337  {
338  size_t pos = index[0];
339  for (size_t i = 1; i < rank; ++i)
340  {
341  pos = index[i] + this->dims[i] * pos;
342  }
343  return this->data_fast[pos];
344  }
345 
346  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
348  {
349  size_t pos = index[0];
350  for (size_t i = 1; i < rank; ++i)
351  {
352  pos = index[i] + this->dims[i] * pos;
353  }
354  return this->data_fast[pos];
355  }
356 
357  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
359  {
360  this->resizeImpl(lo, hi);
361  // size_t p = -this->range.getLo(0);
362 
363  // for (size_t d = 1; d < rank; ++d)
364  // {
365  // p = p * this->dims[d] - this->getLo(d);
366  // }
367  // data_fast = this->data->ptr + p;
368  }
369 
370  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
372  {
373  this->resize(range.getLo(), range.getHi());
374  }
375 
376  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
378  {
379  size_t stride = 1;
380  for (size_t i = rank - 1; i > dim; --i)
381  {
382  stride *= this->dims[i];
383  }
384  return stride;
385  }
386 
387  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
389  {
390  ptrdiff_t p = -this->range.getLo(0);
391 
392  for (size_t d = 1; d < rank; ++d)
393  {
394  p = p * this->dims[d] - this->getLo(d);
395  }
396  data_fast = this->data->ptr + p;
397  }
398 
399  //=================================================================
400  //============ SingleArrayGridFortranOrderStorageBase =============
401  //=================================================================
402 
403  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
405  : BaseType(), data_fast(NULL)
406  {
407  this->onUpdate([this](){ updateDataFast(); });
408  }
409 
410  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
412  : BaseType(other), data_fast(other.data_fast)
413  {
414  this->onUpdate([this](){ updateDataFast(); });
415  }
416 
417  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
419  const IndexType &lo,
420  const IndexType &hi
421  ) : BaseType(), data_fast(NULL)
422  {
423  this->onUpdate([this](){ updateDataFast(); });
424  resize(lo, hi);
425  }
426 
427  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
429  const RangeType &range
430  ) : BaseType(), data_fast(NULL)
431  {
432  this->onUpdate([this](){ updateDataFast(); });
433  resize(range.getLo(), range.getHi());
434  }
435 
436  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
438  {
439  size_t pos = index[rank - 1];
440  for (ptrdiff_t i = ptrdiff_t(rank) - 2; i >= 0; --i)
441  {
442  pos = index[i] + this->dims[i] * pos;
443  }
444  return this->data_fast[pos];
445  }
446 
447  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
449  {
450  size_t pos = index[rank - 1];
451  for (ptrdiff_t i = ptrdiff_t(rank) - 2; i >= 0; --i)
452  {
453  pos = index[i] + this->dims[i] * pos;
454  }
455  return this->data_fast[pos];
456  }
457 
458  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
460  {
461  this->resizeImpl(lo, hi);
462  }
463 
464  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
466  {
467  this->resize(range.getLo(), range.getHi());
468  }
469 
470  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
472  {
473  ptrdiff_t stride = 1;
474  for (size_t i = 0; i < dim; ++i)
475  {
476  stride *= this->dims[i];
477  }
478  return stride;
479  }
480 
481  template <typename T, size_t rank, template <typename, size_t> class AllocationPolicy>
483  {
484  size_t p = -this->getLo(rank - 1);
485 
486  for (ptrdiff_t d = ptrdiff_t(rank) - 2; d >= 0; --d)
487  {
488  p = p * this->dims[d] - this->getLo(d);
489  }
490  data_fast = this->data->ptr + p;
491  }
492 
493 }
494 
495 #endif // SCHNEK_GRID_GRIDSTORAGE_SINGLESTORAGEBASE_HPP_
SCHNEK_INLINE const IndexType & getLo() const
Get the lowest coordinate in the grid (inclusive)
Definition: single-array-storage-base.hpp:68
SingleArrayGridStorageBase< T, rank, AllocationPolicy > BaseType
Base class type.
Definition: single-array-storage-base.hpp:216
SingleArrayGridStorageBase< T, rank, AllocationPolicy > BaseType
Base class type.
Definition: single-array-storage-base.hpp:117
BaseType::IndexType IndexType
The grid index type.
Definition: single-array-storage-base.hpp:120
BaseType::RangeType RangeType
The grid index type.
Definition: single-array-storage-base.hpp:222
SingleArrayGridStorageBase< T, rank, AllocationPolicy > & operator=(const SingleArrayGridStorageBase< T, rank, AllocationPolicy > &)=default
Assignment operator.
SCHNEK_INLINE T & get(const IndexType &index)
Get the lvalue at a given grid index.
Definition: single-array-storage-base.hpp:437
SCHNEK_INLINE const IndexType & getHi() const
Get the highest coordinate in the grid (inclusive)
Definition: single-array-storage-base.hpp:71
Array< int, rank > IndexType
The grid index type.
Definition: single-array-storage-base.hpp:46
void resize(const IndexType &low, const IndexType &high)
resizes to grid with lower indices lo[0],...,lo[rank-1] and upper indices hi[0],...,hi[rank-1]
Definition: single-array-storage-base.hpp:358
BaseType::IndexType IndexType
The grid index type.
Definition: single-array-storage-base.hpp:219
SCHNEK_INLINE int getDims(int k) const
Get k-th component of the dimensions of the grid dims = high - low + 1
Definition: single-array-storage-base.hpp:86
SingleArrayGridStorageBase()
Default constructor.
Definition: single-array-storage-base.hpp:293
T * getRawData() const
Access to the underlying raw data.
Definition: single-array-storage-base.hpp:65
SCHNEK_INLINE const LimitType & getLo() const
Return rectangle minimum.
Definition: range.hpp:74
SingleArrayGridFortranOrderStorageBase()
Default constructor.
Definition: single-array-storage-base.hpp:404
Extends from SingleArrayGridStorageBase to provide C-order indexing over the 1-dimensional data array...
Definition: single-array-storage-base.hpp:110
void resize(const IndexType &low, const IndexType &high)
resizes to grid with lower indices low[0],...,low[rank-1] and upper indices high[0],...,high[rank-1]
Definition: single-array-storage-base.hpp:459
Definition: algo.hpp:30
SCHNEK_INLINE int getHi(int k) const
Get k-th component of the highest coordinate in the grid (inclusive)
Definition: single-array-storage-base.hpp:83
SCHNEK_INLINE int getLo(int k) const
Get k-th component of the lowest coordinate in the grid (inclusive)
Definition: single-array-storage-base.hpp:80
ptrdiff_t stride(size_t dim) const
returns the stride of the specified dimension
Definition: single-array-storage-base.hpp:377
BaseType::RangeType RangeType
The grid index type.
Definition: single-array-storage-base.hpp:123
SCHNEK_INLINE T & get(const IndexType &index)
Get the lvalue at a given grid index.
Definition: single-array-storage-base.hpp:336
SCHNEK_INLINE const RangeType & getRange() const
Get the lowest coordinate in the grid (inclusive)
Definition: single-array-storage-base.hpp:74
SingleArrayGridCOrderStorageBase()
Default constructor.
Definition: single-array-storage-base.hpp:303
Range< int, rank > RangeType
The grid range type.
Definition: single-array-storage-base.hpp:49
The storage base extends from an allocation policy and adds some accessor methods.
Definition: single-array-storage-base.hpp:42
SCHNEK_INLINE const IndexType & getDims() const
Get the dimensions of the grid dims = high - low + 1
Definition: single-array-storage-base.hpp:77
SCHNEK_INLINE int getSize() const
Get the length of the allocated array.
Definition: single-array-storage-base.hpp:89
Extends from SingleArrayGridStorageBase to provide Fortran-order indexing over the 1-dimensional data...
Definition: single-array-storage-base.hpp:209
ptrdiff_t stride(size_t dim) const
returns the stride of the specified dimension
Definition: single-array-storage-base.hpp:471
SCHNEK_INLINE const LimitType & getHi() const
Return rectangle maximum.
Definition: range.hpp:76