#ifndef TARRAY_H #define TARRAY_H #include #include #include template class TArray { public: T m_data[n]; public: T *data() { return m_data; }; size_t size() { return n; }; size_t byte_size() { return n * sizeof(T); }; T &operator[](size_t i) { return m_data[i]; }; T *start() { return m_data; }; T *end() { return &m_data[size()-1]; }; template T2 *as() { return reinterpret_cast(m_data); }; template size_t size_as() { return byte_size() / sizeof(T2); }; template TArray &to() { typedef TArray to_type; return reinterpret_cast(*this); }; u8 *as_bytes() { return reinterpret_cast(m_data); }; void fill(u8 val) { memset(m_data, val, byte_size()); }; template void fill_with(const T2 val) { _fill_with(val); }; template void fast_fill_with(const T2 val) { _fill_with(val); }; template void copy(const T2 &val) { _copy(val); }; template void copy_reverse(const T2 &val) { _copy_reverse(val); }; template void fast_copy(const T2 &val) { _copy(val); }; template void fast_copy_reverse(const T2 &val) { _copy_reverse(val); }; private: template void _fill_with(const T2 val) { T2 *data = as(); size_t size = size_as(); if (do_unroll_check && size <= 8) { int i = 0; switch (size) { case 8: data[i++] = val; case 7: data[i++] = val; case 6: data[i++] = val; case 5: data[i++] = val; case 4: data[i++] = val; case 3: data[i++] = val; case 2: data[i++] = val; case 1: data[i++] = val; default: break; } } else { for (int i = 0; i < size; ++i) { data[i] = val; } } }; template void _copy(const T2 &val) { size_t size = sizeof(T2)/sizeof(T); const T *src = reinterpret_cast(&val); if (do_unroll_check && size <= 8) { int i = 0; switch (size) { case 8: m_data[i] = src[i++]; case 7: m_data[i] = src[i++]; case 6: m_data[i] = src[i++]; case 5: m_data[i] = src[i++]; case 4: m_data[i] = src[i++]; case 3: m_data[i] = src[i++]; case 2: m_data[i] = src[i++]; case 1: m_data[i] = src[i++]; default: break; } } else { for (int i = 0; i < size; ++i) { m_data[i] = src[i]; } } }; template void _copy_reverse(const T2 &val) { size_t size = sizeof(T2)/sizeof(T); const T *src = reinterpret_cast(&val); if (do_unroll_check && size <= 8) { int i = size-1; int j = 0; switch (size) { case 8: m_data[i--] = src[j++]; case 7: m_data[i--] = src[j++]; case 6: m_data[i--] = src[j++]; case 5: m_data[i--] = src[j++]; case 4: m_data[i--] = src[j++]; case 3: m_data[i--] = src[j++]; case 2: m_data[i--] = src[j++]; case 1: m_data[i--] = src[j++]; default: break; } } else { for (int i = size-1, j = 0; i; --i, ++j) { m_data[i] = src[j]; } } }; }; #endif