DIY 3.0 data-parallel out-of-core C++ library

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Examples

- File List

All Classes Namespaces Functions Typedefs Groups Pages
grid.hpp
1 #ifndef DIY_GRID_HPP
2 #define DIY_GRID_HPP
3
4 #include "point.hpp"
5
6 namespace diy
7 {
8
9 template<class C, unsigned D>
10 struct Grid;
11
12 template<class C, unsigned D>
13 struct GridRef
14 {
15 public:
16 typedef C Value;
17
18 typedef Point<int, D> Vertex;
19 typedef size_t Index;
20
21 public:
22 template<class Int>
23 GridRef(C* data, const Point<Int,D>& shape, bool c_order = true):
24 data_(data), shape_(shape), c_order_(c_order) { set_stride(); }
25
26 GridRef(Grid<C,D>& g):
27 data_(g.data()), shape_(g.shape()),
28 c_order_(g.c_order()) { set_stride(); }
29
30 template<class Int>
31 C operator()(const Point<Int, D>& v) const { return (*this)(index(v)); }
32
33 template<class Int>
34 C& operator()(const Point<Int, D>& v) { return (*this)(index(v)); }
35
36 C operator()(Index i) const { return data_[i]; }
37 C& operator()(Index i) { return data_[i]; }
38
39 const Vertex&
40 shape() const { return shape_; }
41
42 const C*
43 data() const { return data_; }
44 C* data() { return data_; }
45
46 // Set every element to the given value
47 GridRef& operator=(C value) { Index s = size(); for (Index i = 0; i < s; ++i) data_[i] = value; return *this; }
48 GridRef& operator/=(C value) { Index s = size(); for (Index i = 0; i < s; ++i) data_[i] /= value; return *this; }
49
50 Vertex vertex(Index idx) const { Vertex v; for (unsigned i = 0; i < D; ++i) { v[i] = idx / stride_[i]; idx %= stride_[i]; } return v; }
51 Index index(const Vertex& v) const { Index idx = 0; for (unsigned i = 0; i < D; ++i) { idx += ((Index) v[i]) * ((Index) stride_[i]); } return idx; }
52
53 Index size() const { return size(shape()); }
54 void swap(GridRef& other) { std::swap(data_, other.data_); std::swap(shape_, other.shape_); std::swap(stride_, other.stride_); std::swap(c_order_, other.c_order_); }
55
56 bool c_order() const { return c_order_; }
57
58 static constexpr
59 unsigned dimension() { return D; }
60
61 protected:
62 static Index
63 size(const Vertex& v) { Index res = 1; for (unsigned i = 0; i < D; ++i) res *= v[i]; return res; }
64
65 void set_stride()
66 {
67 Index cur = 1;
68 if (c_order_)
69 for (unsigned i = D; i > 0; --i) { stride_[i-1] = cur; cur *= shape_[i-1]; }
70 else
71 for (unsigned i = 0; i < D; ++i) { stride_[i] = cur; cur *= shape_[i]; }
72
73 }
74 void set_shape(const Vertex& v) { shape_ = v; set_stride(); }
75 void set_data(C* data) { data_ = data; }
76 void set_c_order(bool order) { c_order_ = order; }
77
78 private:
79 C* data_;
80 Vertex shape_;
81 Vertex stride_;
82 bool c_order_;
83 };
84
85
86 template<class C, unsigned D>
87 struct Grid: public GridRef<C,D>
88 {
89 public:
90 typedef GridRef<C,D> Parent;
91 typedef typename Parent::Value Value;
92 typedef typename Parent::Index Index;
93 typedef typename Parent::Vertex Vertex;
94 typedef Parent Reference;
95
96 template<class U>
97 struct rebind { typedef Grid<U,D> type; };
98
99 public:
100 Grid():
101 Parent(new C[0], Vertex::zero()) {}
102 template<class Int>
103 Grid(const Point<Int, D>& shape, bool c_order = true):
104 Parent(new C[size(shape)], shape, c_order)
105 {}
106
107 Grid(Grid&& g): Grid() { Parent::swap(g); }
108
109 Grid(const Parent& g):
110 Parent(new C[size(g.shape())], g.shape(),
111 g.c_order()) { copy_data(g.data()); }
112
113 template<class OtherGrid>
114 Grid(const OtherGrid& g):
115 Parent(new C[size(g.shape())],
116 g.shape(),
117 g.c_order()) { copy_data(g.data()); }
118
119 ~Grid() { delete[] Parent::data(); }
120
121 template<class OC>
122 Grid& operator=(const GridRef<OC, D>& other)
123 {
124 delete[] Parent::data();
125 Parent::set_c_order(other.c_order()); // NB: order needs to be set before the shape, to set the stride correctly
126 Parent::set_shape(other.shape());
127 Index s = size(shape());
128 Parent::set_data(new C[s]);
129 copy_data(other.data());
130 return *this;
131 }
132
133 Grid& operator=(Grid&& g) { Parent::swap(g); return *this; }
134
135 using Parent::data;
136 using Parent::shape;
137 using Parent::operator();
138 using Parent::operator=;
139 using Parent::size;
140
141 private:
142 template<class OC>
143 void copy_data(const OC* data)
144 {
145 Index s = size(shape());
146 for (Index i = 0; i < s; ++i)
147 Parent::data()[i] = data[i];
148 }
149 };
150
151 }
152
153 #endif
diy::GridRef
Definition: grid.hpp:13
diy::Grid
Definition: grid.hpp:10
diy::Grid::rebind
Definition: grid.hpp:97
diy::Point< int, D >