fix shared_array::convertTo()

This commit is contained in:
Michael Davidsaver
2023-02-11 12:25:44 -08:00
parent 274133bcfc
commit e93909cf7e
2 changed files with 145 additions and 35 deletions
+110 -1
View File
@@ -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>();