Array-Impl.hpp
Go to the documentation of this file.
1 // This code is based on Jet framework.
2 // Copyright (c) 2018 Doyub Kim
3 // CubbyFlow is voxel-based fluid simulation engine for computer games.
4 // Copyright (c) 2020 CubbyFlow Team
5 // Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6 // AI Part: Dongheon Cho, Minseo Kim
7 // We are making my contributions/submissions to this project solely in our
8 // personal capacity and are not conveying any rights to any intellectual
9 // property of any third parties.
10 
11 #ifndef CUBBYFLOW_ARRAY_IMPL_HPP
12 #define CUBBYFLOW_ARRAY_IMPL_HPP
13 
15 
16 namespace CubbyFlow
17 {
18 template <typename T, size_t N>
19 class Array;
20 
21 namespace Internal
22 {
23 template <typename T, size_t N, size_t I>
25 {
26  template <typename... Args>
27  static void Call(Vector<size_t, N>& size, T& value, size_t n, Args... args)
28  {
29  size[N - I - 1] = n;
30 
31  GetSizeAndInitVal<T, N, I - 1>::Call(size, value, args...);
32  }
33 };
34 
35 template <typename T, size_t N>
36 struct GetSizeAndInitVal<T, N, 0>
37 {
38  static void Call(Vector<size_t, N>& size, T& value, size_t n)
39  {
40  Call(size, value, n, T{});
41  }
42 
43  static void Call(Vector<size_t, N>& size, T& value, size_t n,
44  const T& initVal)
45  {
46  size[N - 1] = n;
47  value = initVal;
48  }
49 };
50 
51 template <typename T, size_t N, size_t I>
53 {
54  static size_t Call(Vector<size_t, N>& size,
56  {
57  size[I - 1] = lst.size();
58 
59  size_t i = 0;
60 
61  for (auto subLst : lst)
62  {
63  if (i == 0)
64  {
66  }
67  else
68  {
69  Vector<size_t, N> tempSizeN;
70  [[maybe_unused]] size_t otherSize =
71  GetSizeFromInitList<T, N, I - 1>::Call(tempSizeN, subLst);
72 
73  assert(otherSize == tempSizeN[I - 2]);
74  }
75 
76  ++i;
77  }
78 
79  return size[I - 1];
80  }
81 };
82 
83 template <typename T, size_t N>
84 struct GetSizeFromInitList<T, N, 1>
85 {
86  static size_t Call(Vector<size_t, N>& size,
88  {
89  size[0] = lst.size();
90 
91  return size[0];
92  }
93 };
94 
95 template <typename T, size_t N, size_t I>
97 {
99  {
100  size_t i = 0;
101 
102  for (auto subLst : lst)
103  {
104  assert(i < arr.Size()[I - 1]);
105 
107 
108  ++i;
109  }
110  }
111 
112  template <typename... RemainingIndices>
114  RemainingIndices... indices)
115  {
116  size_t i = 0;
117 
118  for (auto subLst : lst)
119  {
120  assert(i < arr.Size()[I - 1]);
121 
122  SetArrayFromInitList<T, N, I - 1>::Call(arr, subLst, i, indices...);
123  ++i;
124  }
125  }
126 };
127 
128 template <typename T, size_t N>
129 struct SetArrayFromInitList<T, N, 1>
130 {
132  {
133  size_t i = 0;
134 
135  for (auto val : lst)
136  {
137  assert(i < arr.Size()[0]);
138 
139  arr(i) = val;
140  ++i;
141  }
142  }
143 
144  template <typename... RemainingIndices>
146  RemainingIndices... indices)
147  {
148  size_t i = 0;
149 
150  for (auto val : lst)
151  {
152  assert(i < arr.Size()[0]);
153 
154  arr(i, indices...) = val;
155  ++i;
156  }
157  }
158 };
159 } // namespace Internal
160 
161 template <typename T, size_t N>
163 {
164  // Do nothing
165 }
166 
167 template <typename T, size_t N>
168 Array<T, N>::Array(const Vector<size_t, N>& size_, const T& initVal) : Array()
169 {
170  m_data.resize(Product<size_t, N>(size_, 1), initVal);
171  Base::SetPtrAndSize(m_data.data(), size_);
172 }
173 
174 template <typename T, size_t N>
175 template <typename... Args>
176 Array<T, N>::Array(size_t nx, Args... args)
177 {
178  Vector<size_t, N> size;
179  T initVal;
180 
181  Internal::GetSizeAndInitVal<T, N, N - 1>::Call(size, initVal, nx, args...);
182  m_data.resize(Product<size_t, N>(size, 1), initVal);
183  Base::SetPtrAndSize(m_data.data(), size);
184 }
185 
186 template <typename T, size_t N>
188 {
189  Vector<size_t, N> newSize{};
190 
192  m_data.resize(Product<size_t, N>(newSize, 1));
193  Base::SetPtrAndSize(m_data.data(), newSize);
195 }
196 
197 template <typename T, size_t N>
198 template <typename OtherDerived>
200 {
201  CopyFrom(other);
202 }
203 
204 template <typename T, size_t N>
205 template <typename OtherDerived>
207 {
208  CopyFrom(other);
209 }
210 
211 template <typename T, size_t N>
212 Array<T, N>::Array(const Array& other) : Array()
213 {
214  CopyFrom(other);
215 }
216 
217 template <typename T, size_t N>
218 Array<T, N>::Array(Array&& other) noexcept : Array()
219 {
220  *this = std::move(other);
221 }
222 
223 template <typename T, size_t N>
225 {
226  CopyFrom(other);
227 
228  return *this;
229 }
230 
231 template <typename T, size_t N>
233 {
234  m_data = std::move(other.m_data);
235 
236  Base::SetPtrAndSize(other.data(), other.Size());
237  other.SetPtrAndSize(nullptr, Vector<size_t, N>{});
238 
239  return *this;
240 }
241 
242 template <typename T, size_t N>
243 template <typename OtherDerived>
245 {
246  CopyFrom(other);
247 
248  return *this;
249 }
250 
251 template <typename T, size_t N>
252 template <typename OtherDerived>
255 {
256  CopyFrom(other);
257 
258  return *this;
259 }
260 
261 template <typename T, size_t N>
262 template <typename D>
264 {
265  Resize(other.Size());
267  [&](auto... idx) { this->At(idx...) = other(idx...); });
268 }
269 
270 template <typename T, size_t N>
271 template <typename D>
273 {
274  Resize(other.Size());
276  [&](auto... idx) { this->At(idx...) = other(idx...); });
277 }
278 
279 template <typename T, size_t N>
280 void Array<T, N>::Fill(const T& val)
281 {
282  std::fill(m_data.begin(), m_data.end(), val);
283 }
284 
285 template <typename T, size_t N>
286 void Array<T, N>::Resize(Vector<size_t, N> size_, const T& initVal)
287 {
288  Array newArray(size_, initVal);
289  Vector<size_t, N> minSize = Min(m_size, newArray.m_size);
290 
291  ForEachIndex(minSize,
292  [&](auto... idx) { newArray(idx...) = (*this)(idx...); });
293 
294  *this = std::move(newArray);
295 }
296 
297 template <typename T, size_t N>
298 template <typename... Args>
299 void Array<T, N>::Resize(size_t nx, Args... args)
300 {
301  Vector<size_t, N> size;
302  T initVal;
303 
304  Internal::GetSizeAndInitVal<T, N, N - 1>::Call(size, initVal, nx, args...);
305 
306  Resize(size, initVal);
307 }
308 
309 template <typename T, size_t N>
310 template <size_t M>
311 std::enable_if_t<(M == 1), void> Array<T, N>::Append(const T& val)
312 {
313  m_data.push_back(val);
314 
315  Base::SetPtrAndSize(m_data.data(), m_data.size());
316 }
317 
318 template <typename T, size_t N>
319 template <typename OtherDerived, size_t M>
320 std::enable_if_t<(M == 1), void> Array<T, N>::Append(
321  const ArrayBase<T, N, OtherDerived>& extra)
322 {
323  m_data.insert(m_data.end(), extra.begin(), extra.end());
324 
325  Base::SetPtrAndSize(m_data.data(), m_data.size());
326 }
327 
328 template <typename T, size_t N>
329 template <typename OtherDerived, size_t M>
330 std::enable_if_t<(M == 1), void> Array<T, N>::Append(
332 {
333  m_data.insert(m_data.end(), extra.begin(), extra.end());
334 
335  Base::SetPtrAndSize(m_data.data(), m_data.size());
336 }
337 
338 template <typename T, size_t N>
340 {
341  Base::ClearPtrAndSize();
342 
343  m_data.clear();
344 }
345 
346 template <typename T, size_t N>
348 {
349  Base::SwapPtrAndSize(other);
350 
351  std::swap(m_data, other.m_data);
352 }
353 
354 template <typename T, size_t N>
356 {
357  return ArrayView<T, N>(*this);
358 }
359 
360 template <typename T, size_t N>
362 {
363  return ArrayView<const T, N>(*this);
364 }
365 } // namespace CubbyFlow
366 
367 #endif
static void Call(Array< T, N > &arr, NestedInitializerListsT< T, 1 > lst, RemainingIndices... indices)
Definition: Array-Impl.hpp:145
static size_t Call(Vector< size_t, N > &size, NestedInitializerListsT< T, I > lst)
Definition: Array-Impl.hpp:54
static void Call(Array< T, N > &arr, NestedInitializerListsT< T, I > lst, RemainingIndices... indices)
Definition: Array-Impl.hpp:113
Definition: ArrayBase.hpp:19
static size_t Call(Vector< size_t, N > &size, NestedInitializerListsT< T, 1 > lst)
Definition: Array-Impl.hpp:86
Definition: ArrayView.hpp:60
Array()
Definition: Array-Impl.hpp:162
Iterator end()
Definition: ArrayBase-Impl.hpp:102
Vector< size_t, N > m_size
Definition: ArrayBase.hpp:125
Definition: Array-Impl.hpp:52
Definition: Matrix.hpp:27
static void call(Array< T, N > &arr, NestedInitializerListsT< T, 1 > lst)
Definition: Array-Impl.hpp:131
Definition: pybind11Utils.hpp:20
void Fill(ArrayView< T, N > a, const Vector< size_t, N > &begin, const Vector< size_t, N > &end, const T &val)
Definition: ArrayUtils-Impl.hpp:19
static void Call(Vector< size_t, N > &size, T &value, size_t n)
Definition: Array-Impl.hpp:38
Definition: Array-Impl.hpp:19
Iterator begin()
Definition: ArrayBase-Impl.hpp:90
Definition: Array-Impl.hpp:96
static void Call(Vector< size_t, N > &size, T &value, size_t n, Args... args)
Definition: Array-Impl.hpp:27
constexpr auto Min(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition: MatrixExpression-Impl.hpp:1103
Definition: Array-Impl.hpp:24
Generic N-dimensional array class interface.
Definition: Array.hpp:32
typename NestedInitializerLists< T, N >::Type NestedInitializerListsT
Definition: NestedInitializerList.hpp:57
static void Call(Vector< size_t, N > &size, T &value, size_t n, const T &initVal)
Definition: Array-Impl.hpp:43
void ForEachIndex(const Vector< IndexType, N > &begin, const Vector< IndexType, N > &end, const Func &func)
Definition: IterationUtils-Impl.hpp:51
const Vector< size_t, N > & Size() const
Definition: ArrayBase-Impl.hpp:51
static void Call(Array< T, N > &arr, NestedInitializerListsT< T, I > lst)
Definition: Array-Impl.hpp:98