tempalte helpers; static initialization order

This commit is contained in:
Matej Sekoranja
2013-11-08 13:50:54 +01:00
parent 57b3e9a8b2
commit 1aff2ec112
8 changed files with 85 additions and 47 deletions
+1 -1
View File
@@ -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
{
+7 -3
View File
@@ -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;
+4 -2
View File
@@ -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;
+5 -2
View File
@@ -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);
}
+9 -9
View File
@@ -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
+5 -2
View File
@@ -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
View File
@@ -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();
+2 -18
View File
@@ -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");