From 4dd7a183015380eae4865a6ef9267d48085942e7 Mon Sep 17 00:00:00 2001 From: Bruno Martins Date: Mon, 20 May 2019 15:49:00 -0400 Subject: [PATCH] Improve docs. Make getFieldT(offset) use vector::at. --- src/factory/FieldCreateFactory.cpp | 28 ----- src/pv/pvIntrospect.h | 174 ++++++++++++++++++----------- testApp/pv/testIntrospect.cpp | 4 +- 3 files changed, 112 insertions(+), 94 deletions(-) diff --git a/src/factory/FieldCreateFactory.cpp b/src/factory/FieldCreateFactory.cpp index b213062..14e34f6 100644 --- a/src/factory/FieldCreateFactory.cpp +++ b/src/factory/FieldCreateFactory.cpp @@ -566,20 +566,6 @@ FieldConstPtr Structure::getFieldImpl(string const & fieldName, bool throws) con } } -FieldConstPtr Structure::getFieldImpl(size_t fieldOffset, bool throws) const { - if (fieldOffset < fields.size()) - return fields[fieldOffset]; - - if (throws) { - std::stringstream ss; - ss << "Failed to get field with offset " - << fieldOffset << " (Invalid offset)"; - throw std::runtime_error(ss.str()); - } else { - return FieldConstPtr(); - } -} - std::ostream& Structure::dump(std::ostream& o) const { o << format::indent() << getID() << std::endl; @@ -794,20 +780,6 @@ FieldConstPtr Union::getFieldImpl(string const & fieldName, bool throws) const { } } -FieldConstPtr Union::getFieldImpl(size_t fieldOffset, bool throws) const { - if (fieldOffset < fields.size()) - return fields[fieldOffset]; - - if (throws) { - std::stringstream ss; - ss << "Failed to get field with offset " - << fieldOffset << " (Invalid offset)"; - throw std::runtime_error(ss.str()); - } else { - return FieldConstPtr(); - } -} - std::ostream& Union::dump(std::ostream& o) const { o << format::indent() << getID() << std::endl; diff --git a/src/pv/pvIntrospect.h b/src/pv/pvIntrospect.h index 7a13f0c..aecdc23 100644 --- a/src/pv/pvIntrospect.h +++ b/src/pv/pvIntrospect.h @@ -717,72 +717,96 @@ public: * @return The number of fields. */ std::size_t getNumberFields() const {return fieldNames.size();} + /** - * Get the field for the specified fieldName. - * @param fieldName The name of the field to get; - * @return The introspection interface. - * This will hold a null pointer if the field is not in the structure. + * Lookup Field by name + * @param fieldName Member field name. May not contain '.' + * @return NULL if no member by this name. */ FieldConstPtr getField(std::string const &fieldName) const; + /** Lookup Field by name and cast to Field sub-class. + * @param fieldName Member field name. May not contain '.' + * @return NULL If no member by this name, or member exists, but has type other than FT. + */ template std::tr1::shared_ptr getField(std::string const &fieldName) const { STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class - FieldConstPtr field(getField(fieldName)); - if (field) - return std::tr1::dynamic_pointer_cast(field); - else - return std::tr1::shared_ptr(); + return std::tr1::dynamic_pointer_cast(getField(fieldName)); } /** - * Get the field for the specified fieldName. - * @param fieldName The name of the field to get; - * @return The introspection interface. - * This will throw a runtime_error exception if the field is not in the structure. + * Lookup Field by name + * @param fieldName Member field name. May not contain '.' + * @return Field pointer (never NULL) + * @throws std::runtime_error If no member by this name */ FieldConstPtr getFieldT(std::string const &fieldName) const {return getFieldImpl(fieldName, true);}; + /** Lookup Field by name and cast to Field sub-class. + * @param fieldName Member field name. May not contain '.' + * @return Field pointer (never NULL) + * @throws std::runtime_error If no member by this name, or member exists, but has type other than FT. + */ template std::tr1::shared_ptr getFieldT(std::string const &fieldName) const { STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class - return std::tr1::dynamic_pointer_cast(getFieldT(fieldName)); + std::tr1::shared_ptr result( + std::tr1::dynamic_pointer_cast(getFieldT(fieldName)) + ); + + if (!result) + throw std::runtime_error("Wrong Field type"); + + return result; } - /** - * Get the field for the specified fieldName. - * @param index The index of the field to get; - * @return The introspection interface. - * This will hold a null pointer if the field is not in the structure. + /** Lookup Field by index, within this Structure. + * @param index Index of member in this structure. @code index>=0 && index= getNumberFields() */ const FieldConstPtr& getField(std::size_t index) const {return fields.at(index);} + /** Lookup Field by index, within this Structure. + * @param index Index of member in this structure. @code index>=0 && index= getNumberFields() + */ template std::tr1::shared_ptr getField(std::size_t index) const { STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class - const FieldConstPtr& field(getField(index)); - if (field) - return std::tr1::dynamic_pointer_cast(field); - else - return std::tr1::shared_ptr(); + return std::tr1::dynamic_pointer_cast(getField(index)); } - /** - * Get the field for the specified fieldName. - * @param index The index of the field to get; - * @return The introspection interface. - * This will throw a runtime_error exception if the field is not in the structure. + /** Lookup Field by index, within this Structure. + * @param index Index of member in this structure. @code index>=0 && index= getNumberFields() */ - FieldConstPtr getFieldT(std::size_t index) const {return getFieldImpl(index, true);} + FieldConstPtr getFieldT(std::size_t index) const {return fields.at(index);} + /** Lookup Field by index, within this Structure. + * @param index Index of member in this structure. @code index>=0 && index= getNumberFields() + * @throws std::runtime_error If member is not a sub-class of FT + */ template std::tr1::shared_ptr getFieldT(std::size_t index) const { STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class - return std::tr1::dynamic_pointer_cast(getFieldT(index)); + std::tr1::shared_ptr result( + std::tr1::dynamic_pointer_cast(getFieldT(index)) + ); + + if (!result) + throw std::runtime_error("Wrong Field type"); + + return result; } /** @@ -827,7 +851,6 @@ private: std::string id; FieldConstPtr getFieldImpl(const std::string& fieldName, bool throws) const; - FieldConstPtr getFieldImpl(const std::size_t fieldOffset, bool throws) const; void dumpFields(std::ostream& o) const; friend class FieldCreate; @@ -874,72 +897,96 @@ public: * @return The number of fields. */ std::size_t getNumberFields() const {return fieldNames.size();} + /** - * Get the field for the specified fieldName. - * @param fieldName The name of the field to get; - * @return The introspection interface. - * This will hold a null pointer if the field is not in the union. + * Lookup Field by name + * @param fieldName Member field name. May not contain '.' + * @return NULL if no member by this name. */ FieldConstPtr getField(std::string const &fieldName) const; + /** Lookup Field by name and cast to Field sub-class. + * @param fieldName Member field name. May not contain '.' + * @return NULL If no member by this name, or member exists, but has type other than FT. + */ template std::tr1::shared_ptr getField(std::string const &fieldName) const { STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class - FieldConstPtr field = getField(fieldName); - if (field) - return std::tr1::dynamic_pointer_cast(field); - else - return std::tr1::shared_ptr(); + return std::tr1::dynamic_pointer_cast(getField(fieldName)); } /** - * Get the field for the specified fieldName. - * @param fieldName The name of the field to get; - * @return The introspection interface. - * This will throw a runtime_error exception if the field is not in the union. + * Lookup Field by name + * @param fieldName Member field name. May not contain '.' + * @return Field pointer (never NULL) + * @throws std::runtime_error If no member by this name */ FieldConstPtr getFieldT(std::string const &fieldName) const {return getFieldImpl(fieldName, true);}; + /** Lookup Field by name and cast to Field sub-class. + * @param fieldName Member field name. May not contain '.' + * @return Field pointer (never NULL) + * @throws std::runtime_error If no member by this name, or member exists, but has type other than FT. + */ template std::tr1::shared_ptr getFieldT(std::string const &fieldName) const { STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class - return std::tr1::dynamic_pointer_cast(getFieldT(fieldName)); + std::tr1::shared_ptr result( + std::tr1::dynamic_pointer_cast(getFieldT(fieldName)) + ); + + if (!result) + throw std::runtime_error("Wrong Field type"); + + return result; } - /** - * Get the field for the specified fieldName. - * @param index The index of the field to get; - * @return The introspection interface. - * This will hold a null pointer if the field is not in the union. + /** Lookup Field by index, within this Union. + * @param index Index of member in this union. @code index>=0 && index= getNumberFields() */ FieldConstPtr getField(std::size_t index) const {return fields.at(index);} + /** Lookup Field by index, within this Union. + * @param index Index of member in this union. @code index>=0 && index= getNumberFields() + */ template std::tr1::shared_ptr getField(std::size_t index) const { STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class - FieldConstPtr field = getField(index); - if (field) - return std::tr1::dynamic_pointer_cast(field); - else - return std::tr1::shared_ptr(); + return std::tr1::dynamic_pointer_cast(getField(index)); } - /** - * Get the field for the specified fieldName. - * @param index The index of the field to get; - * @return The introspection interface. - * This will throw a runtime_error exception if the field is not in the union. + /** Lookup Field by index, within this Union. + * @param index Index of member in this union. @code index>=0 && index= getNumberFields() */ - FieldConstPtr getFieldT(std::size_t index) const {return getFieldImpl(index, true);} + FieldConstPtr getFieldT(std::size_t index) const {return fields.at(index);} + /** Lookup Field by index, within this Structure. + * @param index Index of member in this structure. @code index>=0 && index= getNumberFields() + * @throws std::runtime_error If member is not a sub-class of FT + */ template std::tr1::shared_ptr getFieldT(std::size_t index) const { STATIC_ASSERT(FT::isField); // only allow cast from Field sub-class - return std::tr1::dynamic_pointer_cast(getFieldT(index)); + std::tr1::shared_ptr result( + std::tr1::dynamic_pointer_cast(getFieldT(index)) + ); + + if (!result) + throw std::runtime_error("Wrong Field type"); + + return result; } /** @@ -1001,7 +1048,6 @@ private: std::string id; FieldConstPtr getFieldImpl(const std::string& fieldName, bool throws) const; - FieldConstPtr getFieldImpl(const std::size_t fieldOffset, bool throws) const; void dumpFields(std::ostream& o) const; friend class FieldCreate; diff --git a/testApp/pv/testIntrospect.cpp b/testApp/pv/testIntrospect.cpp index 1f4d789..98de350 100644 --- a/testApp/pv/testIntrospect.cpp +++ b/testApp/pv/testIntrospect.cpp @@ -169,7 +169,7 @@ static void testStructure() try { FieldConstPtr field(struct1->getFieldT(9999)); testFail("missing required exception"); - } catch (std::runtime_error& e) { + } catch (std::out_of_range& e) { testPass("caught expected exception: %s", e.what()); } @@ -241,7 +241,7 @@ static void testUnion() try { FieldConstPtr field(union1->getFieldT(9999)); testFail("missing required exception"); - } catch (std::runtime_error& e) { + } catch (std::out_of_range& e) { testPass("caught expected exception: %s", e.what()); }