diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2015-01-26 01:47:54 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2015-01-26 01:47:54 +0000 | 
| commit | e5e5b4589c2b30e819d55834dbc19348d800cc53 (patch) | |
| tree | 3336a38886a39457a249010865faa34b8b61ff51 | |
| parent | Explicitly implement the auto modelpart deduction templates (diff) | |
| download | slicer-e5e5b4589c2b30e819d55834dbc19348d800cc53.tar.bz2 slicer-e5e5b4589c2b30e819d55834dbc19348d800cc53.tar.xz slicer-e5e5b4589c2b30e819d55834dbc19348d800cc53.zip | |
Add support for enumerationsslicer-1.0.1
| -rw-r--r-- | slicer/slicer/modelParts.cpp | 6 | ||||
| -rw-r--r-- | slicer/slicer/modelParts.h | 44 | ||||
| -rw-r--r-- | slicer/slicer/parser.cpp | 53 | ||||
| -rw-r--r-- | slicer/slicer/parser.h | 6 | ||||
| -rw-r--r-- | slicer/test/compilation.cpp | 5 | ||||
| -rw-r--r-- | slicer/test/initial/enum.xml | 2 | ||||
| -rw-r--r-- | slicer/test/initial/someenums.xml | 5 | ||||
| -rw-r--r-- | slicer/test/preprocessor.cpp | 2 | ||||
| -rw-r--r-- | slicer/test/serializers.cpp | 23 | ||||
| -rw-r--r-- | slicer/test/types.ice | 7 | 
10 files changed, 150 insertions, 3 deletions
| diff --git a/slicer/slicer/modelParts.cpp b/slicer/slicer/modelParts.cpp index ede9d64..b234777 100644 --- a/slicer/slicer/modelParts.cpp +++ b/slicer/slicer/modelParts.cpp @@ -1,4 +1,5 @@  #include "modelParts.h" +#include <boost/lexical_cast.hpp>  namespace Slicer {  	const Metadata emptyMetadata; @@ -12,6 +13,11 @@ namespace Slicer {  		std::invalid_argument(n)  	{  	} +	InvalidEnumerationValue::InvalidEnumerationValue(const std::string & n, const std::string & e) : +		std::invalid_argument("No such value '" + n + "' in " + e) { } + +	InvalidEnumerationValue::InvalidEnumerationValue(::Ice::Int n, const std::string & e) : +		std::invalid_argument("Invalid value " + boost::lexical_cast<std::string>(n) + " in " + e) { }  	ClassNameMap * &  	classNameMap() diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h index 5b1e634..97f7037 100644 --- a/slicer/slicer/modelParts.h +++ b/slicer/slicer/modelParts.h @@ -31,6 +31,12 @@ namespace Slicer {  			UnknownType(const std::string & n);  	}; +	class InvalidEnumerationValue : public std::invalid_argument { +		public: +			InvalidEnumerationValue(const std::string & n, const std::string & e); +			InvalidEnumerationValue(::Ice::Int n, const std::string & e); +	}; +  	template <typename T>  	class TValueTarget {  		public: @@ -537,6 +543,44 @@ namespace Slicer {  	};  	template<typename T> +	class ModelPartForEnum : public ModelPart { +		public: +			typedef T element_type; +			typedef boost::bimap<T, std::string> Enumerations; + +			ModelPartForEnum(T & s) : +				modelPart(s) +			{ +			} + +			ModelPartForEnum(T * s) : +				modelPart(*s) +			{ +			} + +			virtual void OnEachChild(const ChildHandler &) override { } + +			ChildRefPtr GetAnonChildRef(const HookFilter &) override { return NULL; } + +			ChildRefPtr GetChildRef(const std::string &, const HookFilter &) override { return NULL; } + +			virtual bool HasValue() const override { return true; } + +			virtual ModelPartType GetType() const { return mpt_Simple; } + +			virtual const Metadata & GetMetadata() const override { return metadata; } + +			virtual void SetValue(ValueSourcePtr s) override; + +			virtual void GetValue(ValueTargetPtr s) override; + +		private: +			T & modelPart; +			static Metadata metadata; +			static Enumerations enumerations; +	}; + +	template<typename T>  	class ModelPartForSequence : public ModelPart {  		public:  			typedef T element_type; diff --git a/slicer/slicer/parser.cpp b/slicer/slicer/parser.cpp index a4ee2dd..928984e 100644 --- a/slicer/slicer/parser.cpp +++ b/slicer/slicer/parser.cpp @@ -293,6 +293,56 @@ namespace Slicer {  	}  	void +	Slicer::visitEnum(const Slice::EnumPtr & e) +	{ +		if (e->hasMetaData("slicer:ignore")) { return; } + +		components += 1; + +		if (!cpp) return; + +		fprintf(cpp, "// Enumeration %s\n", e->name().c_str()); +		fprintf(cpp, "template<>\nMetadata ModelPartForEnum< %s >::metadata ", +				e->scoped().c_str()); +		copyMetadata(e->getMetaData()); + +		fprintf(cpp, "template<>\nModelPartForEnum< %s >::Enumerations\nModelPartForEnum< %s >::enumerations([]() -> ModelPartForEnum< %s >::Enumerations\n", +				e->scoped().c_str(), +				e->scoped().c_str(), +				e->scoped().c_str()); +		fprintf(cpp, "{\n\tModelPartForEnum< %s >::Enumerations e;\n", +				e->scoped().c_str()); +		for (const auto & ee : e->getEnumerators()) { +			fprintf(cpp, "\te.insert( { %s, \"%s\" } );\n", ee->scoped().c_str(), ee->name().c_str()); +			 +		} +		fprintf(cpp, "\treturn e;\n}());\n\n"); + +		fprintf(cpp, "template<>\nvoid ModelPartForEnum< %s >::SetValue(ValueSourcePtr s) {\n\ +	std::string val;\n\ +	s->set(val);\n\ +	auto i = enumerations.right.find(val);\n\ +	if (i == enumerations.right.end()) throw InvalidEnumerationValue(val, \"%s\");\n\ +	modelPart = i->second;\n\ +}\n\n", +				e->scoped().c_str(), +				e->scoped().c_str()); +		fprintf(cpp, "template<>\nvoid ModelPartForEnum< %s >::GetValue(ValueTargetPtr s) {\n\ +	auto i = enumerations.left.find(modelPart);\n\ +	if (i == enumerations.left.end()) throw InvalidEnumerationValue((::Ice::Int)modelPart, \"%s\");\n\ +	s->get(i->second);\n\ +}\n\n", +				e->scoped().c_str(), +				e->scoped().c_str()); + +		auto name = metaDataValue("slicer:root:", e->getMetaData()); +		defineRootName(e->scoped(), name ? *name : e->name()); + +		fprintf(cpp, "templateMODELPARTFOR(%s, ModelPartForEnum);\n\n", +				e->scoped().c_str()); +	} + +	void  	Slicer::visitSequence(const Slice::SequencePtr & s)  	{  		if (s->hasMetaData("slicer:ignore")) { return; } @@ -436,6 +486,9 @@ namespace Slicer {  		else if (auto dictionary = Slice::DictionaryPtr::dynamicCast(type)) {  			fprintf(cpp, "ModelPartForDictionary");  		} +		else if (auto enumeration = Slice::EnumPtr::dynamicCast(type)) { +			fprintf(cpp, "ModelPartForEnum"); +		}  	}  	void diff --git a/slicer/slicer/parser.h b/slicer/slicer/parser.h index 6253cf5..8e7c469 100644 --- a/slicer/slicer/parser.h +++ b/slicer/slicer/parser.h @@ -33,9 +33,11 @@ namespace Slicer {  			virtual bool visitStructStart(const Slice::StructPtr&) override; -			void visitSequence(const Slice::SequencePtr & s) override; +			virtual void visitEnum(const Slice::EnumPtr &) override; -			void visitDictionary(const Slice::DictionaryPtr & d) override; +			virtual void visitSequence(const Slice::SequencePtr & s) override; + +			virtual void visitDictionary(const Slice::DictionaryPtr & d) override;  			virtual void visitModuleEnd(const Slice::ModulePtr & m) override; diff --git a/slicer/test/compilation.cpp b/slicer/test/compilation.cpp index d48afd0..cc5d2e5 100644 --- a/slicer/test/compilation.cpp +++ b/slicer/test/compilation.cpp @@ -100,3 +100,8 @@ BOOST_AUTO_TEST_CASE( compile_auto_modelpart_type_struct )  	StackTypeTest(TestModule::StructType, ModelPartForStruct, mpt_Complex);  } +BOOST_AUTO_TEST_CASE( compile_auto_modelpart_type_enum ) +{ +	StackTypeTest(TestModule::SomeNumbers, ModelPartForEnum, mpt_Simple); +} + diff --git a/slicer/test/initial/enum.xml b/slicer/test/initial/enum.xml new file mode 100644 index 0000000..06e0abb --- /dev/null +++ b/slicer/test/initial/enum.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<SomeNumbers>FiftyFive</SomeNumbers> diff --git a/slicer/test/initial/someenums.xml b/slicer/test/initial/someenums.xml new file mode 100644 index 0000000..5691fc2 --- /dev/null +++ b/slicer/test/initial/someenums.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<SomeEnums> +  <one>Ten</one> +  <two>FiftyFive</two> +</SomeEnums> diff --git a/slicer/test/preprocessor.cpp b/slicer/test/preprocessor.cpp index c318e84..fa65a44 100644 --- a/slicer/test/preprocessor.cpp +++ b/slicer/test/preprocessor.cpp @@ -13,7 +13,7 @@  namespace fs = boost::filesystem; -const unsigned int COMPONENTS_IN_TEST_ICE = 28; +const unsigned int COMPONENTS_IN_TEST_ICE = 30;  BOOST_FIXTURE_TEST_SUITE ( preprocessor, FileStructure ); diff --git a/slicer/test/serializers.cpp b/slicer/test/serializers.cpp index a13bb49..df6c052 100644 --- a/slicer/test/serializers.cpp +++ b/slicer/test/serializers.cpp @@ -222,6 +222,19 @@ checkBare(const TestModule::BareContainers & bc)  	BOOST_REQUIRE_EQUAL(bc.bareMap.size(), 2);  } +void +checkSomeEnums(const TestModule::SomeEnumsPtr & se) +{ +	BOOST_REQUIRE_EQUAL(se->one, TestModule::Ten); +	BOOST_REQUIRE_EQUAL(se->two, TestModule::FiftyFive); +} + +void +checkSomeNumbers(const TestModule::SomeNumbers & sn) +{ +	BOOST_REQUIRE_EQUAL(sn, TestModule::FiftyFive); +} +  xmlpp::Document *  readXml(const fs::path & path)  { @@ -375,6 +388,16 @@ BOOST_AUTO_TEST_CASE( xml_barecontainers_xml )  	verifyByFile<TestModule::BareContainers, Slicer::XmlFileDeserializer>("bare.xml", checkBare);  } +BOOST_AUTO_TEST_CASE( xml_classOfEnums_xml ) +{ +	verifyByFile<TestModule::SomeEnumsPtr, Slicer::XmlFileDeserializer>("someenums.xml", checkSomeEnums); +} + +BOOST_AUTO_TEST_CASE( xml_rootEnums_xml ) +{ +	verifyByFile<TestModule::SomeNumbers, Slicer::XmlFileDeserializer>("enum.xml", checkSomeNumbers); +} +  BOOST_AUTO_TEST_SUITE_END(); diff --git a/slicer/test/types.ice b/slicer/test/types.ice index 4192448..198116b 100644 --- a/slicer/test/types.ice +++ b/slicer/test/types.ice @@ -1,6 +1,9 @@  [["cpp:include:boost/date_time/posix_time/posix_time_types.hpp"]]  module TestModule { +	enum SomeNumbers { +		One = 1, Ten = 10, FiftyFive = 55 +	};  	struct DateTime {  		short year;  		short month; @@ -106,6 +109,10 @@ module TestModule {  		[ "slicer:xml:bare" ]  		ClassMap bareMap;  	}; +	class SomeEnums { +		SomeNumbers one; +		SomeNumbers two; +	};  };  module TestModule2 { | 
