9 #include <AH/Error/Error.hpp>
10 #include <AH/STL/iterator>
11 #include <AH/STL/type_traits>
18 return a < b ? b - a : a - b;
24 template <
class T,
size_t N,
bool Reverse,
bool Const>
35 template <
class T,
size_t N>
39 constexpr
static size_t length = N;
52 ERROR(
F(
"Index out of bounds: ") << index <<
F(
" ≥ ") << N, 0xEDED);
69 ERROR(
F(
"Index out of bounds: ") << index <<
F(
" ≥ ") << N, 0xEDED);
83 const T *
begin()
const {
return &data[0]; }
88 T *
end() {
return &data[N]; }
93 const T *
end()
const {
return &data[N]; }
104 for (
size_t i = 0; i < N; i++)
105 if ((*
this)[i] != rhs[i])
130 template <
size_t Start = 0,
size_t End = N - 1>
137 template <
size_t Start = 0,
size_t End = N - 1>
144 template <
size_t Start = 0,
size_t End = N - 1>
148 return This->
slice();
167 template <
class T,
size_t N,
bool Reverse = false,
bool Const = true>
169 using ElementRefType =
170 typename std::conditional<Const, const T &, T &>::type;
172 typename std::conditional<Const, const T *, T *>::type;
183 for (
size_t i = 0; i < N; ++i)
184 slice[i] = (*
this)[i];
204 Reverse ? --ptr : ++ptr;
209 Reverse ? ++ptr : --ptr;
214 return Reverse ? rhs.
ptr - ptr : ptr - rhs.
ptr;
218 return Reverse ? ptr - rhs : ptr + rhs;
222 return Reverse ? ptr + rhs : ptr - rhs;
226 return Reverse ? rhs.
ptr < ptr : ptr < rhs.
ptr;
244 ERROR(
F(
"Index out of bounds: ") << index <<
F(
" ≥ ") << N, 0xEDEF);
248 return array[-index];
267 template <
size_t Start,
size_t End>
275 template <
class T,
size_t N>
276 template <
size_t Start,
size_t End>
279 static_assert(Start < N,
"");
280 static_assert(End < N,
"");
281 return &(*this)[Start];
284 template <
class T,
size_t N>
285 template <
size_t Start,
size_t End>
286 inline ArraySlice<T,
abs_diff(Start, End) + 1, (End < Start), true>
287 Array<T, N>::slice()
const {
288 static_assert(Start < N,
"");
289 static_assert(End < N,
"");
290 return &(*this)[Start];
293 template <
class T,
size_t N,
bool Reverse,
bool Const>
294 template <
size_t Start,
size_t End>
295 ArraySlice<T,
abs_diff(End, Start) + 1, Reverse ^ (End < Start), Const>
296 ArraySlice<T, N, Reverse, Const>::slice()
const {
297 static_assert(Start < N,
"");
298 static_assert(End < N,
"");
299 return &(*this)[Start];
305 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
306 bool Reverse2,
bool Const1,
bool Const2>
309 static_assert(N1 == N2,
"Error: sizes do not match");
310 for (
size_t i = 0; i < N1; ++i)
317 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse2,
bool Const2>
320 return a.
slice() == b;
324 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
bool Const1>
327 return a == b.
slice();
333 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
334 bool Reverse2,
bool Const1,
bool Const2>
341 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse2,
bool Const2>
344 return a.
slice() != b;
348 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
bool Const1>
351 return a != b.
slice();
357 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
358 bool Reverse2,
bool Const1,
bool Const2>
359 Array<decltype(T1{} + T2{}), N1>
362 static_assert(N1 == N2,
"Error: sizes do not match");
363 Array<decltype(T1{} + T2{}), N1> result = {{}};
364 for (
size_t i = 0; i < N1; ++i)
365 result[i] = a[i] + b[i];
370 template <
class T1,
class T2,
size_t N1,
size_t N2>
371 Array<decltype(T1{} + T2{}), N1>
operator+(
const Array<T1, N1> &a,
372 const Array<T2, N2> &b) {
373 return a.
slice() + b.slice();
377 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
378 bool Reverse2,
bool Const1,
bool Const2>
379 const ArraySlice<T1, N1, Reverse1, Const1> &
382 static_assert(N1 == N2,
"Error: sizes do not match");
383 for (
size_t i = 0; i < N1; ++i)
389 template <
class T1,
class T2,
size_t N1,
size_t N2>
398 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
399 bool Reverse2,
bool Const1,
bool Const2>
400 Array<decltype(T1{} - T2{}), N1>
403 static_assert(N1 == N2,
"Error: sizes do not match");
404 Array<decltype(T1{} - T2{}), N1> result = {{}};
405 for (
size_t i = 0; i < N1; ++i)
406 result[i] = a[i] - b[i];
411 template <
class T1,
class T2,
size_t N1,
size_t N2>
412 Array<decltype(T1{} - T2{}), N1>
operator-(
const Array<T1, N1> &a,
413 const Array<T2, N2> &b) {
414 return a.
slice() - b.slice();
418 template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
419 bool Reverse2,
bool Const1,
bool Const2>
420 const ArraySlice<T1, N1, Reverse1, Const1> &
423 static_assert(N1 == N2,
"Error: sizes do not match");
424 for (
size_t i = 0; i < N1; ++i)
430 template <
class T1,
class T2,
size_t N1,
size_t N2>
439 template <
class T1,
class T2,
size_t N1,
bool Reverse1,
bool Const1>
440 Array<decltype(T1{} * T2{}), N1>
442 Array<decltype(T1{} * T2{}), N1> result = {{}};
443 for (
size_t i = 0; i < N1; ++i)
444 result[i] = a[i] * b;
449 template <
class T1,
class T2,
size_t N1>
450 Array<decltype(T1{} * T2{}), N1>
operator*(
const Array<T1, N1> &a, T2 b) {
451 return a.
slice() * b;
455 template <
class T1,
class T2,
size_t N2,
bool Reverse2,
bool Const2>
456 Array<decltype(T1{} * T2{}), N2>
458 Array<decltype(T1{} * T2{}), N2> result = {{}};
459 for (
size_t i = 0; i < N2; ++i)
460 result[i] = a * b[i];
465 template <
class T1,
class T2,
size_t N2>
466 Array<decltype(T1{} * T2{}), N2>
operator*(T1 a,
const Array<T2, N2> &b) {
467 return a * b.
slice();
471 template <
class T1,
class T2,
size_t N1,
bool Reverse1,
bool Const1>
472 const ArraySlice<T1, N1, Reverse1, Const1> &
474 for (
size_t i = 0; i < N1; ++i)
480 template <
class T1,
class T2,
size_t N1>
489 template <
class T1,
class T2,
size_t N1,
bool Reverse1,
bool Const1>
490 Array<decltype(T1{} / T2{}), N1>
492 Array<decltype(T1{} / T2{}), N1> result = {{}};
493 for (
size_t i = 0; i < N1; ++i)
494 result[i] = a[i] / b;
499 template <
class T1,
class T2,
size_t N1>
500 Array<decltype(T1{} / T2{}), N1>
operator/(
const Array<T1, N1> &a, T2 b) {
501 return a.
slice() / b;
505 template <
class T1,
class T2,
size_t N1,
bool Reverse1,
bool Const1>
506 const ArraySlice<T1, N1, Reverse1, Const1> &
508 for (
size_t i = 0; i < N1; ++i)
514 template <
class T1,
class T2,
size_t N1>
523 template <
class T,
size_t N,
bool Reverse,
bool Const>
524 Array<decltype(-T{}), N>
operator-(ArraySlice<T, N, Reverse, Const> a) {
525 Array<decltype(-T{}), N> result = {{}};
526 for (
size_t i = 0; i < N; ++i)
532 template <
class T,
size_t N>
533 Array<decltype(-T{}), N>
operator-(
const Array<T, N> &a) {
540 template <
class T,
size_t nb_rows,
size_t nb_cols>