diff --git a/documentation/pvDataCPP.html b/documentation/pvDataCPP.html
index 8618d59..89541be 100644
--- a/documentation/pvDataCPP.html
+++ b/documentation/pvDataCPP.html
@@ -2309,8 +2309,15 @@ public:
template<typename PVT>
std::tr1::shared_ptr<PVT> getSubField(std::size_t fieldOffset) const
+ PVField& getSubFieldT(std::string const &fieldName) const;
+
template<typename PVT>
- PVT& getSubFieldT(std::string const &fieldName) const;
+ PVT& getSubFieldT(std::string const &fieldName) const
+
+ PVField& getSubFieldT(std::size_t fieldOffset) const;
+
+ template<typename PVT>
+ PVT& getSubFieldT(std::size_t fieldOffset) const
virtual void serialize(
ByteBuffer *pbuffer,SerializableControl *pflusher) const ;
@@ -2332,7 +2339,7 @@ public:
getPVFields
Returns the array of subfields. The set of subfields must all have
different field names.
- getSubField(std::string fieldName)
+ getSubField(std::string const &fieldName)
Get a subField of a field.d
A non-null result is
@@ -2347,12 +2354,13 @@ public:
Get the field located a fieldOffset, where fieldOffset is relative to
the top level structure. This returns null if the specified field is not
located within this PVStructure.
-
- Note The template version replaces getBooleanField, etc.
getSubFieldT(std::string const &fieldName)
Like getSubField except that it throws std::runtime_error if
the field does not exists or has the wrong type.
+ getSubFieldT(int fieldOffset)
+ Like getSubField except that it throws std::runtime_error if
+ the field does not exists or has the wrong type.
dumpValue
Method for streams I/O.
diff --git a/documentation/pvDataCPP_20150623.html b/documentation/pvDataCPP_20150623.html
index 8618d59..89541be 100644
--- a/documentation/pvDataCPP_20150623.html
+++ b/documentation/pvDataCPP_20150623.html
@@ -2309,8 +2309,15 @@ public:
template<typename PVT>
std::tr1::shared_ptr<PVT> getSubField(std::size_t fieldOffset) const
+ PVField& getSubFieldT(std::string const &fieldName) const;
+
template<typename PVT>
- PVT& getSubFieldT(std::string const &fieldName) const;
+ PVT& getSubFieldT(std::string const &fieldName) const
+
+ PVField& getSubFieldT(std::size_t fieldOffset) const;
+
+ template<typename PVT>
+ PVT& getSubFieldT(std::size_t fieldOffset) const
virtual void serialize(
ByteBuffer *pbuffer,SerializableControl *pflusher) const ;
@@ -2332,7 +2339,7 @@ public:
getPVFields
Returns the array of subfields. The set of subfields must all have
different field names.
- getSubField(std::string fieldName)
+ getSubField(std::string const &fieldName)
Get a subField of a field.d
A non-null result is
@@ -2347,12 +2354,13 @@ public:
Get the field located a fieldOffset, where fieldOffset is relative to
the top level structure. This returns null if the specified field is not
located within this PVStructure.
-
- Note The template version replaces getBooleanField, etc.
getSubFieldT(std::string const &fieldName)
Like getSubField except that it throws std::runtime_error if
the field does not exists or has the wrong type.
+ getSubFieldT(int fieldOffset)
+ Like getSubField except that it throws std::runtime_error if
+ the field does not exists or has the wrong type.
dumpValue
Method for streams I/O.
diff --git a/src/factory/PVStructure.cpp b/src/factory/PVStructure.cpp
index 5319369..b4ecf6b 100644
--- a/src/factory/PVStructure.cpp
+++ b/src/factory/PVStructure.cpp
@@ -134,6 +134,20 @@ PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const
throw std::logic_error("PVStructure.getSubField: Logic error");
}
+PVField& PVStructure::getSubFieldT(std::size_t fieldOffset) const
+{
+ PVField * raw = getSubField(fieldOffset).get();
+ if (raw)
+ return *raw;
+ else
+ {
+ std::stringstream ss;
+ ss << "Failed to get field with offset "
+ << fieldOffset << "(Invalid offset)" ;
+ throw std::runtime_error(ss.str());
+ }
+}
+
PVField* PVStructure::getSubFieldImpl(const char *name, bool throws) const
{
const PVStructure *parent = this;
diff --git a/src/pv/pvData.h b/src/pv/pvData.h
index 0e0e6b2..1e305b9 100644
--- a/src/pv/pvData.h
+++ b/src/pv/pvData.h
@@ -684,23 +684,42 @@ public:
*/
PVFieldPtr getSubField(std::string const &fieldName) const;
+ /**
+ * Get a subfield with the specified name.
+ * @param fieldName a '.' separated list of child field names (no whitespace allowed)
+ * @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
+ */
template
- std::tr1::shared_ptr getSubField(std::string const &fieldName) const
+ FORCE_INLINE std::tr1::shared_ptr getSubField(std::string const &fieldName) const
{
- PVFieldPtr pvField = getSubField(fieldName);
- if (pvField.get())
- return std::tr1::dynamic_pointer_cast(pvField);
+ return this->getSubField(fieldName.c_str());
+ }
+
+ template
+ std::tr1::shared_ptr getSubField(const char *name) const
+ {
+ PVField *raw = getSubFieldImpl(name, false);
+ if (raw)
+ return std::tr1::dynamic_pointer_cast(raw->shared_from_this());
else
return std::tr1::shared_ptr();
}
-
+
/**
* Get the subfield with the specified offset.
* @param fieldOffset The offset.
* @return Pointer to the field or null if field does not exist.
*/
PVFieldPtr getSubField(std::size_t fieldOffset) const;
-
+
+ /**
+ * 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) const
{
@@ -711,19 +730,32 @@ public:
return std::tr1::shared_ptr();
}
-private:
- PVField *getSubFieldImpl(const char *name, bool throws = true) const;
-public:
+ /**
+ * 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)
+ * @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
+ {
+ return *getSubFieldImpl(fieldName.c_str());
+ }
/**
* Get a subfield with the specified name.
- * @param name a '.' separated list of child field names (no whitespace allowed)
+ * @param fieldName a '.' separated list of child field names (no whitespace allowed)
* @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");
* @endcode
*/
+ template
+ FORCE_INLINE PVT& getSubFieldT(std::string const &fieldName) const
+ {
+ return this->getSubFieldT(fieldName.c_str());
+ }
+
template
PVT& getSubFieldT(const char *name) const
{
@@ -737,10 +769,33 @@ public:
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;
+
+ /**
+ * 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
- FORCE_INLINE PVT& getSubFieldT(std::string const &fieldName) const
+ PVT& getSubFieldT(std::size_t fieldOffset) const
{
- return this->getSubFieldT(fieldName.c_str());
+ PVT* raw = dynamic_cast(&getSubFieldT(fieldOffset));
+ if (raw)
+ return *raw;
+ else
+ {
+ std::stringstream ss;
+ ss << "Failed to get field with offset "
+ << fieldOffset << " (Field has wrong type)";
+ throw std::runtime_error(ss.str());
+ }
}
/**
@@ -915,6 +970,8 @@ public:
void copyUnchecked(const PVStructure& from, const BitSet& maskBitSet, bool inverse = false);
private:
+ PVField *getSubFieldImpl(const char *name, bool throws = true) const;
+
static PVFieldPtr nullPVField;
static PVBooleanPtr nullPVBoolean;
static PVBytePtr nullPVByte;