diff --git a/src/factory/Compare.cpp b/src/factory/Compare.cpp index fe443cc..6f2fd3c 100644 --- a/src/factory/Compare.cpp +++ b/src/factory/Compare.cpp @@ -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 diff --git a/src/factory/FieldCreateFactory.cpp b/src/factory/FieldCreateFactory.cpp index 1d20323..ca53544 100644 --- a/src/factory/FieldCreateFactory.cpp +++ b/src/factory/FieldCreateFactory.cpp @@ -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(); igetType()!=t) + continue; + + ScalarType type; + switch(fields[i]->getType()) { + case scalar: + type = static_cast(fields[i].get())->getScalarType(); + break; + case scalarArray: + type = static_cast(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 { diff --git a/src/factory/PVUnion.cpp b/src/factory/PVUnion.cpp index bc6ae7c..5450dbe 100644 --- a/src/factory/PVUnion.cpp +++ b/src/factory/PVUnion.cpp @@ -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) diff --git a/src/json/print.cpp b/src/json/print.cpp index 1a9f450..e834473 100644 --- a/src/json/print.cpp +++ b/src/json/print.cpp @@ -130,7 +130,7 @@ void show_field(args& A, const pvd::PVField* fld) case pvd::union_: { const pvd::PVUnion *U=static_cast(fld); - pvd::PVFieldPtr C(U->get()); + const pvd::PVField::const_shared_pointer& C(U->get()); if(!C) { A.strm<<"null"; diff --git a/src/pv/pvData.h b/src/pv/pvData.h index 37e1e03..adc5ea3 100644 --- a/src/pv/pvData.h +++ b/src/pv/pvData.h @@ -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 - std::tr1::shared_ptr get() const { + inline std::tr1::shared_ptr get() { return std::tr1::dynamic_pointer_cast(get()); } - + + template + inline std::tr1::shared_ptr get() const { + return std::tr1::dynamic_pointer_cast(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 - std::tr1::shared_ptr select(int32 index) { + inline std::tr1::shared_ptr select(int32 index) { return std::tr1::dynamic_pointer_cast(select(index)); } @@ -994,7 +1000,7 @@ public: PVFieldPtr select(std::string const & fieldName); template - std::tr1::shared_ptr select(std::string const & fieldName) { + inline std::tr1::shared_ptr select(std::string const & fieldName) { return std::tr1::dynamic_pointer_cast(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; diff --git a/src/pv/pvIntrospect.h b/src/pv/pvIntrospect.h index be57a6e..36f92fd 100644 --- a/src/pv/pvIntrospect.h +++ b/src/pv/pvIntrospect.h @@ -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;