diff options
| author | randomdan <randomdan@localhost> | 2014-09-17 20:01:59 +0000 | 
|---|---|---|
| committer | randomdan <randomdan@localhost> | 2014-09-17 20:01:59 +0000 | 
| commit | bd74759d018c2417a107cd8be59007f8f0e61a08 (patch) | |
| tree | 17288e3932b37c0eb45aa61798dad54359f8c496 | |
| parent | Allow overriding of the slicer-typeid property name (diff) | |
| download | slicer-bd74759d018c2417a107cd8be59007f8f0e61a08.tar.bz2 slicer-bd74759d018c2417a107cd8be59007f8f0e61a08.tar.xz slicer-bd74759d018c2417a107cd8be59007f8f0e61a08.zip | |
Make slice metadata for the slicer namespace available at runtime
| -rw-r--r-- | slicer/slicer/modelParts.cpp | 9 | ||||
| -rw-r--r-- | slicer/slicer/modelParts.h | 26 | ||||
| -rw-r--r-- | slicer/slicer/parser.cpp | 81 | ||||
| -rw-r--r-- | 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<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); | 
