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;
24template <
class T,
size_t N,
bool Reverse,
bool Const>
35template <
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();
167template <
class T,
size_t N,
bool Reverse = false,
bool Const = true>
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];
207 Reverse ? --ptr : ++ptr;
212 Reverse ? ++ptr : --ptr;
229 Reverse ? (ptr -= n) : (ptr += n);
234 Reverse ? (ptr += n) : (ptr -= n);
239 return Reverse ? rhs.
ptr - ptr : ptr - rhs.
ptr;
243 return Reverse ? ptr - rhs : ptr + rhs;
247 return Reverse ? ptr + rhs : ptr - rhs;
251 return Reverse ? rhs.
ptr < ptr : ptr < rhs.
ptr;
275 ERROR(F(
"Index out of bounds: ") << index << F(
" ≥ ") << N, 0xEDEF);
279 return *(array - index);
281 return *(array + index);
298 template <
size_t Start,
size_t End>
306template <
class T,
size_t N>
307template <
size_t Start,
size_t End>
310 static_assert(Start < N,
"");
311 static_assert(End < N,
"");
312 return &(*this)[Start];
315template <
class T,
size_t N>
316template <
size_t Start,
size_t End>
319 static_assert(Start < N,
"");
320 static_assert(End < N,
"");
321 return &(*this)[Start];
324template <
class T,
size_t N,
bool Reverse,
bool Const>
325template <
size_t Start,
size_t End>
328 static_assert(Start < N,
"");
329 static_assert(End < N,
"");
330 return &(*this)[Start];
334template <
class T,
size_t N,
bool Reverse,
bool Const>
345template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
346 bool Reverse2,
bool Const1,
bool Const2>
349 static_assert(N1 == N2,
"Error: sizes do not match");
350 for (
size_t i = 0; i < N1; ++i)
358template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse2,
bool Const2>
361 return a.
slice() == b;
366template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
bool Const1>
369 return a == b.
slice();
376template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
377 bool Reverse2,
bool Const1,
bool Const2>
385template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse2,
bool Const2>
388 return a.
slice() != b;
393template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
bool Const1>
396 return a != b.
slice();
403template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
404 bool Reverse2,
bool Const1,
bool Const2>
405Array<
decltype(T1{} + T2{}), N1>
408 static_assert(N1 == N2,
"Error: sizes do not match");
409 Array<
decltype(T1{} + T2{}), N1> result = {{}};
410 for (
size_t i = 0; i < N1; ++i)
411 result[i] = a[i] + b[i];
417template <
class T1,
class T2,
size_t N1,
size_t N2>
418Array<
decltype(T1{} + T2{}), N1>
operator+(
const Array<T1, N1> &a,
419 const Array<T2, N2> &b) {
420 return a.
slice() + b.slice();
425template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
426 bool Reverse2,
bool Const1,
bool Const2>
427const ArraySlice<T1, N1, Reverse1, Const1> &
430 static_assert(N1 == N2,
"Error: sizes do not match");
431 for (
size_t i = 0; i < N1; ++i)
438template <
class T1,
class T2,
size_t N1,
size_t N2>
448template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
449 bool Reverse2,
bool Const1,
bool Const2>
450Array<
decltype(T1{} - T2{}), N1>
453 static_assert(N1 == N2,
"Error: sizes do not match");
454 Array<
decltype(T1{} - T2{}), N1> result = {{}};
455 for (
size_t i = 0; i < N1; ++i)
456 result[i] = a[i] - b[i];
462template <
class T1,
class T2,
size_t N1,
size_t N2>
463Array<
decltype(T1{} - T2{}), N1>
operator-(
const Array<T1, N1> &a,
464 const Array<T2, N2> &b) {
465 return a.
slice() - b.slice();
470template <
class T1,
class T2,
size_t N1,
size_t N2,
bool Reverse1,
471 bool Reverse2,
bool Const1,
bool Const2>
472const ArraySlice<T1, N1, Reverse1, Const1> &
475 static_assert(N1 == N2,
"Error: sizes do not match");
476 for (
size_t i = 0; i < N1; ++i)
483template <
class T1,
class T2,
size_t N1,
size_t N2>
493template <
class T1,
class T2,
size_t N1,
bool Reverse1,
bool Const1>
494Array<
decltype(T1{} * T2{}), N1>
496 Array<
decltype(T1{} * T2{}), N1> result = {{}};
497 for (
size_t i = 0; i < N1; ++i)
498 result[i] = a[i] * b;
504template <
class T1,
class T2,
size_t N1>
505Array<
decltype(T1{} * T2{}), N1>
operator*(
const Array<T1, N1> &a, T2 b) {
506 return a.
slice() * b;
511template <
class T1,
class T2,
size_t N2,
bool Reverse2,
bool Const2>
512Array<
decltype(T1{} * T2{}), N2>
514 Array<
decltype(T1{} * T2{}), N2> result = {{}};
515 for (
size_t i = 0; i < N2; ++i)
516 result[i] = a * b[i];
522template <
class T1,
class T2,
size_t N2>
523Array<
decltype(T1{} * T2{}), N2>
operator*(T1 a,
const Array<T2, N2> &b) {
524 return a * b.
slice();
529template <
class T1,
class T2,
size_t N1,
bool Reverse1,
bool Const1>
530const ArraySlice<T1, N1, Reverse1, Const1> &
532 for (
size_t i = 0; i < N1; ++i)
539template <
class T1,
class T2,
size_t N1>
549template <
class T1,
class T2,
size_t N1,
bool Reverse1,
bool Const1>
550Array<
decltype(T1{} / T2{}), N1>
552 Array<
decltype(T1{} / T2{}), N1> result = {{}};
553 for (
size_t i = 0; i < N1; ++i)
554 result[i] = a[i] / b;
560template <
class T1,
class T2,
size_t N1>
561Array<
decltype(T1{} / T2{}), N1>
operator/(
const Array<T1, N1> &a, T2 b) {
562 return a.
slice() / b;
567template <
class T1,
class T2,
size_t N1,
bool Reverse1,
bool Const1>
568const ArraySlice<T1, N1, Reverse1, Const1> &
570 for (
size_t i = 0; i < N1; ++i)
577template <
class T1,
class T2,
size_t N1>
587template <
class T,
size_t N,
bool Reverse,
bool Const>
589 Array<
decltype(-T{}), N> result = {{}};
590 for (
size_t i = 0; i < N; ++i)
597template <
class T,
size_t N>
605template <
class T,
size_t NumRows,
size_t NumCols>
#define BEGIN_AH_NAMESPACE
#define AH_DIAGNOSTIC_POP()
#define AH_DIAGNOSTIC_WERROR()
bool operator!=(Iterator rhs) const
bool operator<=(Iterator rhs) const
Iterator & operator-=(difference_type n)
bool operator>=(Iterator rhs) const
reference operator[](difference_type n) const
difference_type operator-(Iterator rhs) const
Iterator(ElementPtrType ptr)
std::random_access_iterator_tag iterator_category
Iterator & operator+=(difference_type n)
Iterator operator-(difference_type rhs) const
bool operator==(Iterator rhs) const
bool operator<(Iterator rhs) const
reference operator*() const
Iterator operator+(difference_type rhs) const
std::ptrdiff_t difference_type
bool operator>(Iterator rhs) const
pointer operator->() const
Class for a view on a slice of an array.
ArraySlice(ElementPtrType array)
Constructor.
typename std::conditional< Const, const T &, T & >::type ElementRefType
typename std::conditional< Const, const T *, T * >::type ElementPtrType
ElementRefType operator[](size_t index) const
Get the element at the given index.
Array< T, N > asArray() const
Array< T1, N1 > & operator*=(Array< T1, N1 > &a, T2 b)
Array *= Scalar.
bool operator!=(ArraySlice< T1, N1, Reverse1, Const1 > a, ArraySlice< T2, N2, Reverse2, Const2 > b)
Slice != Slice.
const ArraySlice< T1, N1, Reverse1, Const1 > & operator+=(const ArraySlice< T1, N1, Reverse1, Const1 > &a, const ArraySlice< T2, N2, Reverse2, Const2 > &b)
Slice += Slice.
const ArraySlice< T1, N1, Reverse1, Const1 > & operator*=(const ArraySlice< T1, N1, Reverse1, Const1 > &a, T2 b)
Slice *= Scalar.
const ArraySlice< T1, N1, Reverse1, Const1 > & operator/=(const ArraySlice< T1, N1, Reverse1, Const1 > &a, T2 b)
Slice /= Scalar.
bool operator!=(const Array< T1, N1 > &a, ArraySlice< T2, N2, Reverse2, Const2 > b)
Array != Slice.
bool operator==(const Array< T1, N1 > &a, ArraySlice< T2, N2, Reverse2, Const2 > b)
Array == Slice.
Array< T1, N1 > & operator+=(Array< T1, N1 > &a, const Array< T2, N2 > &b)
Array += Array.
bool operator==(ArraySlice< T1, N1, Reverse1, Const1 > a, ArraySlice< T2, N2, Reverse2, Const2 > b)
Slice == Slice.
bool operator==(ArraySlice< T1, N1, Reverse1, Const1 > a, const Array< T2, N2 > &b)
Slice == Array.
const ArraySlice< T1, N1, Reverse1, Const1 > & operator-=(const ArraySlice< T1, N1, Reverse1, Const1 > &a, const ArraySlice< T2, N2, Reverse2, Const2 > &b)
Slice -= Slice.
ArraySlice< T, abs_diff(Start, End)+1,(End< Start), true > slice() const
Get a read-only view on a slice of the Array.
Array< T1, N1 > & operator/=(Array< T1, N1 > &a, T2 b)
Array /= Scalar.
bool operator!=(ArraySlice< T1, N1, Reverse1, Const1 > a, const Array< T2, N2 > &b)
Slice != Array.
Array< T1, N1 > & operator-=(Array< T1, N1 > &a, const Array< T2, N2 > &b)
Array -= Array.
ArraySlice< T, abs_diff(Start, End)+1,(End< Start), false > slice()
Get a view on a slice of the Array.
ArraySlice< T, N, Reverse, Const >::Iterator operator+(typename ArraySlice< T, N, Reverse, Const >::Iterator::difference_type n, typename ArraySlice< T, N, Reverse, Const >::Iterator a)
constexpr T abs_diff(const T &a, const T &b)
An array wrapper for easy copying, comparing, and iterating.
const T * end() const
Get a pointer to the memory beyond the array.
T & operator[](size_t index)
Get the element at the given index.
bool operator==(const Array< T, N > &rhs) const
Check the equality of all elements in two arrays.
bool operator!=(const Array< T, N > &rhs) const
Check the inequality of all elements in two arrays.
T * begin()
Get a pointer to the first element.
T * end()
Get a pointer to the memory beyond the array.
ArraySlice< T, abs_diff(Start, End)+1,(End< Start), true > cslice() const
Get a read-only view on a slice of the Array.
const T * begin() const
Get a pointer to the first element.
const T & operator[](size_t index) const
Get the element at the given index.