diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2023-02-26 19:14:56 -0400 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2023-02-26 19:14:56 -0400 |
commit | 91a5937ef11f0503dde9d6f62e9d1f21e6f8a78f (patch) | |
tree | e49846c976c4a49e9b074afabaf61f4d64c06c53 /include | |
parent | b86a9a31e664cc4c5f1e7e3a55c0b131e5c1564b (diff) |
TArray: Add `TArray` template class
This is a convenience class, to make working with arrays alot easier,
but without hurting our chances of matching.
Diffstat (limited to 'include')
-rw-r--r-- | include/pso/TArray.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/include/pso/TArray.h b/include/pso/TArray.h new file mode 100644 index 0000000..fb7a903 --- /dev/null +++ b/include/pso/TArray.h @@ -0,0 +1,142 @@ +#ifndef TARRAY_H +#define TARRAY_H + +#include <global_types.h> +#include <string.h> +#include <pso/macros.h> + +template<typename T, size_t n> +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]; + }; + + template<typename T2> + T2 *as() { + return reinterpret_cast<T2 *>(m_data); + }; + + u8 *as_bytes() { + return reinterpret_cast<u8 *>(m_data); + }; + + void fill_with(u8 val) { + _fill_with<false>(val); + }; + + void fast_fill_with(u8 val) { + _fill_with<true>(val); + }; + + template<typename T2> + void copy(const T2 &val) { + _copy<T2, false>(val); + }; + + template<typename T2> + void copy_reverse(const T2 &val) { + _copy_reverse<T2, false>(val); + }; + + template<typename T2> + void fast_copy(const T2 &val) { + _copy<T2, true>(val); + }; + + template<typename T2> + void fast_copy_reverse(const T2 &val) { + _copy_reverse<T2, true>(val); + }; + +private: + template<bool do_unroll_check> + void _fill_with(u8 val) { + u8 *bytes = as_bytes(); + size_t size = byte_size(); + if (do_unroll_check && size <= 8) { + int i = 0; + switch (size) { + case 8: bytes[i++] = val; + case 7: bytes[i++] = val; + case 6: bytes[i++] = val; + case 5: bytes[i++] = val; + case 4: bytes[i++] = val; + case 3: bytes[i++] = val; + case 2: bytes[i++] = val; + case 1: bytes[i++] = val; + default: break; + } + } else { + for (int i = 0; i < size; ++i) { + bytes[i] = val; + } + } + }; + + template<typename T2, bool do_unroll_check> + void _copy(const T2 &val) { + size_t size = sizeof(T2)/sizeof(T); + const T *src = reinterpret_cast<const T *>(&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<typename T2, bool do_unroll_check> + void _copy_reverse(const T2 &val) { + size_t size = sizeof(T2)/sizeof(T); + const T *src = reinterpret_cast<const T *>(&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 |