Skip to content
Snippets Groups Projects
Commit 55153065 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add conversion of Array<data_type> to an "Array<another_data_type>"

"Array<another_data_type>" is actually (CastArray<another_data_type>).  This is
in fact just a view which allow to access/modify original array's data
reinterpreting them to another type.

The only constrain w.r. to the type is that one must have
sizeof(data_type)*Array::size() == sizeof(other_data_type)*CastArray::size().

CastArray can be built thanks to the helper static function
cast_array_to<other_data_type>::from(given_array).

Usage: for instance, one writes:

Array<double> x(3); x[0]=1;x[1]=2;x[2]=3;
CastArray y = cast_array_to<int>::from(x);        // ok! y values can change
CastArray z = cast_array_to<const int>::from(x);  // ok! z values cannot change

Array<const double> cx = x;
CastArray cy = cast_array_to<int>::from(cx);      // invalid! cannot remove const
CastArray cz = cast_array_to<const int>::from(cx);// ok!

CastArray t = cast_array_to<TinyVector<4,int>>::from(x); // ok!

In last example, execution will fail (sizes are incompatible), but would success
if the size of x was a multiple of 2.

It is unclear if one should impose sizeof(other_data_type) <= sizeof(data_type)
parent 66c22f0f
No related branches found
No related tags found
1 merge request!11Feature/mpi
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment