summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2014-09-17 20:01:59 +0000
committerrandomdan <randomdan@localhost>2014-09-17 20:01:59 +0000
commitaa4aaa7a21b393b2d181b471c0d06ff63cd52385 (patch)
tree17288e3932b37c0eb45aa61798dad54359f8c496
parentAllow overriding of the slicer-typeid property name (diff)
downloadslicer-aa4aaa7a21b393b2d181b471c0d06ff63cd52385.tar.bz2
slicer-aa4aaa7a21b393b2d181b471c0d06ff63cd52385.tar.xz
slicer-aa4aaa7a21b393b2d181b471c0d06ff63cd52385.zip
Make slice metadata for the slicer namespace available at runtime
-rw-r--r--slicer/slicer/modelParts.cpp9
-rw-r--r--slicer/slicer/modelParts.h26
-rw-r--r--slicer/slicer/parser.cpp81
-rw-r--r--slicer/slicer/parser.h3
4 files changed, 104 insertions, 15 deletions
diff --git a/slicer/slicer/modelParts.cpp b/slicer/slicer/modelParts.cpp
index b163da3..f902b92 100644
--- a/slicer/slicer/modelParts.cpp
+++ b/slicer/slicer/modelParts.cpp
@@ -1,6 +1,8 @@
#include "modelParts.h"
namespace Slicer {
+ const Metadata emptyMetadata;
+
IncorrectElementName::IncorrectElementName(const std::string & n) :
std::invalid_argument(n)
{
@@ -50,9 +52,16 @@ namespace Slicer {
ModelPart::SetValue(ValueSourcePtr)
{
}
+
void
ModelPart::GetValue(ValueTargetPtr)
{
}
+
+ const Metadata &
+ ModelPart::GetMetadata() const
+ {
+ return emptyMetadata;
+ }
}
diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h
index 9a0dab9..2fc43fe 100644
--- a/slicer/slicer/modelParts.h
+++ b/slicer/slicer/modelParts.h
@@ -86,6 +86,7 @@ namespace Slicer {
typedef boost::function<ModelPartPtr(void *)> ClassRef;
typedef std::map<std::string, ClassRef> ClassRefMap;
ClassRefMap * & classRefMap();
+ typedef std::set<std::string> Metadata;
enum ModelPartType {
mpt_Null,
mpt_Simple,
@@ -109,6 +110,7 @@ namespace Slicer {
virtual void SetValue(ValueSourcePtr);
virtual void GetValue(ValueTargetPtr);
virtual bool HasValue() const = 0;
+ virtual const Metadata & GetMetadata() const;
};
template<typename T>
@@ -227,6 +229,7 @@ namespace Slicer {
}
return mpt_Null;
}
+ virtual const Metadata & GetMetadata() const override { return modelPart->GetMetadata(); }
private:
IceUtil::Optional< typename T::element_type > & OptionalMember;
@@ -241,11 +244,22 @@ namespace Slicer {
virtual ModelPartPtr Get(T * t) const = 0;
virtual std::string PartName() const = 0;
+
+ virtual const Metadata & GetMetadata() const = 0;
};
typedef IceUtil::Handle<HookBase> HookPtr;
+ template <typename MT, typename CT, MT CT::*M>
+ class HookMetadata : public HookBase {
+ public:
+ virtual const Metadata & GetMetadata() const override { return metadata; }
+
+ private:
+ static Metadata metadata;
+ };
+
template <typename MT, typename CT, MT CT::*M, typename MP>
- class Hook : public HookBase {
+ class Hook : public HookMetadata<MT, CT, M> {
public:
Hook(const std::string & n) :
name(n)
@@ -262,6 +276,7 @@ namespace Slicer {
return name;
}
+
private:
const std::string name;
};
@@ -287,12 +302,15 @@ namespace Slicer {
virtual ModelPartType GetType() const { return mpt_Complex; }
+ virtual const Metadata & GetMetadata() const override { return metadata; }
+
virtual T * GetModel() = 0;
typedef std::vector<HookPtr> Hooks;
private:
static Hooks hooks;
+ static Metadata metadata;
};
template<typename T>
@@ -434,11 +452,14 @@ namespace Slicer {
virtual ModelPartType GetType() const { return mpt_Sequence; }
+ virtual const Metadata & GetMetadata() const override { return metadata; }
+
private:
ModelPartPtr elementModelPart(typename T::value_type &) const;
T & sequence;
static std::string elementName;
+ static Metadata metadata;
};
template<typename T>
@@ -512,9 +533,12 @@ namespace Slicer {
virtual ModelPartType GetType() const { return mpt_Dictionary; }
+ virtual const Metadata & GetMetadata() const override { return metadata; }
+
private:
T & dictionary;
static std::string pairName;
+ static Metadata metadata;
};
}
diff --git a/slicer/slicer/parser.cpp b/slicer/slicer/parser.cpp
index e3487c7..fac9ff7 100644
--- a/slicer/slicer/parser.cpp
+++ b/slicer/slicer/parser.cpp
@@ -120,13 +120,7 @@ namespace Slicer {
auto decl = c->declaration();
fprintf(cpp, "// Class %s\n", c->name().c_str());
- fprintf(cpp, "template<>\n");
- fprintf(cpp, "ModelPartForComplex< %s::%s >::Hooks ",
- modulePath().c_str(), c->name().c_str());
- fprintf(cpp, "ModelPartForComplex< %s::%s >::hooks {\n",
- modulePath().c_str(), c->name().c_str());
visitComplexDataMembers(decl, c->allDataMembers());
- fprintf(cpp, "\t};\n\n");
fprintf(cpp, "template<>\n");
auto typeId = metaDataValue("slicer:typeid:", c->getMetaData());
@@ -159,6 +153,10 @@ namespace Slicer {
fprintf(cpp, "\treturn (id == \"%s::%s\") ? TypeId() : id;\n}\n\n",
modulePath().c_str(), c->name().c_str());
+ fprintf(cpp, "template<>\nMetadata ModelPartForComplex< %s::%s >::metadata ",
+ modulePath().c_str(), c->name().c_str());
+ copyMetadata(c->getMetaData());
+
classNo += 1;
return true;
@@ -170,20 +168,23 @@ namespace Slicer {
if (c->hasMetaData("slicer:ignore")) { return false; }
fprintf(cpp, "// Struct %s\n", c->name().c_str());
- fprintf(cpp, "template<>\n");
- fprintf(cpp, "ModelPartForComplex< %s::%s >::Hooks ",
- modulePath().c_str(), c->name().c_str());
- fprintf(cpp, "ModelPartForComplex< %s::%s >::hooks {\n",
- modulePath().c_str(), c->name().c_str());
visitComplexDataMembers(c, c->dataMembers());
- fprintf(cpp, "\t};\n\n");
+ fprintf(cpp, "template<>\nMetadata ModelPartForComplex< %s::%s >::metadata ",
+ modulePath().c_str(), c->name().c_str());
+ copyMetadata(c->getMetaData());
+
return true;
}
void
- Slicer::visitComplexDataMembers(Slice::TypePtr it, const Slice::DataMemberList & dataMembers) const
+ Slicer::visitComplexDataMembers(Slice::ConstructedPtr it, const Slice::DataMemberList & dataMembers) const
{
+ fprintf(cpp, "template<>\n");
+ fprintf(cpp, "ModelPartForComplex< %s::%s >::Hooks ",
+ modulePath().c_str(), it->name().c_str());
+ fprintf(cpp, "ModelPartForComplex< %s::%s >::hooks {\n",
+ modulePath().c_str(), it->name().c_str());
BOOST_FOREACH (const auto & dm, dataMembers) {
auto c = Slice::ContainedPtr::dynamicCast(dm->container());
auto t = Slice::TypePtr::dynamicCast(dm->container());
@@ -221,6 +222,25 @@ namespace Slicer {
fprintf(cpp, " >(\"%s\"),\n",
name ? name->c_str() : dm->name().c_str());
}
+ fprintf(cpp, "\t};\n\n");
+
+ BOOST_FOREACH (const auto & dm, dataMembers) {
+ auto c = Slice::ContainedPtr::dynamicCast(dm->container());
+ auto t = Slice::TypePtr::dynamicCast(dm->container());
+ if (!t) {
+ t = Slice::ClassDefPtr::dynamicCast(dm->container())->declaration();
+ }
+ auto type = dm->type();
+ fprintf(cpp, "template<>\ntemplate<>\nMetadata\n");
+ createNewModelPartPtrFor(t);
+ fprintf(cpp, "< %s >::HookMetadata< %s",
+ typeToString(it).c_str(),
+ Slice::typeToString(type, dm->optional()).c_str());
+ fprintf(cpp, ", %s::%s, &%s::%s::%s >::metadata ",
+ modulePath().c_str(), c->name().c_str(),
+ modulePath().c_str(), c->name().c_str(), dm->name().c_str());
+ copyMetadata(dm->getMetaData());
+ }
}
void
@@ -258,6 +278,10 @@ namespace Slicer {
fprintf(cpp, "std::string ModelPartForSequence< %s::%s >::elementName(\"%s\");\n\n",
modulePath().c_str(), s->name().c_str(),
ename ? ename->c_str() : "element");
+
+ fprintf(cpp, "template<>\nMetadata ModelPartForSequence< %s::%s >::metadata ",
+ modulePath().c_str(), s->name().c_str());
+ copyMetadata(s->getMetaData());
}
void
@@ -302,6 +326,25 @@ namespace Slicer {
vname ? vname->c_str() : "value");
fprintf(cpp, "\t};\n");
fprintf(cpp, "\n");
+
+ fprintf(cpp, "template<>\nMetadata ModelPartForDictionary< %s::%s >::metadata ",
+ modulePath().c_str(), d->name().c_str());
+ copyMetadata(d->getMetaData());
+
+ fprintf(cpp, "template<>\nMetadata ModelPartForComplex<ModelPartForDictionaryElement< %s::%s > >::metadata ",
+ modulePath().c_str(), d->name().c_str());
+ copyMetadata(d->getMetaData());
+
+ fprintf(cpp, "template<>\ntemplate<>\nMetadata\nModelPartForDictionaryElement< %s::%s >::HookMetadata< %s*, ModelPartForDictionaryElement< %s::%s >, &ModelPartForDictionaryElement< %s::%s >::key >::metadata { };\n\n",
+ modulePath().c_str(), d->name().c_str(),
+ Slice::typeToString(ktype).c_str(),
+ modulePath().c_str(), d->name().c_str(),
+ modulePath().c_str(), d->name().c_str());
+ fprintf(cpp, "template<>\ntemplate<>\nMetadata\nModelPartForDictionaryElement< %s::%s >::HookMetadata< %s*, ModelPartForDictionaryElement< %s::%s >, &ModelPartForDictionaryElement< %s::%s >::value >::metadata { };\n\n",
+ modulePath().c_str(), d->name().c_str(),
+ Slice::typeToString(vtype).c_str(),
+ modulePath().c_str(), d->name().c_str(),
+ modulePath().c_str(), d->name().c_str());
}
void
@@ -342,6 +385,18 @@ namespace Slicer {
return path;
}
+ void
+ Slicer::copyMetadata(const std::list<std::string> & metadata) const
+ {
+ fprintf(cpp, "{\n");
+ BOOST_FOREACH (const auto & md, metadata) {
+ if (boost::algorithm::starts_with(md, "slicer:")) {
+ fprintf(cpp, "\t\"%.*s\",\n", (int)md.length() - 7, md.c_str() + 7);
+ }
+ }
+ fprintf(cpp, "};\n\n");
+ }
+
boost::optional<std::string>
Slicer::metaDataValue(const std::string & prefix, const std::list<std::string> & metadata)
{
diff --git a/slicer/slicer/parser.h b/slicer/slicer/parser.h
index 64d961f..8aef56f 100644
--- a/slicer/slicer/parser.h
+++ b/slicer/slicer/parser.h
@@ -41,12 +41,13 @@ namespace Slicer {
private:
void createNewModelPartPtrFor(const Slice::TypePtr & type) const;
- void visitComplexDataMembers(Slice::TypePtr t, const Slice::DataMemberList &) const;
+ void visitComplexDataMembers(Slice::ConstructedPtr t, const Slice::DataMemberList &) const;
std::string modulePath() const;
void defineConversions(Slice::DataMemberPtr dm) const;
+ void copyMetadata(const std::list<std::string> & metadata) const;
static boost::optional<std::string> metaDataValue(const std::string & prefix, const std::list<std::string> & metadata);
static std::list<std::string> metaDataValues(const std::string & prefix, const std::list<std::string> & metadata);
static std::vector<std::string> metaDataSplit(const std::string & metadata);