diff --git a/pvDataApp/factory/PVDataCreateFactory.cpp b/pvDataApp/factory/PVDataCreateFactory.cpp index baf1047..a3fe68b 100644 --- a/pvDataApp/factory/PVDataCreateFactory.cpp +++ b/pvDataApp/factory/PVDataCreateFactory.cpp @@ -28,6 +28,19 @@ using std::min; namespace epics { namespace pvData { +//template<> const ScalarType PVBoolean::typeCode = pvBoolean; +template<> const ScalarType PVByte::typeCode = pvByte; +template<> const ScalarType PVShort::typeCode = pvShort; +template<> const ScalarType PVInt::typeCode = pvInt; +template<> const ScalarType PVLong::typeCode = pvLong; +template<> const ScalarType PVUByte::typeCode = pvUByte; +template<> const ScalarType PVUShort::typeCode = pvUShort; +template<> const ScalarType PVUInt::typeCode = pvUInt; +template<> const ScalarType PVULong::typeCode = pvULong; +template<> const ScalarType PVFloat::typeCode = pvFloat; +template<> const ScalarType PVDouble::typeCode = pvDouble; +template<> const ScalarType PVScalarValue::typeCode = pvString; + /** Default storage for scalar values */ template diff --git a/pvDataApp/pv/pvData.h b/pvDataApp/pv/pvData.h index 45098ab..418bc43 100644 --- a/pvDataApp/pv/pvData.h +++ b/pvDataApp/pv/pvData.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace epics { namespace pvData { @@ -396,6 +397,41 @@ public: * @return the interface. */ const ScalarConstPtr getScalar() const ; + + /** + * Convert and return the scalar value in the requested type. + * Result type is determined from the function template argument + * which must be one of the ScalarType enums. + * Uses castUnsafe() for value conversion. + @code + PVScalar* pv = ...; + uint32 val = pv->getAs(); + @endcode + */ + template + inline typename ScalarTypeTraits::type getAs() const { + typename ScalarTypeTraits::type result; + this->getAs((void*)&result, ID); + return result; + } + virtual void getAs(void *, ScalarType) const = 0; + + /** + * Convert and assign the provided value. + * The value type is determined from the function template argument + * which must be one of the ScalarType enums. + * Uses castUnsafe() for value conversion. + @code + PVScalar* pv = ...; + pv->putFrom((int32)42); + @endcode + */ + template + inline void putFrom(typename ScalarTypeTraits::type val) { + this->putFrom((const void*)&val, ID); + } + virtual void putFrom(const void *, ScalarType) = 0; + protected: PVScalar(ScalarConstPtr const & scalar); }; @@ -410,6 +446,9 @@ public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; + + static const ScalarType typeCode; + /** * Destructor */ @@ -447,6 +486,18 @@ public: protected: PVScalarValue(ScalarConstPtr const & scalar) : PVScalar(scalar) {} + virtual void getAs(void * result, ScalarType rtype) const + { + const T src = get(); + castUnsafeV(1, rtype, result, typeCode, (const void*)&src); + } + virtual void putFrom(const void *src, ScalarType stype) + { + T result; + castUnsafeV(1, typeCode, (void*)&result, stype, src); + put(result); + } + private: friend class PVDataCreate; }; diff --git a/pvDataApp/pv/pvIntrospect.h b/pvDataApp/pv/pvIntrospect.h index defd954..9f3179d 100644 --- a/pvDataApp/pv/pvIntrospect.h +++ b/pvDataApp/pv/pvIntrospect.h @@ -555,5 +555,29 @@ private: */ extern FieldCreatePtr getFieldCreate(); +/** + * Static mapping from ScalarType enum to value type. + @code + typename ScalarTypeTraits::type value = 4; + @endcode + */ +template +struct ScalarTypeTraits {}; + +#define OP(ENUM, TYPE) template<> struct ScalarTypeTraits {typedef TYPE type;} +OP(pvBoolean, boolean); +OP(pvByte, int8); +OP(pvShort, int16); +OP(pvInt, int32); +OP(pvLong, int64); +OP(pvUByte, uint8); +OP(pvUShort, uint16); +OP(pvUInt, uint32); +OP(pvULong, uint64); +OP(pvFloat, float); +OP(pvDouble, double); +OP(pvString, String); +#undef OP + }} #endif /* PVINTROSPECT_H */