diff --git a/src/utils/CastArray.hpp b/src/utils/CastArray.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0f9ec514549056c1b89195356cceaf396f001032 --- /dev/null +++ b/src/utils/CastArray.hpp @@ -0,0 +1,72 @@ +#ifndef CAST_ARRAY_HPP +#define CAST_ARRAY_HPP + +#include <Array.hpp> + +template <typename DataType, + typename CastDataType> +class CastArray +{ + private: + const Array<DataType> m_array; + const size_t m_size; + CastDataType* const m_values; + + public: + PASTIS_INLINE + const size_t& size() const + { + return m_size; + } + + PASTIS_INLINE + CastDataType& operator[](const size_t& i) const + { + Assert(i<m_size); + return m_values[i]; + } + + PASTIS_INLINE + CastArray(const Array<DataType>& array) + : m_array (array), + m_size (sizeof(DataType)*array.size()/sizeof(CastDataType)), + m_values((array.size() == 0) ? nullptr : reinterpret_cast<CastDataType*>(&(array[0]))) + { + static_assert((std::is_const_v<CastDataType> and std::is_const_v<DataType>) or + (not std::is_const_v<DataType>), "CastArray cannot remove const attribute"); + + if (sizeof(DataType)*array.size() % sizeof(CastDataType)) { + std::cerr << "cannot cast array to the chosen data type\n"; + std::exit(1); + } + } + + PASTIS_INLINE + CastArray(const CastArray&) = default; + + PASTIS_INLINE + CastArray(CastArray&&) = default; + + PASTIS_INLINE + CastArray& operator=(const CastArray&) = default; + + PASTIS_INLINE + CastArray& operator=(CastArray&&) = default; + + PASTIS_INLINE + ~CastArray() = default; +}; + +template <typename CastDataType> +struct cast_array_to +{ + template <typename DataType> + PASTIS_INLINE + static CastArray<DataType, CastDataType> + from(const Array<DataType>& array) + { + return CastArray<DataType, CastDataType>(array); + } +}; + +#endif // CAST_ARRAY_HPP