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>