From aa4aaa7a21b393b2d181b471c0d06ff63cd52385 Mon Sep 17 00:00:00 2001 From: randomdan Date: Wed, 17 Sep 2014 20:01:59 +0000 Subject: Make slice metadata for the slicer namespace available at runtime --- slicer/slicer/modelParts.cpp | 9 +++++ slicer/slicer/modelParts.h | 26 +++++++++++++- slicer/slicer/parser.cpp | 81 +++++++++++++++++++++++++++++++++++++------- slicer/slicer/parser.h | 3 +- 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 ClassRef; typedef std::map ClassRefMap; ClassRefMap * & classRefMap(); + typedef std::set 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 @@ -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 HookPtr; + template + class HookMetadata : public HookBase { + public: + virtual const Metadata & GetMetadata() const override { return metadata; } + + private: + static Metadata metadata; + }; + template - class Hook : public HookBase { + class Hook : public HookMetadata { 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 Hooks; private: static Hooks hooks; + static Metadata metadata; }; template @@ -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 @@ -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 >::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 & 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 Slicer::metaDataValue(const std::string & prefix, const std::list & 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 & metadata) const; static boost::optional metaDataValue(const std::string & prefix, const std::list & metadata); static std::list metaDataValues(const std::string & prefix, const std::list & metadata); static std::vector metaDataSplit(const std::string & metadata); -- cgit v1.2.3