fix shared_array::convertTo()
This commit is contained in:
+35
-34
@@ -263,13 +263,14 @@ void convertArr(ArrayType dtype, void *dbase,
|
||||
case ArrayType::Bool: convertCast<int8_t, bool>(sbase, dbase, count); return;
|
||||
case ArrayType::Int8:
|
||||
case ArrayType::UInt8: memcpy(dbase, sbase, count*sizeof(int8_t)); return;
|
||||
// cast sint -> *int always sign extends
|
||||
case ArrayType::Int16:
|
||||
case ArrayType::UInt16: convertCast<int8_t, int16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int32:
|
||||
case ArrayType::UInt32: convertCast<int8_t, int32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64:
|
||||
case ArrayType::UInt64: convertCast<int8_t, int64_t>(sbase, dbase, count); return;
|
||||
// cast sint -> sint extends sign
|
||||
case ArrayType::Int16: convertCast<int8_t, int16_t>(sbase, dbase, count); return;
|
||||
// cast sint -> uint does not extend sign
|
||||
case ArrayType::UInt16: convertCast<int8_t, uint16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int32: convertCast<int8_t, int32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt32: convertCast<int8_t, uint32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64: convertCast<int8_t, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt64: convertCast<int8_t, uint64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Float32:convertCast<int8_t, float>(sbase, dbase, count); return;
|
||||
case ArrayType::Float64:convertCast<int8_t, double>(sbase, dbase, count); return;
|
||||
case ArrayType::String: convertToStr<int8_t>(sbase, dbase, count); return;
|
||||
@@ -281,13 +282,13 @@ void convertArr(ArrayType dtype, void *dbase,
|
||||
switch(dtype) {
|
||||
case ArrayType::Bool: convertCast<int16_t, bool>(sbase, dbase, count); return;
|
||||
case ArrayType::Int8:
|
||||
case ArrayType::UInt8: convertCast<int16_t, int8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt8: convertCast<uint16_t, uint8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int16:
|
||||
case ArrayType::UInt16: memcpy(dbase, sbase, count*sizeof(int16_t)); return;
|
||||
case ArrayType::Int32:
|
||||
case ArrayType::UInt32: convertCast<int16_t, int32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64:
|
||||
case ArrayType::UInt64: convertCast<int16_t, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int32: convertCast<int16_t, int32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt32: convertCast<int16_t, uint32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64: convertCast<int16_t, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt64: convertCast<int16_t, uint64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Float32:convertCast<int16_t, float>(sbase, dbase, count); return;
|
||||
case ArrayType::Float64:convertCast<int16_t, double>(sbase, dbase, count); return;
|
||||
case ArrayType::String: convertToStr<int16_t>(sbase, dbase, count); return;
|
||||
@@ -299,13 +300,13 @@ void convertArr(ArrayType dtype, void *dbase,
|
||||
switch(dtype) {
|
||||
case ArrayType::Bool: convertCast<int32_t, bool>(sbase, dbase, count); return;
|
||||
case ArrayType::Int8:
|
||||
case ArrayType::UInt8: convertCast<int32_t, int8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt8: convertCast<uint32_t, uint8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int16:
|
||||
case ArrayType::UInt16: convertCast<int32_t, int16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt16: convertCast<uint32_t, uint16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int32:
|
||||
case ArrayType::UInt32: memcpy(dbase, sbase, count*sizeof(int32_t)); return;
|
||||
case ArrayType::Int64:
|
||||
case ArrayType::UInt64: convertCast<int32_t, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64: convertCast<int32_t, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt64: convertCast<int32_t, uint64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Float32:convertCast<int32_t, float>(sbase, dbase, count); return;
|
||||
case ArrayType::Float64:convertCast<int32_t, double>(sbase, dbase, count); return;
|
||||
case ArrayType::String: convertToStr<int32_t>(sbase, dbase, count); return;
|
||||
@@ -407,14 +408,14 @@ void convertArr(ArrayType dtype, void *dbase,
|
||||
case ArrayType::Float32:
|
||||
switch(dtype) {
|
||||
case ArrayType::Bool: convertCast<float, bool>(sbase, dbase, count); return;
|
||||
case ArrayType::Int8:
|
||||
case ArrayType::UInt8: convertCast<float, int8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int16:
|
||||
case ArrayType::UInt16: convertCast<float, int16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int32:
|
||||
case ArrayType::UInt32: convertCast<float, int32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64:
|
||||
case ArrayType::UInt64: convertCast<float, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int8: convertCast<float, int8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt8: convertCast<float, uint8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int16: convertCast<float, int16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt16: convertCast<float, uint16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int32: convertCast<float, int32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt32: convertCast<float, uint32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64: convertCast<float, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt64: convertCast<float, uint64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Float32:memcpy(dbase, sbase, count*sizeof(float)); return;
|
||||
case ArrayType::Float64:convertCast<float, double>(sbase, dbase, count); return;
|
||||
case ArrayType::String: convertToStr<float>(sbase, dbase, count); return;
|
||||
@@ -425,16 +426,16 @@ void convertArr(ArrayType dtype, void *dbase,
|
||||
case ArrayType::Float64:
|
||||
switch(dtype) {
|
||||
case ArrayType::Bool: convertCast<double, bool>(sbase, dbase, count); return;
|
||||
case ArrayType::Int8:
|
||||
case ArrayType::UInt8: convertCast<double, int8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int16:
|
||||
case ArrayType::UInt16: convertCast<double, int16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int32:
|
||||
case ArrayType::UInt32: convertCast<double, int32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64:
|
||||
case ArrayType::UInt64: convertCast<double, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Float32:memcpy(dbase, sbase, count*sizeof(double)); return;
|
||||
case ArrayType::Float64:convertCast<double, double>(sbase, dbase, count); return;
|
||||
case ArrayType::Int8: convertCast<double, int8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt8: convertCast<double, uint8_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int16: convertCast<double, int16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt16: convertCast<double, uint16_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int32: convertCast<double, int32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt32: convertCast<double, uint32_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Int64: convertCast<double, int64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::UInt64: convertCast<double, uint64_t>(sbase, dbase, count); return;
|
||||
case ArrayType::Float32:convertCast<double, float>(sbase, dbase, count); return;
|
||||
case ArrayType::Float64:memcpy(dbase, sbase, count*sizeof(double)); return;
|
||||
case ArrayType::String: convertToStr<double>(sbase, dbase, count); return;
|
||||
case ArrayType::Value:
|
||||
case ArrayType::Null: break; // no convert
|
||||
|
||||
+110
-1
@@ -7,6 +7,7 @@
|
||||
#include <typeinfo>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
#include <pvxs/sharedArray.h>
|
||||
#include <pvxs/data.h>
|
||||
@@ -324,12 +325,120 @@ void testElemAlloc()
|
||||
testEq(varr.original_type(), ArrayType::UInt32);
|
||||
}
|
||||
|
||||
// round trip conversion when TO can exactly represent all possible values of FROM
|
||||
template<typename FROM, typename TO>
|
||||
void testConvertExact()
|
||||
{
|
||||
shared_array<const FROM> inp({
|
||||
FROM(0),
|
||||
FROM(1),
|
||||
FROM(-1),
|
||||
std::numeric_limits<FROM>::min(),
|
||||
std::numeric_limits<FROM>::max(),
|
||||
});
|
||||
shared_array<const TO> expect({
|
||||
(TO)FROM(0),
|
||||
(TO)FROM(1),
|
||||
(TO)FROM(-1),
|
||||
(TO)std::numeric_limits<FROM>::min(),
|
||||
(TO)std::numeric_limits<FROM>::max(),
|
||||
});
|
||||
auto conv(inp.template convertTo<const TO>());
|
||||
testShow()<<"Input "<<inp;
|
||||
testArrEq(conv, expect)<<" "<<__func__<<"("<<typeid(FROM).name()<<" -> "<<typeid(TO).name()<<")";
|
||||
testArrEq(expect.template convertTo<const FROM>(), inp)<<" "<<__func__<<"("<<typeid(FROM).name()<<" <- "<<typeid(TO).name()<<")";
|
||||
}
|
||||
|
||||
// conversion based on truncation of unsigned integer
|
||||
template<typename FROM, typename TO>
|
||||
void testConvertTrunc()
|
||||
{
|
||||
shared_array<const FROM> inp({
|
||||
FROM(0),
|
||||
FROM(1),
|
||||
FROM(-1),
|
||||
std::numeric_limits<FROM>::min(),
|
||||
std::numeric_limits<FROM>::max(),
|
||||
});
|
||||
shared_array<const TO> expect({
|
||||
(TO)FROM(0),
|
||||
(TO)FROM(1),
|
||||
(TO)FROM(-1),
|
||||
std::numeric_limits<TO>::min(),
|
||||
std::numeric_limits<TO>::max(),
|
||||
});
|
||||
auto conv(inp.template convertTo<const TO>());
|
||||
testShow()<<"Input "<<inp;
|
||||
testArrEq(conv, expect)<<" "<<__func__<<"("<<typeid(FROM).name()<<" -> "<<typeid(TO).name()<<")";
|
||||
}
|
||||
|
||||
void testConvert()
|
||||
{
|
||||
testDiag("%s", __func__);
|
||||
|
||||
static_assert (detail::CaptureCode<uint32_t>::code!=detail::CaptureCode<uint16_t>::code, "");
|
||||
|
||||
testDiag("reversible conversions");
|
||||
testConvertExact<uint8_t, uint8_t>();
|
||||
testConvertExact<uint8_t, int16_t>();
|
||||
testConvertExact<uint8_t, uint16_t>();
|
||||
testConvertExact<uint8_t, int32_t>();
|
||||
testConvertExact<uint8_t, uint32_t>();
|
||||
testConvertExact<uint8_t, int64_t>();
|
||||
testConvertExact<uint8_t, uint64_t>();
|
||||
testConvertExact<uint8_t, float>();
|
||||
testConvertExact<uint8_t, double>();
|
||||
|
||||
testConvertExact<int8_t, int8_t>();
|
||||
testConvertExact<int8_t, int16_t>();
|
||||
testConvertExact<int8_t, uint16_t>();
|
||||
testConvertExact<int8_t, int32_t>();
|
||||
testConvertExact<int8_t, uint32_t>();
|
||||
testConvertExact<int8_t, int64_t>();
|
||||
testConvertExact<int8_t, uint64_t>();
|
||||
testConvertExact<int8_t, float>();
|
||||
testConvertExact<int8_t, double>();
|
||||
|
||||
testConvertExact<uint16_t, uint16_t>();
|
||||
testConvertExact<uint16_t, int32_t>();
|
||||
testConvertExact<uint16_t, uint32_t>();
|
||||
testConvertExact<uint16_t, int64_t>();
|
||||
testConvertExact<uint16_t, uint64_t>();
|
||||
testConvertExact<uint16_t, float>();
|
||||
testConvertExact<uint16_t, double>();
|
||||
|
||||
testConvertExact<int16_t, int16_t>();
|
||||
testConvertExact<int16_t, int32_t>();
|
||||
testConvertExact<int16_t, uint32_t>();
|
||||
testConvertExact<int16_t, int64_t>();
|
||||
testConvertExact<int16_t, uint64_t>();
|
||||
testConvertExact<int16_t, float>();
|
||||
testConvertExact<int16_t, double>();
|
||||
|
||||
testConvertExact<uint32_t, uint32_t>();
|
||||
testConvertExact<uint32_t, int64_t>();
|
||||
testConvertExact<uint32_t, uint64_t>();
|
||||
testConvertExact<uint32_t, double>();
|
||||
|
||||
testConvertExact<int32_t, int32_t>();
|
||||
testConvertExact<int32_t, int64_t>();
|
||||
testConvertExact<int32_t, uint64_t>();
|
||||
testConvertExact<int32_t, double>();
|
||||
|
||||
testConvertExact<uint64_t, uint64_t>();
|
||||
|
||||
testConvertExact<int64_t, int64_t>();
|
||||
|
||||
testConvertExact<float, double>();
|
||||
|
||||
testDiag("integer truncation");
|
||||
testConvertTrunc<uint16_t, uint8_t>();
|
||||
testConvertTrunc<uint32_t, uint8_t>();
|
||||
testConvertTrunc<uint64_t, uint8_t>();
|
||||
testConvertTrunc<uint32_t, uint16_t>();
|
||||
testConvertTrunc<uint64_t, uint16_t>();
|
||||
testConvertTrunc<uint64_t, uint32_t>();
|
||||
|
||||
testArrEq(shared_array<uint32_t>({1u, 2u, 0xffffffffu}).convertTo<uint32_t>(),
|
||||
shared_array<uint32_t>({1u, 2u, 0xffffffffu}));
|
||||
|
||||
@@ -356,7 +465,7 @@ void testConvert()
|
||||
|
||||
MAIN(testshared)
|
||||
{
|
||||
testPlan(155);
|
||||
testPlan(247);
|
||||
testSetup();
|
||||
testEmpty<void>();
|
||||
testEmpty<const void>();
|
||||
|
||||
Reference in New Issue
Block a user