#ifndef __ma_conversions_h__ #define __ma_conversions_h__ #include "multi_array.h" #include "slice.h" namespace MultiArrayTools { namespace ConversionSizes { template struct OrigSize { template struct FromTo { static void check() { static_assert( not N % (sizeof(T) / sizeof(C)), "conversion does not fit" ); } static constexpr size_t SIZE = N * sizeof(T) / sizeof(C); }; }; template <> struct OrigSize<-1> { template struct FromTo { static void check() {} static constexpr size_t SIZE = -1; }; }; } namespace { template using SC = typename ConversionSizes::OrigSize::template FromTo; template using SCR = SC; template using SCRR = GenSingleRange::SIZE>; } template struct SubTuple { template static inline auto mk(const RTP& rtp, const Ranges&... rs) -> decltype(SubTuple::mk(rtp, std::get(rtp), rs...)) { return SubTuple::mk(rtp, std::get(rtp), rs...); } }; template <> struct SubTuple<0> { template static inline auto mk(const RTP& rtp, const Ranges&... rs) -> decltype(std::make_tuple(std::get<0>(rtp), rs...)) { return std::make_tuple(std::get<0>(rtp), rs...); } }; template using LastR = typename std::tuple_element>::type; template auto rtcast(const std::tuple...>& rtp) -> decltype(std::tuple_cat(SubTuple::mk(rtp), std::make_tuple( std::dynamic_pointer_cast>> ( SCRR>::factory().create() ) ) )) { return std::tuple_cat(SubTuple::mk(rtp), std::make_tuple( std::dynamic_pointer_cast>> ( SCRR>::factory().create() ) ) ); } template inline Slice rangeTpToSlice( const std::tuple...>& rtp, T* data ) { return Slice(rtp, data); } template inline ConstSlice rangeTpToSlice( const std::tuple...>& rtp, const T* data ) { return ConstSlice(rtp, data); } template auto tcast(MultiArray& ma) -> decltype(rangeTpToSlice ( rtcast( ma.range()->space() ), reinterpret_cast( ma.data() ) )) { // VCHECK(reinterpret_cast(ma.data()) % 32); //VCHECK(reinterpret_cast(reinterpret_cast(ma.data())) % 32); return rangeTpToSlice ( rtcast( ma.range()->space() ), reinterpret_cast( ma.data() ) ); } template auto tcast(const MultiArray& ma) -> decltype(rangeTpToSlice ( rtcast( ma.range()->space() ), reinterpret_cast( ma.data() ) )) { //VCHECK(reinterpret_cast(ma.data()) % 32); //VCHECK(reinterpret_cast(reinterpret_cast(ma.data())) % 32); return rangeTpToSlice ( rtcast( ma.range()->space() ), reinterpret_cast( ma.data() ) ); } } #endif