From 78b51ebe5952c139753911808fb636663fc83b0e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 16 Aug 2017 11:07:29 +0200 Subject: [PATCH] c++98 compatible, but still reduced, number of getSubField() specializations --- src/factory/PVStructure.cpp | 2 +- src/pv/pvData.h | 142 +++++++++++++----------------------- 2 files changed, 53 insertions(+), 91 deletions(-) diff --git a/src/factory/PVStructure.cpp b/src/factory/PVStructure.cpp index 8dc2195..9568b07 100644 --- a/src/factory/PVStructure.cpp +++ b/src/factory/PVStructure.cpp @@ -199,7 +199,7 @@ PVFieldPtr PVStructure::getSubFieldImpl(const char *name, bool throws) const throw std::runtime_error(ss.str()); } else - return NULL; + return PVFieldPtr(); } child = NULL; name = sep+1; // skip past '.' diff --git a/src/pv/pvData.h b/src/pv/pvData.h index cae9031..446df4b 100644 --- a/src/pv/pvData.h +++ b/src/pv/pvData.h @@ -779,130 +779,89 @@ public: */ const PVFieldPtrArray & getPVFields() const; + /** + * Get the subfield with the specified offset. + * @param a A sub-field name or index + * @return Pointer to the field or NULL if field does not exist. + */ + template + FORCE_INLINE std::tr1::shared_ptr getSubField(A a) + { + return getSubFieldImpl(a, false); + } + + template + FORCE_INLINE std::tr1::shared_ptr getSubField(A a) const + { + return getSubFieldImpl(a, false); + } + /** * Get a subfield with the specified name. - * @param fieldName a '.' separated list of child field names (no whitespace allowed) + * @param a A sub-field name or index * @returns A pointer to the sub-field or null if field does not exist or has a different type * @code * PVIntPtr ptr = pvStruct->getSubField("substruct.leaffield"); * @endcode + * + * A field name is a '.' delimited list of child field names (no whitespace allowed) */ - template - FORCE_INLINE std::tr1::shared_ptr getSubField(std::string const &fieldName) + template + inline std::tr1::shared_ptr getSubField(A a) { - return this->getSubField(fieldName.c_str()); + return std::tr1::dynamic_pointer_cast(getSubFieldImpl(a, false)); } - template - FORCE_INLINE std::tr1::shared_ptr getSubField(std::string const &fieldName) const + template + inline std::tr1::shared_ptr getSubField(A a) const { - return this->getSubField(fieldName.c_str()); - } - - template - std::tr1::shared_ptr getSubField(const char *name) - { - return std::tr1::dynamic_pointer_cast(getSubFieldImpl(name, false)); - } - - template - std::tr1::shared_ptr getSubField(const char *name) const - { - return std::tr1::dynamic_pointer_cast(getSubFieldImpl(name, false)); + return std::tr1::dynamic_pointer_cast(getSubFieldImpl(a, false)); } /** * Get the subfield with the specified offset. - * @param fieldOffset The offset. - * @return Pointer to the field or null if field does not exist. - */ - template - std::tr1::shared_ptr getSubField(std::size_t fieldOffset) - { - return std::tr1::dynamic_pointer_cast(getSubFieldImpl(fieldOffset, false)); - } - template - std::tr1::shared_ptr getSubField(std::size_t fieldOffset) const - { - return std::tr1::dynamic_pointer_cast(getSubFieldImpl(fieldOffset, false)); - } - - /** - * Get a subfield with the specified name. - * @param fieldName a '.' separated list of child field names (no whitespace allowed) - * @returns A reference to the sub-field (never NULL) + * @param a A sub-field name or index * @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type - * @code - * PVIntPtr ptr = pvStruct->getSubFieldT("substruct.leaffield"); - * @endcode + * @return Pointer to the field */ - template - FORCE_INLINE std::tr1::shared_ptr getSubFieldT(std::string const &fieldName) + template + FORCE_INLINE std::tr1::shared_ptr getSubFieldT(A a) { - return this->getSubFieldT(fieldName.c_str()); + return getSubFieldImpl(a, true); } - template - FORCE_INLINE std::tr1::shared_ptr getSubFieldT(std::string const &fieldName) const + template + FORCE_INLINE std::tr1::shared_ptr getSubFieldT(A a) const { - return this->getSubFieldT(fieldName.c_str()); + return getSubFieldImpl(a, true); } private: static void throwBadFieldType(const char *name); -public: - - template - std::tr1::shared_ptr getSubFieldT(const char *name) - { - std::tr1::shared_ptr pvField(std::tr1::dynamic_pointer_cast( - getSubFieldImpl(name, true))); - if(!pvField) - throwBadFieldType(name); - return pvField; - } - - template - std::tr1::shared_ptr getSubFieldT(const char *name) const - { - std::tr1::shared_ptr pvField(std::tr1::dynamic_pointer_cast( - getSubFieldImpl(name, true))); - if(!pvField) - throwBadFieldType(name); - return pvField; - } - -private: static void throwBadFieldType(std::size_t fieldOffset); + static FORCE_INLINE void throwBadFieldType(const std::string& name) { + throwBadFieldType(name.c_str()); + } public: - /** - * 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, or has a different type - */ - template - std::tr1::shared_ptr getSubFieldT(std::size_t fieldOffset) + template + inline std::tr1::shared_ptr getSubFieldT(A a) { - std::tr1::shared_ptr pvField = std::tr1::dynamic_pointer_cast( - getSubFieldImpl(fieldOffset, true)); - if(!pvField) - throwBadFieldType(fieldOffset); - return pvField; + std::tr1::shared_ptr ret(std::tr1::dynamic_pointer_cast(getSubFieldImpl(a, true))); + if(!ret) + throwBadFieldType(a); + return ret; } - template - std::tr1::shared_ptr getSubFieldT(std::size_t fieldOffset) const + template + inline std::tr1::shared_ptr getSubFieldT(A a) const { - std::tr1::shared_ptr pvField = std::tr1::dynamic_pointer_cast( - getSubFieldImpl(fieldOffset, true)); - if(!pvField) - throwBadFieldType(fieldOffset); - return pvField; + std::tr1::shared_ptr ret(std::tr1::dynamic_pointer_cast(getSubFieldImpl(a, true))); + if(!ret) + throwBadFieldType(a); + return ret; } - /** * Serialize. * @param pbuffer The byte buffer. @@ -953,6 +912,9 @@ public: void copyUnchecked(const PVStructure& from, const BitSet& maskBitSet, bool inverse = false); private: + inline PVFieldPtr getSubFieldImpl(const std::string& name, bool throws) const { + return getSubFieldImpl(name.c_str(), throws); + } PVFieldPtr getSubFieldImpl(const char *name, bool throws) const; PVFieldPtr getSubFieldImpl(std::size_t fieldOffset, bool throws) const;