summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2015-01-26 01:47:54 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2015-01-26 01:47:54 +0000
commite5e5b4589c2b30e819d55834dbc19348d800cc53 (patch)
tree3336a38886a39457a249010865faa34b8b61ff51
parentExplicitly implement the auto modelpart deduction templates (diff)
downloadslicer-e5e5b4589c2b30e819d55834dbc19348d800cc53.tar.bz2
slicer-e5e5b4589c2b30e819d55834dbc19348d800cc53.tar.xz
slicer-e5e5b4589c2b30e819d55834dbc19348d800cc53.zip
Add support for enumerationsslicer-1.0.1
-rw-r--r--slicer/slicer/modelParts.cpp6
-rw-r--r--slicer/slicer/modelParts.h44
-rw-r--r--slicer/slicer/parser.cpp53
-rw-r--r--slicer/slicer/parser.h6
-rw-r--r--slicer/test/compilation.cpp5
-rw-r--r--slicer/test/initial/enum.xml2
-rw-r--r--slicer/test/initial/someenums.xml5
-rw-r--r--slicer/test/preprocessor.cpp2
-rw-r--r--slicer/test/serializers.cpp23
-rw-r--r--slicer/test/types.ice7
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 {