PVUnion: get() const propagation, add guess(), and inline trival

This commit is contained in:
Michael Davidsaver
2017-09-30 13:18:04 -05:00
parent 406b163bcc
commit 9b1e789e62
6 changed files with 73 additions and 37 deletions

View File

@@ -271,7 +271,7 @@ bool compareField(const PVUnion* left, const PVUnion* right)
if (ls->isVariant())
{
PVFieldPtr lval = left->get();
const PVField::const_shared_pointer& lval = left->get();
if (lval.get() == 0)
return right->get().get() == 0;
else

View File

@@ -611,6 +611,44 @@ Union::Union (
Union::~Union() { }
int32 Union::guess(Type t, ScalarType s) const
{
if(t!=scalar && t!=scalarArray)
THROW_EXCEPTION2(std::logic_error, "PVUnion::guess() only support scalar and scalarArray");
int32 ret = -1;
for(size_t i=0, N=fields.size(); i<N; i++)
{
if(fields[i]->getType()!=t)
continue;
ScalarType type;
switch(fields[i]->getType()) {
case scalar:
type = static_cast<const Scalar*>(fields[i].get())->getScalarType();
break;
case scalarArray:
type = static_cast<const ScalarArray*>(fields[i].get())->getElementType();
break;
case structure:
case structureArray:
case union_:
case unionArray:
continue;
}
if(type==s) {
// exact match
ret = i;
break; // we're done
} else if(ret==-1) {
// first partial match
ret = i;
}
}
return ret;
}
string Union::getID() const
{

View File

@@ -40,24 +40,7 @@ PVUnion::PVUnion(UnionConstPtr const & unionPtr)
#undef PVUNION_UNDEFINED_INDEX
PVUnion::~PVUnion()
{
}
UnionConstPtr PVUnion::getUnion() const
{
return unionPtr;
}
PVFieldPtr PVUnion::get() const
{
return value;
}
int32 PVUnion::getSelectedIndex() const
{
return selector;
}
PVUnion::~PVUnion() {}
string PVUnion::getSelectedFieldName() const
{
@@ -100,11 +83,6 @@ PVFieldPtr PVUnion::select(string const & fieldName)
throw std::invalid_argument("no such fieldName");
return select(index);
}
void PVUnion::set(PVFieldPtr const & value)
{
set(selector, value);
}
void PVUnion::set(int32 index, PVFieldPtr const & value)
{
@@ -203,7 +181,7 @@ std::ostream& PVUnion::dumpValue(std::ostream& o) const
o << format::indent() << getUnion()->getID() << ' ' << getFieldName() << std::endl;
{
format::indent_scope s(o);
PVFieldPtr fieldField = get();
const PVField::const_shared_pointer& fieldField = get();
if (fieldField.get() == NULL)
o << format::indent() << "(none)" << std::endl;
else
@@ -232,7 +210,7 @@ void PVUnion::copy(const PVUnion& from)
void PVUnion::copyUnchecked(const PVUnion& from)
{
PVFieldPtr fromValue = from.get();
const PVField::const_shared_pointer& fromValue = from.get();
if (from.getUnion()->isVariant())
{
if (fromValue.get() == 0)

View File

@@ -130,7 +130,7 @@ void show_field(args& A, const pvd::PVField* fld)
case pvd::union_:
{
const pvd::PVUnion *U=static_cast<const pvd::PVUnion*>(fld);
pvd::PVFieldPtr C(U->get());
const pvd::PVField::const_shared_pointer& C(U->get());
if(!C) {
A.strm<<"null";

View File

@@ -959,19 +959,25 @@ public:
* Get the introspection interface
* @return The interface.
*/
UnionConstPtr getUnion() const;
inline const UnionConstPtr& getUnion() const { return unionPtr; }
/**
* Get the @c PVField value stored in the field.
* @return @c PVField value of field, @c null if {@code getSelectedIndex() == UNDEFINED_INDEX}.
*/
PVFieldPtr get() const;
inline const PVFieldPtr& get() { return value; }
inline PVField::const_shared_pointer get() const { return value; }
template<typename PVT>
std::tr1::shared_ptr<PVT> get() const {
inline std::tr1::shared_ptr<PVT> get() {
return std::tr1::dynamic_pointer_cast<PVT>(get());
}
template<typename PVT>
inline std::tr1::shared_ptr<const PVT> get() const {
return std::tr1::dynamic_pointer_cast<const PVT>(get());
}
/**
* Select field (set index) and get the field at the index.
* @param index index of the field to select.
@@ -981,7 +987,7 @@ public:
PVFieldPtr select(int32 index);
template<typename PVT>
std::tr1::shared_ptr<PVT> select(int32 index) {
inline std::tr1::shared_ptr<PVT> select(int32 index) {
return std::tr1::dynamic_pointer_cast<PVT>(select(index));
}
@@ -994,7 +1000,7 @@ public:
PVFieldPtr select(std::string const & fieldName);
template<typename PVT>
std::tr1::shared_ptr<PVT> select(std::string const & fieldName) {
inline std::tr1::shared_ptr<PVT> select(std::string const & fieldName) {
return std::tr1::dynamic_pointer_cast<PVT>(select(fieldName));
}
@@ -1002,21 +1008,23 @@ public:
* Get selected field index.
* @return selected field index.
*/
int32 getSelectedIndex() const;
inline int32 getSelectedIndex() const { return selector; }
/**
* Get selected field name.
* @return selected field name, empty string if field does not exist.
*/
std::string getSelectedFieldName() const;
/**
* Set the @c PVField (by reference!) as selected field.
* If a value is not a valid union field an @c std::invalid_argument
* exception is thrown.
* @param value the field to set.
*/
void set(PVFieldPtr const & value);
inline void set(PVFieldPtr const & value) {
set(selector, value);
}
/**
* Set the @c PVField (by reference!) as field at given index.
* If a value is not a valid union field an @c std::invalid_argument
@@ -1027,6 +1035,7 @@ public:
* @see #select(int32)
*/
void set(int32 index, PVFieldPtr const & value);
/**
* Set the @c PVField (by reference!) as field by given name.
* If a value is not a valid union field an @c std::invalid_argument
@@ -1067,7 +1076,7 @@ private:
static PVDataCreatePtr pvDataCreate;
friend class PVDataCreate;
UnionConstPtr unionPtr;
UnionConstPtr unionPtr; // same as PVField::getField()
int32 selector;
PVFieldPtr value;

View File

@@ -856,6 +856,17 @@ public:
*/
bool isVariant() const {return (fieldNames.size() == 0);}
/** Attempt to find an suitable member to stored the specified type.
*
* Returned index is guerenteed to by of specified Type (either scalar or scalarArray).
* Provided ScalarType is taken as a hint.
*
@param t Must be either scalar or scalarArray
@param s The preferred ScalarType
@returns A valid index or -1
*/
int32 guess(Type t, ScalarType s) const;
virtual std::string getID() const;
virtual std::ostream& dump(std::ostream& o) const;