tempalte helpers; static initialization order
This commit is contained in:
@@ -461,7 +461,7 @@ void Convert::copyUnion(PVUnionPtr const & from, PVUnionPtr const & to)
|
||||
if (fromValue.get() == 0)
|
||||
to->set(PVFieldPtr());
|
||||
else
|
||||
to->set(getPVDataCreate()->createPVField(fromValue)); // clone value // TODO
|
||||
to->set(getPVDataCreate()->createPVField(fromValue)); // clone value // TODO cache getPVDataCreate()
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -460,18 +460,21 @@ void Structure::deserialize(ByteBuffer */*buffer*/, DeserializableControl */*con
|
||||
throw std::runtime_error("not valid operation, use FieldCreate::deserialize instead");
|
||||
}
|
||||
|
||||
|
||||
String Union::DEFAULT_ID = "union";
|
||||
String Union::ANY_ID = "any";
|
||||
|
||||
#define UNION_ANY_ID "any"
|
||||
String Union::ANY_ID = UNION_ANY_ID;
|
||||
|
||||
Union::Union ()
|
||||
: Field(union_),
|
||||
fieldNames(),
|
||||
fields(),
|
||||
id(ANY_ID)
|
||||
id(UNION_ANY_ID)
|
||||
{
|
||||
}
|
||||
|
||||
#undef UNION_ANY_ID
|
||||
|
||||
Union::Union (
|
||||
StringArray const & fieldNames,
|
||||
FieldConstPtrArray const & infields,
|
||||
@@ -996,6 +999,7 @@ FieldConstPtr FieldCreate::deserialize(ByteBuffer* buffer, DeserializableControl
|
||||
}
|
||||
}
|
||||
|
||||
// TODO replace with non-locking singleton pattern
|
||||
FieldCreatePtr FieldCreate::getFieldCreate()
|
||||
{
|
||||
LOCAL_STATIC_LOCK;
|
||||
|
||||
@@ -651,12 +651,12 @@ PVUnionPtr PVDataCreate::createPVUnion(
|
||||
|
||||
PVUnionPtr PVDataCreate::createPVVariantUnion()
|
||||
{
|
||||
return PVUnionPtr(new PVUnion(getFieldCreate()->createVariantUnion()));
|
||||
return PVUnionPtr(new PVUnion(fieldCreate->createVariantUnion()));
|
||||
}
|
||||
|
||||
PVUnionArrayPtr PVDataCreate::createPVVariantUnionArray()
|
||||
{
|
||||
return PVUnionArrayPtr(new PVUnionArray(getFieldCreate()->createVariantUnionArray()));
|
||||
return PVUnionArrayPtr(new PVUnionArray(fieldCreate->createVariantUnionArray()));
|
||||
}
|
||||
|
||||
PVStructurePtr PVDataCreate::createPVStructure(
|
||||
@@ -694,6 +694,8 @@ PVUnionPtr PVDataCreate::createPVUnion(PVUnionPtr const & unionToClone)
|
||||
return punion;
|
||||
}
|
||||
|
||||
// TODO not thread-safe (local static initializers)
|
||||
// TODO replace with non-locking singleton pattern
|
||||
PVDataCreatePtr PVDataCreate::getPVDataCreate()
|
||||
{
|
||||
static PVDataCreatePtr pvDataCreate;
|
||||
|
||||
@@ -28,8 +28,9 @@ size_t PVStructureArray::append(size_t number)
|
||||
|
||||
StructureConstPtr structure = structureArray->getStructure();
|
||||
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
for(svector::reverse_iterator it = data.rbegin(); number; ++it, --number)
|
||||
*it = getPVDataCreate()->createPVStructure(structure);
|
||||
*it = pvDataCreate->createPVStructure(structure);
|
||||
|
||||
size_t newLength = data.size();
|
||||
|
||||
@@ -148,6 +149,8 @@ void PVStructureArray::deserialize(ByteBuffer *pbuffer,
|
||||
|
||||
StructureConstPtr structure = structureArray->getStructure();
|
||||
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
|
||||
for(size_t i = 0; i<size; i++) {
|
||||
pcontrol->ensureData(1);
|
||||
size_t temp = pbuffer->getByte();
|
||||
@@ -156,7 +159,7 @@ void PVStructureArray::deserialize(ByteBuffer *pbuffer,
|
||||
}
|
||||
else {
|
||||
if(data[i].get()==NULL) {
|
||||
data[i] = getPVDataCreate()->createPVStructure(structure);
|
||||
data[i] = pvDataCreate->createPVStructure(structure);
|
||||
}
|
||||
data[i]->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
|
||||
@@ -23,19 +23,20 @@ using std::size_t;
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
int32 PVUnion::UNDEFINED_INDEX = -1;
|
||||
PVDataCreatePtr PVUnion::pvDataCreate = getPVDataCreate();
|
||||
|
||||
#define PVUNION_UNDEFINED_INDEX -1
|
||||
int32 PVUnion::UNDEFINED_INDEX = PVUNION_UNDEFINED_INDEX;
|
||||
|
||||
PVUnion::PVUnion(UnionConstPtr const & unionPtr)
|
||||
: PVField(unionPtr),
|
||||
unionPtr(unionPtr),
|
||||
selector(UNDEFINED_INDEX),
|
||||
selector(PVUNION_UNDEFINED_INDEX), // to allow out-of-order static initialization
|
||||
value(),
|
||||
variant(unionPtr->isVariant())
|
||||
{
|
||||
}
|
||||
|
||||
#undef PVUNION_UNDEFINED_INDEX
|
||||
|
||||
PVUnion::~PVUnion()
|
||||
{
|
||||
}
|
||||
@@ -83,8 +84,8 @@ PVFieldPtr PVUnion::select(int32 index)
|
||||
|
||||
FieldConstPtr field = unionPtr->getField(index);
|
||||
selector = index;
|
||||
value = pvDataCreate->createPVField(field);
|
||||
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -93,7 +94,6 @@ PVFieldPtr PVUnion::select(String const & fieldName)
|
||||
int32 index = variant ? -1 : unionPtr->getFieldIndex(fieldName);
|
||||
if (index == -1)
|
||||
throw std::invalid_argument("no such fieldName");
|
||||
|
||||
return select(index);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol)
|
||||
FieldConstPtr field = pcontrol->cachedDeserialize(pbuffer);
|
||||
if (field.get())
|
||||
{
|
||||
value = pvDataCreate->createPVField(field);
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
value->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
else
|
||||
@@ -177,7 +177,7 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol)
|
||||
if (selector != UNDEFINED_INDEX)
|
||||
{
|
||||
FieldConstPtr field = unionPtr->getField(selector);
|
||||
value = pvDataCreate->createPVField(field);
|
||||
value = getPVDataCreate()->createPVField(field);
|
||||
value->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -28,8 +28,9 @@ size_t PVUnionArray::append(size_t number)
|
||||
|
||||
UnionConstPtr punion = unionArray->getUnion();
|
||||
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
for(svector::reverse_iterator it = data.rbegin(); number; ++it, --number)
|
||||
*it = getPVDataCreate()->createPVUnion(punion);
|
||||
*it = pvDataCreate->createPVUnion(punion);
|
||||
|
||||
size_t newLength = data.size();
|
||||
|
||||
@@ -148,6 +149,8 @@ void PVUnionArray::deserialize(ByteBuffer *pbuffer,
|
||||
|
||||
UnionConstPtr punion = unionArray->getUnion();
|
||||
|
||||
PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
|
||||
for(size_t i = 0; i<size; i++) {
|
||||
pcontrol->ensureData(1);
|
||||
size_t temp = pbuffer->getByte();
|
||||
@@ -156,7 +159,7 @@ void PVUnionArray::deserialize(ByteBuffer *pbuffer,
|
||||
}
|
||||
else {
|
||||
if(data[i].get()==NULL) {
|
||||
data[i] = getPVDataCreate()->createPVUnion(punion);
|
||||
data[i] = pvDataCreate->createPVUnion(punion);
|
||||
}
|
||||
data[i]->deserialize(pbuffer, pcontrol);
|
||||
}
|
||||
|
||||
+52
-10
@@ -814,12 +814,34 @@ public:
|
||||
* @return Pointer to the field or null if field does not exist.
|
||||
*/
|
||||
PVFieldPtr getSubField(String const &fieldName) const;
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubField(String const &fieldName) const
|
||||
{
|
||||
PVFieldPtr pvField = getSubField(fieldName);
|
||||
if (pvField.get())
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvField);
|
||||
else
|
||||
return std::tr1::shared_ptr<PVT>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubField(std::size_t fieldOffset) const
|
||||
{
|
||||
PVFieldPtr pvField = getSubField(fieldOffset);
|
||||
if (pvField.get())
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvField);
|
||||
else
|
||||
return std::tr1::shared_ptr<PVT>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a field to the structure.
|
||||
* @param fieldName The name of the field to append.
|
||||
@@ -910,6 +932,7 @@ public:
|
||||
* @return Pointer to the field of null if a field with that name and type does not exist.
|
||||
*/
|
||||
PVStringPtr getStringField(String const &fieldName) ;
|
||||
|
||||
/**
|
||||
* Get a structure field with the specified name.
|
||||
* @param fieldName The name of the field to get.
|
||||
@@ -1054,11 +1077,10 @@ public:
|
||||
* @return {@code PVField} value of field, {@code null} if {@code getSelectedIndex() == UNDEFINED_INDEX}.
|
||||
*/
|
||||
PVFieldPtr get() const;
|
||||
|
||||
// TODO dynamic vs static cast?
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> get() const {
|
||||
return std::tr1::static_pointer_cast<PVT>(get());
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(get());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1068,11 +1090,10 @@ public:
|
||||
* @throws {@code std::invalid_argument} if index is invalid (out of range).
|
||||
*/
|
||||
PVFieldPtr select(int32 index);
|
||||
|
||||
// TODO dynamic vs static cast?
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> select(int32 index) {
|
||||
return std::tr1::static_pointer_cast<PVT>(select(index));
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(select(index));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1082,11 +1103,10 @@ public:
|
||||
* @throws {@code std::invalid_argument} if field does not exist.
|
||||
*/
|
||||
PVFieldPtr select(String const & fieldName);
|
||||
|
||||
// TODO dynamic vs static cast?
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> select(String const & fieldName) {
|
||||
return std::tr1::static_pointer_cast<PVT>(select(fieldName));
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(select(fieldName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1150,7 +1170,6 @@ public:
|
||||
|
||||
private:
|
||||
friend class PVDataCreate;
|
||||
static PVDataCreatePtr pvDataCreate;
|
||||
|
||||
UnionConstPtr unionPtr;
|
||||
|
||||
@@ -1741,6 +1760,29 @@ public:
|
||||
* @return The variant PVUnionArray implementation.
|
||||
*/
|
||||
PVUnionArrayPtr createPVVariantUnionArray();
|
||||
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> createPVScalar()
|
||||
{
|
||||
return std::tr1::static_pointer_cast<PVT>(createPVScalar(PVT::typeCode));
|
||||
}
|
||||
|
||||
template<typename PVAT>
|
||||
std::tr1::shared_ptr<PVAT> createPVScalarArray()
|
||||
{
|
||||
return std::tr1::static_pointer_cast<PVAT>(createPVScalarArray(PVAT::typeCode));
|
||||
}
|
||||
|
||||
PVStructureArrayPtr createPVStructureArray(StructureConstPtr const & structure)
|
||||
{
|
||||
return createPVStructureArray(fieldCreate->createStructureArray(structure));
|
||||
}
|
||||
|
||||
PVUnionArrayPtr createPVUnionArray(UnionConstPtr const & punion)
|
||||
{
|
||||
return createPVUnionArray(fieldCreate->createUnionArray(punion));
|
||||
}
|
||||
|
||||
private:
|
||||
PVDataCreate();
|
||||
|
||||
@@ -398,22 +398,6 @@ void testStructure() {
|
||||
serializationTest(pvStructure);
|
||||
}
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> createPVScalar()
|
||||
{
|
||||
return std::tr1::static_pointer_cast<PVT>(
|
||||
getPVDataCreate()->createPVScalar(PVT::typeCode)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename PVAT>
|
||||
std::tr1::shared_ptr<PVAT> createPVScalarArray()
|
||||
{
|
||||
return std::tr1::static_pointer_cast<PVAT>(
|
||||
getPVDataCreate()->createPVScalarArray(PVAT::typeCode)
|
||||
);
|
||||
}
|
||||
|
||||
void testUnion() {
|
||||
testDiag("Testing union...");
|
||||
|
||||
@@ -421,8 +405,8 @@ void testUnion() {
|
||||
testOk1(factory.get()!=NULL);
|
||||
|
||||
|
||||
PVDoublePtr doubleValue = createPVScalar<PVDouble>();
|
||||
PVIntPtr intValue = createPVScalar<PVInt>();
|
||||
PVDoublePtr doubleValue = factory->createPVScalar<PVDouble>();
|
||||
PVIntPtr intValue = factory->createPVScalar<PVInt>();
|
||||
|
||||
testDiag("\tVariant union test");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user