From ac2b6ea8dbdf1f74cf2392534b919710eb21bdbc Mon Sep 17 00:00:00 2001 From: Dave Hickin Date: Mon, 13 Jul 2015 12:48:05 +0100 Subject: [PATCH] Make getSubFieldT return shared pointer Signed-off-by: Dave Hickin --- documentation/pvDataCPP.html | 8 +++---- documentation/pvDataCPP_20150623.html | 8 +++---- src/factory/PVStructure.cpp | 8 +++---- src/pv/pvData.h | 31 +++++++++++++++------------ testApp/pv/testPVData.cpp | 8 +++---- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html index 89541be..53902c0 100644 --- a/documentation/pvDataCPP.html +++ b/documentation/pvDataCPP.html @@ -2309,15 +2309,15 @@ public: template<typename PVT> std::tr1::shared_ptr<PVT> getSubField(std::size_t fieldOffset) const - PVField& getSubFieldT(std::string const &fieldName) const; + PVFieldPtr getSubFieldT(std::string const &fieldName) const; template<typename PVT> - PVT& getSubFieldT(std::string const &fieldName) const + std::tr1::shared_ptr<PVT> getSubFieldT(std::string const &fieldName) const - PVField& getSubFieldT(std::size_t fieldOffset) const; + PVFieldPtr getSubFieldT(std::size_t fieldOffset) const; template<typename PVT> - PVT& getSubFieldT(std::size_t fieldOffset) const + std::tr1::shared_ptr<PVT> getSubFieldT(std::size_t fieldOffset) const virtual void serialize( ByteBuffer *pbuffer,SerializableControl *pflusher) const ; diff --git a/documentation/pvDataCPP_20150623.html b/documentation/pvDataCPP_20150623.html index 89541be..53902c0 100644 --- a/documentation/pvDataCPP_20150623.html +++ b/documentation/pvDataCPP_20150623.html @@ -2309,15 +2309,15 @@ public: template<typename PVT> std::tr1::shared_ptr<PVT> getSubField(std::size_t fieldOffset) const - PVField& getSubFieldT(std::string const &fieldName) const; + PVFieldPtr getSubFieldT(std::string const &fieldName) const; template<typename PVT> - PVT& getSubFieldT(std::string const &fieldName) const + std::tr1::shared_ptr<PVT> getSubFieldT(std::string const &fieldName) const - PVField& getSubFieldT(std::size_t fieldOffset) const; + PVFieldPtr getSubFieldT(std::size_t fieldOffset) const; template<typename PVT> - PVT& getSubFieldT(std::size_t fieldOffset) const + std::tr1::shared_ptr<PVT> getSubFieldT(std::size_t fieldOffset) const virtual void serialize( ByteBuffer *pbuffer,SerializableControl *pflusher) const ; diff --git a/src/factory/PVStructure.cpp b/src/factory/PVStructure.cpp index b4ecf6b..a7996b7 100644 --- a/src/factory/PVStructure.cpp +++ b/src/factory/PVStructure.cpp @@ -134,11 +134,11 @@ PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const throw std::logic_error("PVStructure.getSubField: Logic error"); } -PVField& PVStructure::getSubFieldT(std::size_t fieldOffset) const +PVFieldPtr PVStructure::getSubFieldT(std::size_t fieldOffset) const { - PVField * raw = getSubField(fieldOffset).get(); - if (raw) - return *raw; + PVFieldPtr pvField = getSubField(fieldOffset); + if (pvField.get()) + return pvField; else { std::stringstream ss; diff --git a/src/pv/pvData.h b/src/pv/pvData.h index 1e305b9..e54d636 100644 --- a/src/pv/pvData.h +++ b/src/pv/pvData.h @@ -736,9 +736,9 @@ public: * @returns A reference to the sub-field (never NULL) * @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type */ - FORCE_INLINE PVField& getSubFieldT(std::string const &fieldName) const + FORCE_INLINE PVFieldPtr getSubFieldT(std::string const &fieldName) const { - return *getSubFieldImpl(fieldName.c_str()); + return getSubFieldImpl(fieldName.c_str())->shared_from_this(); } /** @@ -747,35 +747,37 @@ public: * @returns A reference to the sub-field (never NULL) * @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type * @code - * PVInt& ref = pvStruct->getSubFieldT("substruct.leaffield"); + * PVIntPtr ptr = pvStruct->getSubFieldT("substruct.leaffield"); * @endcode */ template - FORCE_INLINE PVT& getSubFieldT(std::string const &fieldName) const + FORCE_INLINE std::tr1::shared_ptr getSubFieldT(std::string const &fieldName) const { return this->getSubFieldT(fieldName.c_str()); } template - PVT& getSubFieldT(const char *name) const + std::tr1::shared_ptr getSubFieldT(const char *name) const { - PVT *raw = dynamic_cast(getSubFieldImpl(name)); - if(!raw) + std::tr1::shared_ptr pvField = std::tr1::dynamic_pointer_cast( + getSubFieldImpl(name)->shared_from_this()); + + if (pvField.get()) + return pvField; + else { std::stringstream ss; ss << "Failed to get field: " << name << " (Field has wrong type)"; throw std::runtime_error(ss.str()); } - return *raw; } - /** * Get the subfield with the specified offset. * @param fieldOffset The offset. * @returns A reference to the sub-field (never NULL) * @throws std::runtime_error if the requested sub-field doesn't exist */ - PVField& getSubFieldT(std::size_t fieldOffset) const; + PVFieldPtr getSubFieldT(std::size_t fieldOffset) const; /** * Get the subfield with the specified offset. @@ -784,11 +786,12 @@ public: * @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type */ template - PVT& getSubFieldT(std::size_t fieldOffset) const + std::tr1::shared_ptr getSubFieldT(std::size_t fieldOffset) const { - PVT* raw = dynamic_cast(&getSubFieldT(fieldOffset)); - if (raw) - return *raw; + std::tr1::shared_ptr pvField = std::tr1::dynamic_pointer_cast( + getSubFieldT(fieldOffset)); + if (pvField.get()) + return pvField; else { std::stringstream ss; diff --git a/testApp/pv/testPVData.cpp b/testApp/pv/testPVData.cpp index 747d8c6..ec387f7 100644 --- a/testApp/pv/testPVData.cpp +++ b/testApp/pv/testPVData.cpp @@ -541,16 +541,16 @@ static void testFieldAccess() PVIntPtr a = fld->getSubField("test"); testOk1(a!=NULL); if(a.get()) { - PVInt& b = fld->getSubFieldT("test"); - testOk(&b==a.get(), "%p == %p", &b, a.get()); + PVIntPtr b = fld->getSubFieldT("test"); + testOk(b.get()==a.get(), "%p == %p", b.get(), a.get()); } else testSkip(1, "test doesn't exist?"); a = fld->getSubField("hello.world"); testOk1(a!=NULL); if(a.get()) { - PVInt& b = fld->getSubFieldT("hello.world"); - testOk(&b==a.get(), "%p == %p", &b, a.get()); + PVIntPtr b = fld->getSubFieldT("hello.world"); + testOk(b.get()==a.get(), "%p == %p", b.get(), a.get()); } else testSkip(1, "hello.world doesn't exist?");