diff --git a/src/pv/pvData.h b/src/pv/pvData.h index 3f6e86d..f79f08b 100644 --- a/src/pv/pvData.h +++ b/src/pv/pvData.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -339,6 +340,8 @@ protected: virtual void getAs(void *, ScalarType) const = 0; public: + virtual void getAs(AnyScalar& v) const =0; + /** * Convert and assign the provided value. * The value type is determined from the function template argument @@ -357,6 +360,10 @@ public: //! Convert and assign virtual void putFrom(const void *, ScalarType) = 0; + inline void putFrom(const AnyScalar& v) { + if(v) + putFrom(v.unsafe(), v.type()); + } virtual void assign(const PVScalar&) = 0; @@ -459,6 +466,11 @@ public: put(castUnsafe(val)); } + FORCE_INLINE void putFrom(const AnyScalar& v) { + // the template form of putFrom() hides the base class AnyScalar overload + PVScalar::putFrom(v); + } + virtual void assign(const PVScalar& scalar) OVERRIDE { if(isImmutable()) @@ -492,6 +504,10 @@ protected: castUnsafeV(1, rtype, result, typeCode, (const void*)&src); } public: + virtual void getAs(AnyScalar& v) const + { + v = get(); + } virtual void putFrom(const void *src, ScalarType stype) OVERRIDE { T result; diff --git a/testApp/pv/testPVData.cpp b/testApp/pv/testPVData.cpp index b8f2410..49ef3c6 100644 --- a/testApp/pv/testPVData.cpp +++ b/testApp/pv/testPVData.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -626,6 +626,42 @@ static void testFieldAccess() } } +static void testAnyScalar() +{ + PVStructurePtr value(getPVDataCreate()->createPVStructure(getFieldCreate()->createFieldBuilder() + ->add("a", pvInt) + ->add("b", pvDouble) + ->add("c", pvString) + ->createStructure())); + + PVIntPtr a(value->getSubFieldT("a")); + PVDoublePtr b(value->getSubFieldT("b")); + PVStringPtr c(value->getSubFieldT("c")); + + a->put(42); + testEqual(a->get(), 42); + testEqual(b->get(), 0.0); + + { + AnyScalar temp; + a->getAs(temp); + b->putFrom(temp); + } + + testEqual(a->get(), 42); + testEqual(b->get(), 42.0); + testEqual(c->get(), ""); + + { + AnyScalar temp; + a->getAs(temp); + c->putFrom(temp); + } + + testEqual(a->get(), 42); + testEqual(c->get(), "42"); +} + static void testSubField() { PVStructurePtr value(ValueBuilder() @@ -678,7 +714,7 @@ static void testSubField() MAIN(testPVData) { - testPlan(251); + testPlan(258); try{ fieldCreate = getFieldCreate(); pvDataCreate = getPVDataCreate(); @@ -692,6 +728,7 @@ MAIN(testPVData) testRequest(); testCopy(); testFieldAccess(); + testAnyScalar(); testSubField(); }catch(std::exception& e){ PRINT_EXCEPTION(e);