diff options
-rw-r--r-- | slicer/slicer/modelParts.h | 93 | ||||
-rw-r--r-- | slicer/slicer/parser.cpp | 61 | ||||
-rw-r--r-- | slicer/slicer/slicer.h | 4 | ||||
-rw-r--r-- | slicer/test/types.ice | 7 |
4 files changed, 131 insertions, 34 deletions
diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h index bdbe40f..761c557 100644 --- a/slicer/slicer/modelParts.h +++ b/slicer/slicer/modelParts.h @@ -4,6 +4,7 @@ #include <Ice/Config.h> #include <IceUtil/Shared.h> #include <IceUtil/Handle.h> +#include <IceUtil/Optional.h> #include <Ice/Handle.h> #include <Slice/Parser.h> #include <stdexcept> @@ -65,6 +66,8 @@ namespace Slicer { template<typename T> class ModelPartForSimple : public ModelPart { public: + typedef T element_type; + ModelPartForSimple(T & h) : Member(h) { @@ -83,6 +86,70 @@ namespace Slicer { }; template<typename T> + class ModelPartForOptional : public ModelPart { + public: + ModelPartForOptional(IceUtil::Optional< typename T::element_type > & h) : + OptionalMember(h) + { + if (OptionalMember) { + modelPart = new T(*OptionalMember); + } + } + ModelPartForOptional(IceUtil::Optional< typename T::element_type > * h) : + OptionalMember(*h) + { + if (OptionalMember) { + modelPart = new T(*OptionalMember); + } + } + virtual void OnEachChild(const ChildHandler & ch) + { + if (OptionalMember) { + modelPart->OnEachChild(ch); + } + } + virtual void Complete() override + { + if (OptionalMember) { + modelPart->Complete(); + } + } + virtual void Create() override + { + if (!OptionalMember) { + OptionalMember = typename T::element_type(); + modelPart = new T(*OptionalMember); + modelPart->Create(); + } + } + virtual ModelPartPtr GetChild(const std::string & name) override + { + if (OptionalMember) { + return modelPart->GetChild(name); + } + return NULL; + } + virtual void SetValue(ValueSourcePtr s) override + { + if (OptionalMember) { + modelPart->SetValue(s); + } + } + virtual void GetValue(ValueTargetPtr s) override + { + if (!OptionalMember) { + OptionalMember = typename T::element_type(); + modelPart = new T(*OptionalMember); + } + modelPart->GetValue(s); + } + + private: + IceUtil::Optional< typename T::element_type > & OptionalMember; + ModelPartPtr modelPart; + }; + + template<typename T> class ModelPartForComplex : public ModelPart { public: class HookBase : public IceUtil::Shared { @@ -125,35 +192,39 @@ namespace Slicer { }; template<typename T> - class ModelPartForClass : public ModelPartForComplex<T> { + class ModelPartForClass : public ModelPartForComplex<typename T::element_type> { public: - ModelPartForClass(IceInternal::Handle<T> & h) : + typedef T element_type; + + ModelPartForClass(T & h) : ModelObject(h) { } - ModelPartForClass(IceInternal::Handle<T> * h) : + ModelPartForClass(T * h) : ModelObject(*h) { } virtual void Create() override { - ModelObject = new T(); + ModelObject = new typename T::element_type(); } - T & GetModel() override + typename T::element_type & GetModel() override { return *ModelObject; } private: - IceInternal::Handle<T> & ModelObject; + T & ModelObject; }; template<typename T> class ModelPartForStruct : public ModelPartForComplex<T> { public: + typedef T element_type; + ModelPartForStruct(T & o) : ModelObject(o) { @@ -181,7 +252,7 @@ namespace Slicer { { } - ModelPartForClassRoot(IceInternal::Handle<T> o) : + ModelPartForClassRoot(T o) : ModelPartForClass<T>(ModelObject) { ModelObject = o; @@ -201,19 +272,21 @@ namespace Slicer { ch(rootName, new ModelPartForClass<T>(ModelObject)); } - T & GetModel() override + typename T::element_type & GetModel() override { return *ModelObject; } private: - IceInternal::Handle<T> ModelObject; + T ModelObject; static std::string rootName; }; template<typename T> class ModelPartForSequence : public ModelPart { public: + typedef T element_type; + ModelPartForSequence(T & s) : sequence(s) { @@ -279,6 +352,8 @@ namespace Slicer { template<typename T> class ModelPartForDictionary : public ModelPart { public: + typedef T element_type; + ModelPartForDictionary(T & d) : dictionary(d) { diff --git a/slicer/slicer/parser.cpp b/slicer/slicer/parser.cpp index fd1d9b1..680ca2f 100644 --- a/slicer/slicer/parser.cpp +++ b/slicer/slicer/parser.cpp @@ -58,18 +58,34 @@ namespace Slicer { fprintf(cpp, "\t\t{ \"%s\", ", name ? name->c_str() : dm->name().c_str()); auto type = dm->type(); - fprintf(cpp, "new ModelPartForClass< %s::%s >::Hook< %s, &%s::%s::%s, ", - modulePath().c_str(), c->name().c_str(), - Slice::typeToString(type).c_str(), + fprintf(cpp, "new ModelPartForClass< %s::%sPtr >::Hook< ", + modulePath().c_str(), c->name().c_str()); + if (dm->optional()) { + fprintf(cpp, "::IceUtil::Optional< %s >", + Slice::typeToString(type).c_str()); + } + else { + fprintf(cpp, "%s", + Slice::typeToString(type).c_str()); + } + fprintf(cpp, ", &%s::%s::%s, ", modulePath().c_str(), c->name().c_str(), dm->name().c_str()); + if (dm->optional()) { + fprintf(cpp, "ModelPartForOptional< "); + } createNewModelPartPtrFor(type); - fprintf(cpp, " >() },\n"); + fprintf(cpp, "< %s", + Slice::typeToString(type).c_str()); + if (dm->optional()) { + fprintf(cpp, " > "); + } + fprintf(cpp, " > >() },\n"); } fprintf(cpp, "\t};\n"); fprintf(cpp, "template<>\n"); auto name = metaDataValue("slicer:root:", c->getMetaData()); - fprintf(cpp, "std::string ModelPartForClassRoot< %s::%s >::rootName(\"%s\");\n\n", + fprintf(cpp, "std::string ModelPartForClassRoot< %s::%sPtr >::rootName(\"%s\");\n\n", modulePath().c_str(), c->name().c_str(), name ? name->c_str() : c->name().c_str()); return true; @@ -96,7 +112,8 @@ namespace Slicer { Slice::typeToString(type).c_str(), modulePath().c_str(), c->name().c_str(), dm->name().c_str()); createNewModelPartPtrFor(type); - fprintf(cpp, " >() },\n"); + fprintf(cpp, " < %s > >() },\n", + Slice::typeToString(type).c_str()); } fprintf(cpp, "\t};\n\n"); @@ -123,18 +140,19 @@ namespace Slicer { fprintf(cpp, "\tsequence.push_back(%s());\n", Slice::typeToString(s->type()).c_str()); fprintf(cpp, "\treturn new "); - createNewModelPartPtrFor(s->type()); - fprintf(cpp, "(sequence.back());\n}\n\n"); - + auto etype = s->type(); + createNewModelPartPtrFor(etype); + fprintf(cpp, "< %s >(sequence.back());\n}\n\n", + Slice::typeToString(etype).c_str()); fprintf(cpp, "template<>\n"); fprintf(cpp, "ModelPartPtr\n"); fprintf(cpp, "ModelPartForSequence< %s::%s >::elementModelPart(typename %s::%s::value_type & e) const {\n", modulePath().c_str(), s->name().c_str(), modulePath().c_str(), s->name().c_str()); - auto etype = s->type(); fprintf(cpp, "\treturn new "); createNewModelPartPtrFor(etype); - fprintf(cpp, "(e);\n}\n\n"); + fprintf(cpp, "< %s >(e);\n}\n\n", + Slice::typeToString(etype).c_str()); fprintf(cpp, "template<>\n"); auto ename = metaDataValue("slicer:element:", s->getMetaData()); fprintf(cpp, "std::string ModelPartForSequence< %s::%s >::elementName(\"%s\");\n\n", @@ -169,7 +187,8 @@ namespace Slicer { Slice::typeToString(ktype).c_str(), modulePath().c_str(), d->name().c_str()); createNewModelPartPtrFor(ktype); - fprintf(cpp, " >() },\n\t\t{ \"%s\", ", + fprintf(cpp, "< %s > >() },\n\t\t{ \"%s\", ", + Slice::typeToString(ktype).c_str(), vname ? vname->c_str() : "value"); auto vtype = d->valueType(); fprintf(cpp, "new ModelPartForDictionaryElement< %s::%s >::Hook< %s*, &ModelPartForDictionaryElement< %s::%s >::value, ", @@ -177,7 +196,8 @@ namespace Slicer { Slice::typeToString(vtype).c_str(), modulePath().c_str(), d->name().c_str()); createNewModelPartPtrFor(vtype); - fprintf(cpp, " >() },\n"); + fprintf(cpp, "< %s > >() },\n", + Slice::typeToString(vtype).c_str()); fprintf(cpp, "\t};\n"); fprintf(cpp, "\n"); } @@ -193,24 +213,19 @@ namespace Slicer { Slicer::createNewModelPartPtrFor(const Slice::TypePtr & type) const { if (auto builtin = Slice::BuiltinPtr::dynamicCast(type)) { - fprintf(cpp, "ModelPartForSimple< %s >", - Slice::typeToString(type).c_str()); + fprintf(cpp, "ModelPartForSimple "); } else if (auto complexClass = Slice::ClassDeclPtr::dynamicCast(type)) { - fprintf(cpp, "ModelPartForClass< %s::element_type >", - Slice::typeToString(type).c_str()); + fprintf(cpp, "ModelPartForClass "); } else if (auto complexStruct = Slice::StructPtr::dynamicCast(type)) { - fprintf(cpp, "ModelPartForStruct< %s >", - Slice::typeToString(type).c_str()); + fprintf(cpp, "ModelPartForStruct "); } else if (auto sequence = Slice::SequencePtr::dynamicCast(type)) { - fprintf(cpp, "ModelPartForSequence< %s >", - Slice::typeToString(type).c_str()); + fprintf(cpp, "ModelPartForSequence "); } else if (auto dictionary = Slice::DictionaryPtr::dynamicCast(type)) { - fprintf(cpp, "ModelPartForDictionary< %s >", - Slice::typeToString(type).c_str()); + fprintf(cpp, "ModelPartForDictionary "); } } diff --git a/slicer/slicer/slicer.h b/slicer/slicer/slicer.h index 8421774..55ccf00 100644 --- a/slicer/slicer/slicer.h +++ b/slicer/slicer/slicer.h @@ -11,7 +11,7 @@ namespace Slicer { IceInternal::Handle<Object> Deserialize(const boost::filesystem::path & path) { - IceUtil::Handle<ModelPartForClassRoot<Object>> root = new ModelPartForClassRoot<Object>(); + IceUtil::Handle<ModelPartForClassRoot<IceInternal::Handle<Object>>> root = new ModelPartForClassRoot<IceInternal::Handle<Object>>(); SerializerPtr serializer = new Serializer(); serializer->Deserialize(path, root); return &root->GetModel(); @@ -21,7 +21,7 @@ namespace Slicer { void Serialize(IceInternal::Handle<Object> object, const boost::filesystem::path & path) { - IceUtil::Handle<ModelPartForClassRoot<Object>> root = new ModelPartForClassRoot<Object>(object); + IceUtil::Handle<ModelPartForClassRoot<IceInternal::Handle<Object>>> root = new ModelPartForClassRoot<IceInternal::Handle<Object>>(object); SerializerPtr serializer = new Serializer(); serializer->Serialize(path, root); } diff --git a/slicer/test/types.ice b/slicer/test/types.ice index 0fef708..46f834f 100644 --- a/slicer/test/types.ice +++ b/slicer/test/types.ice @@ -21,6 +21,13 @@ module TestModule { sequence<StructType> Structs; dictionary<int, ClassType> ClassMap; dictionary<int, StructType> StructMap; + class Optionals { + optional(0) int optSimple; + optional(1) StructType optStruct; + optional(2) ClassType optClass; + optional(3) Classes optSeq; + optional(4) ClassMap optDict; + }; class ClassClass { ClassType cls; StructType str; |