namespace Internal { template<hh_u32 _FootprintInBytes> struct TNativeSwapper : public FalseType {}; template<> struct TNativeSwapper<1> : public TrueType { static void SwapInPlace(void *data, hh_u32 count) { } }; template<> struct TNativeSwapper<2> : public TrueType { static void SwapInPlace(void *data, hh_u32 count) { Mem::SwapEndian16(data, count); } }; template<> struct TNativeSwapper<4> : public TrueType { static void SwapInPlace(void *data, hh_u32 count) { Mem::SwapEndian32(data, count); } }; template<> struct TNativeSwapper<8> : public TrueType { static void SwapInPlace(void *data, hh_u32 count) { Mem::SwapEndian64(data, count); } }; template<typename _Type> struct TStreamEndianSwapperHelpers { static void SwapInPlace(_Type *data, hh_u32 count) { for (hh_u32 i = 0; i < count; i++) { PKSwapEndianInPlace(data\[i]); } } }; template<> struct TStreamEndianSwapperHelpers<hh_u8> { static void SwapInPlace(hh_u8 *data, hh_u32 count) { TNativeSwapper<sizeof(*data)>::SwapInPlace(data, count); } }; template<> struct TStreamEndianSwapperHelpers<hh_i8> { static void SwapInPlace(hh_i8 *data, hh_u32 count) { TNativeSwapper<sizeof(*data)>::SwapInPlace(data, count); } }; template<> struct TStreamEndianSwapperHelpers<hh_u16> { static void SwapInPlace(hh_u16 *data, hh_u32 count) { TNativeSwapper<sizeof(*data)>::SwapInPlace(data, count); } }; template<> struct TStreamEndianSwapperHelpers<hh_i16> { static void SwapInPlace(hh_i16 *data, hh_u32 count) { TNativeSwapper<sizeof(*data)>::SwapInPlace(data, count); } }; template<> struct TStreamEndianSwapperHelpers<hh_u32> { static void SwapInPlace(hh_u32 *data, hh_u32 count) { TNativeSwapper<sizeof(*data)>::SwapInPlace(data, count); } }; template<> struct TStreamEndianSwapperHelpers<hh_i32> { static void SwapInPlace(hh_i32 *data, hh_u32 count) { TNativeSwapper<sizeof(*data)>::SwapInPlace(data, count); } }; template<> struct TStreamEndianSwapperHelpers<float> { static void SwapInPlace(float *data, hh_u32 count) { TNativeSwapper<sizeof(*data)>::SwapInPlace(data, count); } }; } //---------------------------------------------------------------------------- template<typename _Type> void PKSwapEndianInPlace(const TMemoryView<_Type> &object) { Internal::TStreamEndianSwapperHelpers<_Type>::SwapInPlace(object.Data(), object.Count()); } //---------------------------------------------------------------------------- template<typename _Type, hh_i32 _FootprintInBytes> void PKSwapEndianInPlace(const TStridedMemoryView<_Type, _FootprintInBytes> &object) { if ((sizeof(_Type) == _FootprintInBytes || // compile-time culling : compact footprint _FootprintInBytes % sizeof(_Type) == 0) && // compile-time culling : footprint is a multiple of sizeof(_Type), we can reinterpret as a contiguous array of _Type objects and patch the count Internal::TNativeSwapper<sizeof(_Type)>::True && // we know how to endian-swap this type object.Stride() == _FootprintInBytes) { Internal::TStreamEndianSwapperHelpers<_Type>::SwapInPlace(object.Data(), object.Count() * (_FootprintInBytes / sizeof(_Type))); TMemoryView<_Type> contiguousView = object.ToMemoryViewIFP(); if (!contiguousView.Empty()) { PKSwapEndianInPlace(contiguousView); return; } } for (hh_u32 i = 0; i < object.Count(); i++) { PKSwapEndianInPlace(object\[i]); } }