add PVScalar::getAs and PVScalar::putFrom

Allow get/put to a scalar without knowledge of ScalarType

Currently won't work correctly for PVBoolean
This commit is contained in:
Michael Davidsaver
2013-04-26 15:44:05 -04:00
parent c1b6d26b8e
commit 5e689f94f4
3 changed files with 88 additions and 0 deletions

View File

@@ -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<String>::typeCode = pvString;
/** Default storage for scalar values
*/
template<typename T>

View File

@@ -18,6 +18,7 @@
#include <iomanip>
#include <pv/pvIntrospect.h>
#include <pv/requester.h>
#include <pv/typeCast.h>
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<TO>() for value conversion.
@code
PVScalar* pv = ...;
uint32 val = pv->getAs<pvInt>();
@endcode
*/
template<ScalarType ID>
inline typename ScalarTypeTraits<ID>::type getAs() const {
typename ScalarTypeTraits<ID>::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<TO>() for value conversion.
@code
PVScalar* pv = ...;
pv->putFrom<pvInt>((int32)42);
@endcode
*/
template<ScalarType ID>
inline void putFrom(typename ScalarTypeTraits<ID>::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;
};

View File

@@ -555,5 +555,29 @@ private:
*/
extern FieldCreatePtr getFieldCreate();
/**
* Static mapping from ScalarType enum to value type.
@code
typename ScalarTypeTraits<pvByte>::type value = 4;
@endcode
*/
template<ScalarType ID>
struct ScalarTypeTraits {};
#define OP(ENUM, TYPE) template<> struct ScalarTypeTraits<ENUM> {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 */