diff options
author | Dan Goodliffe <daniel.goodliffe@pressassociation.com> | 2016-02-05 16:39:51 +0000 |
---|---|---|
committer | Dan Goodliffe <daniel.goodliffe@pressassociation.com> | 2016-02-05 16:39:51 +0000 |
commit | e2fe79e103b311426efff6bee328babbc24928df (patch) | |
tree | 65924375daa9fa2b700e33afd16d652f39267647 | |
parent | Build most things by default (diff) | |
download | slicer-e2fe79e103b311426efff6bee328babbc24928df.tar.bz2 slicer-e2fe79e103b311426efff6bee328babbc24928df.tar.xz slicer-e2fe79e103b311426efff6bee328babbc24928df.zip |
Internalize all slicer components
-rw-r--r-- | slicer/slicer/modelParts.h | 80 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.cpp | 58 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.h | 337 | ||||
-rw-r--r-- | slicer/slicer/modelPartsTypes.impl.h | 447 | ||||
-rw-r--r-- | slicer/slicer/parser.cpp | 53 | ||||
-rw-r--r-- | slicer/slicer/slicer.h | 4 | ||||
-rw-r--r-- | slicer/test/compilation.cpp | 10 |
7 files changed, 613 insertions, 376 deletions
diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h index 8cf525a..6f9338d 100644 --- a/slicer/slicer/modelParts.h +++ b/slicer/slicer/modelParts.h @@ -121,39 +121,13 @@ namespace Slicer { virtual const Metadata & GetMetadata() const = 0; }; -#define templateMODELPARTFOR(Type) \ - template <class T> ModelPartPtr DLL_PUBLIC ModelPartFor(IceUtil::Optional<Type> & t); \ - template <class T> ModelPartPtr DLL_PUBLIC ModelPartFor(IceUtil::Optional<Type> * t); \ - template <class T> ModelPartPtr DLL_PUBLIC ModelPartFor(Type & t); \ - template <class T> ModelPartPtr DLL_PUBLIC ModelPartFor(Type * t); -#define MODELPARTFOR(Type) \ - ModelPartPtr DLL_PUBLIC ModelPartFor(IceUtil::Optional<Type> & t); \ - ModelPartPtr DLL_PUBLIC ModelPartFor(IceUtil::Optional<Type> * t); \ - ModelPartPtr DLL_PUBLIC ModelPartFor(Type & t); \ - ModelPartPtr DLL_PUBLIC ModelPartFor(Type * t); - templateMODELPARTFOR(IceInternal::Handle<T>); - templateMODELPARTFOR(std::vector<T>); - templateMODELPARTFOR(std::list<T>); - template <class K, class V> ModelPartPtr DLL_PUBLIC ModelPartFor(std::map<K, V> & t); - template <class K, class V> ModelPartPtr DLL_PUBLIC ModelPartFor(std::map<K, V> * t); - MODELPARTFOR(std::string); - MODELPARTFOR(bool); - MODELPARTFOR(Ice::Float); - MODELPARTFOR(Ice::Double); - MODELPARTFOR(Ice::Byte); - MODELPARTFOR(Ice::Short); - MODELPARTFOR(Ice::Int); - MODELPARTFOR(Ice::Long); - templateMODELPARTFOR(T); -#undef templateMODELPARTFOR -#undef MODELPARTFOR - class ChildRef : public IceUtil::Shared { public: virtual ModelPartPtr Child() const = 0; virtual const Metadata & ChildMetaData() const = 0; }; typedef IceUtil::Handle<ChildRef> ChildRefPtr; + class DLL_PUBLIC ImplicitChildRef : public ChildRef { public: ImplicitChildRef(ModelPartPtr); @@ -164,6 +138,7 @@ namespace Slicer { private: ModelPartPtr mpp; }; + class DLL_PUBLIC MemberChildRef : public ChildRef { public: MemberChildRef(ModelPartPtr, const Metadata &); @@ -180,6 +155,11 @@ namespace Slicer { public: virtual ~ModelPart() = default; + template<typename T> + static ModelPartPtr CreateFor(T & t); + template<typename T> + static ModelPartPtr CreateRootFor(T & t); + virtual void OnEachChild(const ChildHandler &) = 0; ModelPartPtr GetAnonChild(const HookFilter & = HookFilter()); ModelPartPtr GetChild(const std::string & memberName, const HookFilter & = HookFilter()); @@ -202,47 +182,21 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForRoot : public ModelPart { + class ModelPartForRoot : public ModelPart { public: - ModelPartForRoot(T & o) : - ModelObject(&o), - mp(ModelPartFor(*ModelObject)) - { - } - - virtual ChildRefPtr GetAnonChildRef(const HookFilter &) override - { - mp->Create(); - return new ImplicitChildRef(mp); - } - - virtual ChildRefPtr GetChildRef(const std::string & name, const HookFilter &) override - { - if (name != rootName) { - throw IncorrectElementName(name); - } - mp->Create(); - return new ImplicitChildRef(mp); - } - - virtual void OnEachChild(const ChildHandler & ch) override - { - ch(rootName, mp, NULL); - } - - virtual bool HasValue() const override { return ModelObject && mp->HasValue(); } - - virtual ModelPartType GetType() const override - { - return mp->GetType(); - } - - virtual bool IsOptional() const override { return mp->IsOptional(); } + ModelPartForRoot(T & o); + + virtual ChildRefPtr GetAnonChildRef(const HookFilter &) override; + virtual ChildRefPtr GetChildRef(const std::string & name, const HookFilter &) override; + virtual void OnEachChild(const ChildHandler & ch) override; + virtual bool HasValue() const override; + virtual ModelPartType GetType() const override; + virtual bool IsOptional() const override; private: T * ModelObject; ModelPartPtr mp; - DLL_PUBLIC static std::string rootName; + static std::string rootName; }; } diff --git a/slicer/slicer/modelPartsTypes.cpp b/slicer/slicer/modelPartsTypes.cpp index 7f07b42..4540060 100644 --- a/slicer/slicer/modelPartsTypes.cpp +++ b/slicer/slicer/modelPartsTypes.cpp @@ -1,11 +1,6 @@ -#include "modelPartsTypes.h" +#include "modelPartsTypes.impl.h" namespace Slicer { -#define MODELPARTFOR(Type, ModelPart) \ - ModelPartPtr ModelPartFor(IceUtil::Optional<Type> & t) { return new ModelPartForOptional< ModelPart<Type> >(t); } \ - ModelPartPtr ModelPartFor(IceUtil::Optional<Type> * t) { return new ModelPartForOptional< ModelPart<Type> >(t); } \ - ModelPartPtr ModelPartFor(Type & t) { return new ModelPart< Type >(t); } \ - ModelPartPtr ModelPartFor(Type * t) { return new ModelPart< Type >(t); } MODELPARTFOR(std::string, ModelPartForSimple); MODELPARTFOR(bool, ModelPartForSimple); MODELPARTFOR(Ice::Float, ModelPartForSimple); @@ -14,25 +9,42 @@ namespace Slicer { MODELPARTFOR(Ice::Short, ModelPartForSimple); MODELPARTFOR(Ice::Int, ModelPartForSimple); MODELPARTFOR(Ice::Long, ModelPartForSimple); -#undef MODELPARTFOR - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<std::string>::rootName = "String"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<bool>::rootName = "Boolean"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<Ice::Float>::rootName = "Float"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<Ice::Double>::rootName = "Double"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<Ice::Byte>::rootName = "Byte"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<Ice::Short>::rootName = "Short"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<Ice::Int>::rootName = "Int"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<Ice::Long>::rootName = "Long"; + template<> std::string Slicer::ModelPartForRoot<std::string>::rootName = "String"; + template<> std::string Slicer::ModelPartForRoot<bool>::rootName = "Boolean"; + template<> std::string Slicer::ModelPartForRoot<Ice::Float>::rootName = "Float"; + template<> std::string Slicer::ModelPartForRoot<Ice::Double>::rootName = "Double"; + template<> std::string Slicer::ModelPartForRoot<Ice::Byte>::rootName = "Byte"; + template<> std::string Slicer::ModelPartForRoot<Ice::Short>::rootName = "Short"; + template<> std::string Slicer::ModelPartForRoot<Ice::Int>::rootName = "Int"; + template<> std::string Slicer::ModelPartForRoot<Ice::Long>::rootName = "Long"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<IceUtil::Optional<std::string>>::rootName = "OptionalString"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<IceUtil::Optional<bool>>::rootName = "OptionalBoolean"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Float>>::rootName = "OptionalFloat"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Double>>::rootName = "OptionalDouble"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Byte>>::rootName = "OptionalByte"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Short>>::rootName = "OptionalShort"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Int>>::rootName = "OptionalInt"; - template<> DLL_PUBLIC std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Long>>::rootName = "OptionalLong"; + template<> std::string Slicer::ModelPartForRoot<IceUtil::Optional<std::string>>::rootName = "OptionalString"; + template<> std::string Slicer::ModelPartForRoot<IceUtil::Optional<bool>>::rootName = "OptionalBoolean"; + template<> std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Float>>::rootName = "OptionalFloat"; + template<> std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Double>>::rootName = "OptionalDouble"; + template<> std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Byte>>::rootName = "OptionalByte"; + template<> std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Short>>::rootName = "OptionalShort"; + template<> std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Int>>::rootName = "OptionalInt"; + template<> std::string Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Long>>::rootName = "OptionalLong"; + + template class Slicer::ModelPartForRoot<std::string>; + template class Slicer::ModelPartForRoot<bool>; + template class Slicer::ModelPartForRoot<Ice::Float>; + template class Slicer::ModelPartForRoot<Ice::Double>; + template class Slicer::ModelPartForRoot<Ice::Byte>; + template class Slicer::ModelPartForRoot<Ice::Short>; + template class Slicer::ModelPartForRoot<Ice::Int>; + template class Slicer::ModelPartForRoot<Ice::Long>; + + template class Slicer::ModelPartForRoot<IceUtil::Optional<std::string>>; + template class Slicer::ModelPartForRoot<IceUtil::Optional<bool>>; + template class Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Float>>; + template class Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Double>>; + template class Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Byte>>; + template class Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Short>>; + template class Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Int>>; + template class Slicer::ModelPartForRoot<IceUtil::Optional<Ice::Long>>; void ModelPartForSimpleBase::OnEachChild(const ChildHandler &) { } ChildRefPtr ModelPartForSimpleBase::GetAnonChildRef(const HookFilter &) { return NULL; } diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h index 47c08ea..02ef8c8 100644 --- a/slicer/slicer/modelPartsTypes.h +++ b/slicer/slicer/modelPartsTypes.h @@ -15,20 +15,16 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForSimple : public ModelPartForSimpleBase { + class ModelPartForSimple : public ModelPartForSimpleBase { public: typedef T element_type; - ModelPartForSimple(T & h) : - Member(h) - { - } - ModelPartForSimple(T * h) : - Member(*h) - { - } - virtual void SetValue(ValueSourcePtr s) override { s->set(Member); } - virtual void GetValue(ValueTargetPtr s) override { s->get(Member); } + ModelPartForSimple(T & h); + + ModelPartForSimple(T * h); + + virtual void SetValue(ValueSourcePtr s) override; + virtual void GetValue(ValueTargetPtr s) override; private: T & Member; @@ -45,18 +41,13 @@ namespace Slicer { }; template<typename T, typename M, T M::* MV> - class DLL_PUBLIC ModelPartForConverted : public ModelPartForConvertedBase { + class ModelPartForConverted : public ModelPartForConvertedBase { public: typedef T element_type; - ModelPartForConverted(T & h) : - Member(h) - { - } - ModelPartForConverted(T * h) : - Member(*h) - { - } + ModelPartForConverted(T & h); + + ModelPartForConverted(T * h); virtual void SetValue(ValueSourcePtr s) override; virtual void GetValue(ValueTargetPtr s) override; @@ -65,81 +56,25 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForOptional : public ModelPart { + 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) override - { - 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 ChildRefPtr GetAnonChildRef(const HookFilter & flt) override - { - if (OptionalMember) { - return modelPart->GetAnonChildRef(flt); - } - return NULL; - } - virtual ChildRefPtr GetChildRef(const std::string & name, const HookFilter & flt) override - { - if (OptionalMember) { - return modelPart->GetChildRef(name, flt); - } - 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); - } - - virtual bool HasValue() const override { return OptionalMember && modelPart->HasValue(); } - - virtual ModelPartType GetType() const - { - return T::type; - } - - virtual bool IsOptional() const override { return true; }; - - virtual const Metadata & GetMetadata() const override { return modelPart->GetMetadata(); } + ModelPartForOptional(IceUtil::Optional< typename T::element_type > & h); + ModelPartForOptional(IceUtil::Optional< typename T::element_type > * h); + virtual void OnEachChild(const ChildHandler & ch) override; + virtual void Complete() override; + virtual void Create() override; + virtual ChildRefPtr GetAnonChildRef(const HookFilter & flt) override; + virtual ChildRefPtr GetChildRef(const std::string & name, const HookFilter & flt) override; + virtual void SetValue(ValueSourcePtr s) override; + virtual void GetValue(ValueTargetPtr s) override; + + virtual bool HasValue() const override; + + virtual ModelPartType GetType() const; + + virtual bool IsOptional() const override; + + virtual const Metadata & GetMetadata() const override; private: IceUtil::Optional< typename T::element_type > & OptionalMember; @@ -153,7 +88,7 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForComplex : public ModelPartForComplexBase { + class ModelPartForComplex : public ModelPartForComplexBase { public: class HookBase : public HookCommon { public: @@ -193,34 +128,12 @@ namespace Slicer { const std::string name; }; - virtual void OnEachChild(const ChildHandler & ch) - { - for (const auto & h : hooks) { - auto modelPart = h->Get(GetModel()); - ch(h->PartName(), modelPart && modelPart->HasValue() ? modelPart : ModelPartPtr(), h); - } - } - - virtual ChildRefPtr GetAnonChildRef(const HookFilter & flt) override - { - for (const auto & h : hooks) { - if (!flt || flt(h)) { - return new MemberChildRef(h->Get(GetModel()), h->GetMetadata()); - } - } - return NULL; - } - ChildRefPtr GetChildRef(const std::string & name, const HookFilter & flt) override - { - for (const auto & h : hooks) { - if (h->PartName() == name && (!flt || flt(h))) { - return new MemberChildRef(h->Get(GetModel()), h->GetMetadata()); - } - } - return NULL; - } + virtual void OnEachChild(const ChildHandler & ch); + + virtual ChildRefPtr GetAnonChildRef(const HookFilter & flt) override; + ChildRefPtr GetChildRef(const std::string & name, const HookFilter & flt) override; - virtual const Metadata & GetMetadata() const override { return metadata; } + virtual const Metadata & GetMetadata() const override; virtual T * GetModel() = 0; @@ -232,44 +145,25 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForClass : public ModelPartForComplex<typename T::element_type> { + class ModelPartForClass : public ModelPartForComplex<typename T::element_type> { public: typedef T element_type; - ModelPartForClass(T & h) : - ModelObject(h) - { - } - - ModelPartForClass(T * h) : - ModelObject(*h) - { - } - - virtual void Create() override - { - ModelObject = new typename T::element_type(); - } - - typename T::element_type * GetModel() override - { - return ModelObject.get(); - } - - virtual ModelPartPtr GetSubclassModelPart(const std::string & name) override - { - auto ref = classRefMap()->find(ModelPart::ToModelTypeName(name)); - if (ref == classRefMap()->end()) { - throw UnknownType(name); - } - return ref->second(&this->ModelObject); - } - - virtual bool HasValue() const override { return ModelObject; } + ModelPartForClass(T & h); + + ModelPartForClass(T * h); + + virtual void Create() override; + + typename T::element_type * GetModel() override; + + virtual ModelPartPtr GetSubclassModelPart(const std::string & name) override; + + virtual bool HasValue() const override; virtual TypeId GetTypeId() const override; - virtual IceUtil::Optional<std::string> GetTypeIdProperty() const override { return typeIdProperty; } + virtual IceUtil::Optional<std::string> GetTypeIdProperty() const override; private: T & ModelObject; @@ -277,26 +171,17 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForStruct : public ModelPartForComplex<T> { + class ModelPartForStruct : public ModelPartForComplex<T> { public: typedef T element_type; - ModelPartForStruct(T & o) : - ModelObject(o) - { - } + ModelPartForStruct(T & o); - ModelPartForStruct(T * o) : - ModelObject(*o) - { - } + ModelPartForStruct(T * o); - T * GetModel() override - { - return &ModelObject; - } + T * GetModel() override; - virtual bool HasValue() const override { return true; } + virtual bool HasValue() const override; private: T & ModelObject; @@ -313,22 +198,16 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForEnum : public ModelPartForEnumBase { + class ModelPartForEnum : public ModelPartForEnumBase { public: typedef T element_type; typedef boost::bimap<T, std::string> Enumerations; - ModelPartForEnum(T & s) : - modelPart(s) - { - } + ModelPartForEnum(T & s); - ModelPartForEnum(T * s) : - modelPart(*s) - { - } + ModelPartForEnum(T * s); - virtual const Metadata & GetMetadata() const override { return metadata; } + virtual const Metadata & GetMetadata() const override; virtual void SetValue(ValueSourcePtr s) override; @@ -348,36 +227,21 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForSequence : public ModelPartForSequenceBase { + class ModelPartForSequence : public ModelPartForSequenceBase { public: typedef T element_type; - ModelPartForSequence(T & s) : - sequence(s) - { - } - - ModelPartForSequence(T * s) : - sequence(*s) - { - } - - virtual void OnEachChild(const ChildHandler & ch) override - { - for(auto & element : sequence) { - ch(elementName, elementModelPart(element), NULL); - } - } - - ChildRefPtr GetAnonChildRef(const HookFilter &) override - { - sequence.push_back(typename element_type::value_type()); - return new ImplicitChildRef(ModelPartFor(sequence.back())); - } + ModelPartForSequence(T & s); + + ModelPartForSequence(T * s); + + virtual void OnEachChild(const ChildHandler & ch) override; + + ChildRefPtr GetAnonChildRef(const HookFilter &) override; ChildRefPtr GetChildRef(const std::string &, const HookFilter &) override; - virtual const Metadata & GetMetadata() const override { return metadata; } + virtual const Metadata & GetMetadata() const override; private: ModelPartPtr elementModelPart(typename T::value_type &) const; @@ -388,35 +252,24 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForDictionaryElement : public ModelPartForComplex<ModelPartForDictionaryElement<T> > { + class ModelPartForDictionaryElement : public ModelPartForComplex<ModelPartForDictionaryElement<T> > { public: - ModelPartForDictionaryElement(typename T::key_type * k, typename T::mapped_type * v) : - key(k), - value(v) - { - } + ModelPartForDictionaryElement(typename T::key_type * k, typename T::mapped_type * v); - ModelPartForDictionaryElement<T> * GetModel() override - { - return this; - } + ModelPartForDictionaryElement<T> * GetModel() override; - virtual bool HasValue() const override { return true; } + virtual bool HasValue() const override; typename T::key_type * key; typename T::mapped_type * value; }; template<typename T> - class DLL_PUBLIC ModelPartForDictionaryElementInserter : public ModelPartForDictionaryElement<T> { + class ModelPartForDictionaryElementInserter : public ModelPartForDictionaryElement<T> { public: - ModelPartForDictionaryElementInserter(T & d) : - ModelPartForDictionaryElement<T>(&key, &value), - dictionary(d) - { - } + ModelPartForDictionaryElementInserter(T & d); - virtual void Complete() override { dictionary.insert(typename T::value_type(key, value)); } + virtual void Complete() override; mutable typename T::key_type key; mutable typename T::mapped_type value; @@ -433,41 +286,21 @@ namespace Slicer { }; template<typename T> - class DLL_PUBLIC ModelPartForDictionary : public ModelPartForDictionaryBase { + class ModelPartForDictionary : public ModelPartForDictionaryBase { public: typedef T element_type; - ModelPartForDictionary(T & d) : - dictionary(d) - { - } - - ModelPartForDictionary(T * d) : - dictionary(*d) - { - } - - virtual void OnEachChild(const ChildHandler & ch) override - { - for (auto & pair : dictionary) { - ch(pairName, new ModelPartForDictionaryElement<T>(const_cast<typename T::key_type *>(&pair.first), &pair.second), NULL); - } - } - - ChildRefPtr GetAnonChildRef(const HookFilter &) override - { - return new ImplicitChildRef(new ModelPartForDictionaryElementInserter<T>(dictionary)); - } - - ChildRefPtr GetChildRef(const std::string & name, const HookFilter &) override - { - if (name != pairName) { - throw IncorrectElementName(name); - } - return new ImplicitChildRef(new ModelPartForDictionaryElementInserter<T>(dictionary)); - } - - virtual const Metadata & GetMetadata() const override { return metadata; } + ModelPartForDictionary(T & d); + + ModelPartForDictionary(T * d); + + virtual void OnEachChild(const ChildHandler & ch) override; + + ChildRefPtr GetAnonChildRef(const HookFilter &) override; + + ChildRefPtr GetChildRef(const std::string & name, const HookFilter &) override; + + virtual const Metadata & GetMetadata() const override; private: T & dictionary; diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h new file mode 100644 index 0000000..2f34fa1 --- /dev/null +++ b/slicer/slicer/modelPartsTypes.impl.h @@ -0,0 +1,447 @@ +#ifndef SLICER_MODELPARTSTYPES_IMPL_H +#define SLICER_MODELPARTSTYPES_IMPL_H + +#include "modelPartsTypes.h" + +#define MODELPARTFOR(Type, ModelPartType) \ + template<> ModelPartPtr ModelPart::CreateFor(Type & s) { return new ModelPartType<Type>(s); } \ + template<> ModelPartPtr ModelPart::CreateFor(IceUtil::Optional<Type> & s) { return new ModelPartForOptional<ModelPartType<Type> >(s); } \ + template<> ModelPartPtr ModelPart::CreateRootFor(Type & s) { return new ModelPartForRoot<Type>(s); } \ + template<> ModelPartPtr ModelPart::CreateRootFor(IceUtil::Optional<Type> & s) { return new ModelPartForRoot<IceUtil::Optional<Type> >(s); } \ + +namespace Slicer { + // ModelPartForRoot + template<typename T> + ModelPartForRoot<T>::ModelPartForRoot(T & o) : + ModelObject(&o), + mp(ModelPart::CreateFor(o)) + { + } + + template<typename T> + ChildRefPtr ModelPartForRoot<T>::GetAnonChildRef(const HookFilter &) + { + mp->Create(); + return new ImplicitChildRef(mp); + } + + template<typename T> + ChildRefPtr ModelPartForRoot<T>::GetChildRef(const std::string & name, const HookFilter &) + { + if (name != rootName) { + throw IncorrectElementName(name); + } + mp->Create(); + return new ImplicitChildRef(mp); + } + + template<typename T> + void ModelPartForRoot<T>::OnEachChild(const ChildHandler & ch) + { + ch(rootName, mp, NULL); + } + + template<typename T> + bool ModelPartForRoot<T>::HasValue() const + { + return ModelObject && mp->HasValue(); + } + + template<typename T> + ModelPartType ModelPartForRoot<T>::GetType() const + { + return mp->GetType(); + } + + template<typename T> + bool ModelPartForRoot<T>::IsOptional() const + { + return mp->IsOptional(); + } + + // ModelPartForSimple + template<typename T> + ModelPartForSimple<T>::ModelPartForSimple(T & h) : + Member(h) + { + } + + template<typename T> + ModelPartForSimple<T>::ModelPartForSimple(T * h) : + Member(*h) + { + } + + template<typename T> + void ModelPartForSimple<T>::SetValue(ValueSourcePtr s) + { + s->set(Member); + } + + template<typename T> + void ModelPartForSimple<T>::GetValue(ValueTargetPtr s) + { + s->get(Member); + } + + // ModelPartForConverted + template<typename T, typename M, T M::* MV> + ModelPartForConverted<T, M, MV>::ModelPartForConverted(T & h) : + Member(h) + { + } + + template<typename T, typename M, T M::* MV> + ModelPartForConverted<T, M, MV>::ModelPartForConverted(T * h) : + Member(*h) + { + } + + // ModelPartForOptional + template<typename T> + ModelPartForOptional<T>::ModelPartForOptional(IceUtil::Optional< typename T::element_type > & h) : + OptionalMember(h) + { + if (OptionalMember) { + modelPart = new T(*OptionalMember); + } + } + + template<typename T> + ModelPartForOptional<T>::ModelPartForOptional(IceUtil::Optional< typename T::element_type > * h) : + OptionalMember(*h) + { + if (OptionalMember) { + modelPart = new T(*OptionalMember); + } + } + + template<typename T> + void ModelPartForOptional<T>::OnEachChild(const ChildHandler & ch) + { + if (OptionalMember) { + modelPart->OnEachChild(ch); + } + } + + template<typename T> + void ModelPartForOptional<T>::Complete() + { + if (OptionalMember) { + modelPart->Complete(); + } + } + + template<typename T> + void ModelPartForOptional<T>::Create() + { + if (!OptionalMember) { + OptionalMember = typename T::element_type(); + modelPart = new T(*OptionalMember); + modelPart->Create(); + } + } + + template<typename T> + ChildRefPtr ModelPartForOptional<T>::GetAnonChildRef(const HookFilter & flt) + { + if (OptionalMember) { + return modelPart->GetAnonChildRef(flt); + } + return NULL; + } + + template<typename T> + ChildRefPtr ModelPartForOptional<T>::GetChildRef(const std::string & name, const HookFilter & flt) + { + if (OptionalMember) { + return modelPart->GetChildRef(name, flt); + } + return NULL; + } + + template<typename T> + void ModelPartForOptional<T>::SetValue(ValueSourcePtr s) + { + if (OptionalMember) { + modelPart->SetValue(s); + } + } + + template<typename T> + void ModelPartForOptional<T>::GetValue(ValueTargetPtr s) + { + if (!OptionalMember) { + OptionalMember = typename T::element_type(); + modelPart = new T(*OptionalMember); + } + modelPart->GetValue(s); + } + + template<typename T> + bool ModelPartForOptional<T>::HasValue() const + { + return OptionalMember && modelPart->HasValue(); + } + + template<typename T> + ModelPartType ModelPartForOptional<T>::GetType() const + { + return T::type; + } + + template<typename T> + bool ModelPartForOptional<T>::IsOptional() const + { + return true; + }; + + template<typename T> + const Metadata & ModelPartForOptional<T>::GetMetadata() const + { + return modelPart->GetMetadata(); + } + + // ModelPartForComplex + template<typename T> + void ModelPartForComplex<T>::OnEachChild(const ChildHandler & ch) + { + for (const auto & h : hooks) { + auto modelPart = h->Get(GetModel()); + ch(h->PartName(), modelPart && modelPart->HasValue() ? modelPart : ModelPartPtr(), h); + } + } + + template<typename T> + ChildRefPtr ModelPartForComplex<T>::GetAnonChildRef(const HookFilter & flt) + { + for (const auto & h : hooks) { + if (!flt || flt(h)) { + return new MemberChildRef(h->Get(GetModel()), h->GetMetadata()); + } + } + return NULL; + } + + template<typename T> + ChildRefPtr ModelPartForComplex<T>::GetChildRef(const std::string & name, const HookFilter & flt) + { + for (const auto & h : hooks) { + if (h->PartName() == name && (!flt || flt(h))) { + return new MemberChildRef(h->Get(GetModel()), h->GetMetadata()); + } + } + return NULL; + } + + template<typename T> + const Metadata & ModelPartForComplex<T>::GetMetadata() const + { + return metadata; + } + + // ModelPartForClass + template<typename T> + ModelPartForClass<T>::ModelPartForClass(T & h) : + ModelObject(h) + { + } + + template<typename T> + ModelPartForClass<T>::ModelPartForClass(T * h) : + ModelObject(*h) + { + } + + template<typename T> + void ModelPartForClass<T>::Create() + { + ModelObject = new typename T::element_type(); + } + + template<typename T> + typename T::element_type * ModelPartForClass<T>::GetModel() + { + return ModelObject.get(); + } + + template<typename T> + ModelPartPtr ModelPartForClass<T>::GetSubclassModelPart(const std::string & name) + { + auto ref = classRefMap()->find(ModelPart::ToModelTypeName(name)); + if (ref == classRefMap()->end()) { + throw UnknownType(name); + } + return ref->second(&this->ModelObject); + } + + template<typename T> + bool ModelPartForClass<T>::HasValue() const + { + return ModelObject; + } + + template<typename T> + IceUtil::Optional<std::string> ModelPartForClass<T>::GetTypeIdProperty() const + { + return typeIdProperty; + } + + // ModelPartForStruct + template<typename T> + ModelPartForStruct<T>::ModelPartForStruct(T & o) : + ModelObject(o) + { + } + + template<typename T> + ModelPartForStruct<T>::ModelPartForStruct(T * o) : + ModelObject(*o) + { + } + + template<typename T> + T * ModelPartForStruct<T>::GetModel() + { + return &ModelObject; + } + + template<typename T> + bool ModelPartForStruct<T>::HasValue() const + { + return true; + } + + // ModelPartForEnum + template<typename T> + ModelPartForEnum<T>::ModelPartForEnum(T & s) : + modelPart(s) + { + } + + template<typename T> + ModelPartForEnum<T>::ModelPartForEnum(T * s) : + modelPart(s) + { + } + + template<typename T> + const Metadata & ModelPartForEnum<T>::GetMetadata() const + { + return metadata; + } + + // ModelPartForSequence + template<typename T> + ModelPartForSequence<T>::ModelPartForSequence(T & s) : + sequence(s) + { + } + + template<typename T> + ModelPartForSequence<T>::ModelPartForSequence(T * s) : + sequence(*s) + { + } + + template<typename T> + void ModelPartForSequence<T>::OnEachChild(const ChildHandler & ch) + { + for(auto & element : sequence) { + ch(elementName, elementModelPart(element), NULL); + } + } + + template<typename T> + ChildRefPtr ModelPartForSequence<T>::GetAnonChildRef(const HookFilter &) + { + sequence.push_back(typename element_type::value_type()); + return new ImplicitChildRef(ModelPart::CreateFor(sequence.back())); + } + + template<typename T> + const Metadata & ModelPartForSequence<T>::GetMetadata() const + { + return metadata; + } + + // ModelPartForDictionaryElement + template<typename T> + ModelPartForDictionaryElement<T>::ModelPartForDictionaryElement(typename T::key_type * k, typename T::mapped_type * v) : + key(k), + value(v) + { + } + + template<typename T> + ModelPartForDictionaryElement<T> * ModelPartForDictionaryElement<T>::GetModel() + { + return this; + } + + template<typename T> + bool ModelPartForDictionaryElement<T>::HasValue() const + { + return true; + } + + // ModelPartForDictionaryElementInserter + template<typename T> + ModelPartForDictionaryElementInserter<T>::ModelPartForDictionaryElementInserter(T & d) : + ModelPartForDictionaryElement<T>(&key, &value), + dictionary(d) + { + } + + template<typename T> + void ModelPartForDictionaryElementInserter<T>::Complete() + { + dictionary.insert(typename T::value_type(key, value)); + } + + // ModelPartForDictionary + template<typename T> + ModelPartForDictionary<T>::ModelPartForDictionary(T & d) : + dictionary(d) + { + } + + template<typename T> + ModelPartForDictionary<T>::ModelPartForDictionary(T * d) : + dictionary(*d) + { + } + + template<typename T> + void ModelPartForDictionary<T>::OnEachChild(const ChildHandler & ch) + { + for (auto & pair : dictionary) { + ch(pairName, new ModelPartForDictionaryElement<T>(const_cast<typename T::key_type *>(&pair.first), &pair.second), NULL); + } + } + + template<typename T> + ChildRefPtr ModelPartForDictionary<T>::GetAnonChildRef(const HookFilter &) + { + return new ImplicitChildRef(new ModelPartForDictionaryElementInserter<T>(dictionary)); + } + + template<typename T> + ChildRefPtr ModelPartForDictionary<T>::GetChildRef(const std::string & name, const HookFilter &) + { + if (name != pairName) { + throw IncorrectElementName(name); + } + return new ImplicitChildRef(new ModelPartForDictionaryElementInserter<T>(dictionary)); + } + + template<typename T> + const Metadata & ModelPartForDictionary<T>::GetMetadata() const + { + return metadata; + } + +} + +#endif + diff --git a/slicer/slicer/parser.cpp b/slicer/slicer/parser.cpp index df9e501..813d134 100644 --- a/slicer/slicer/parser.cpp +++ b/slicer/slicer/parser.cpp @@ -97,13 +97,7 @@ namespace Slicer { fprintbf(cpp, "// Begin Slicer code\n\n"); fprintbf(cpp, "#include <%s>\n\n", fs::change_extension(topLevelFile.filename(), ".h").string()); - fprintbf(cpp, "#include <slicer/modelParts.h>\n\n"); - fprintbf(cpp, "#include <slicer/modelPartsTypes.h>\n\n"); - fprintbf(cpp, "#define templateMODELPARTFOR(Type, ModelPart) \\\n"); - fprintbf(cpp, "template <> ModelPartPtr DLL_PUBLIC ModelPartFor(IceUtil::Optional<Type> & t) { return new ModelPartForOptional< ModelPart< Type > >(t); } \\\n"); - fprintbf(cpp, "template <> ModelPartPtr DLL_PUBLIC ModelPartFor(IceUtil::Optional<Type> * t) { return new ModelPartForOptional< ModelPart< Type > >(t); } \\\n"); - fprintbf(cpp, "template <> ModelPartPtr DLL_PUBLIC ModelPartFor(Type & t) { return new ModelPart< Type >(t); } \\\n"); - fprintbf(cpp, "template <> ModelPartPtr DLL_PUBLIC ModelPartFor(Type * t) { return new ModelPart< Type >(t); }\n\n"); + fprintbf(cpp, "#include <slicer/modelPartsTypes.impl.h>\n\n"); fprintbf(cpp, "namespace Slicer {\n"); return true; } @@ -141,11 +135,14 @@ namespace Slicer { Slicer::defineRootName(const std::string & type, const std::string & name) const { fprintbf(cpp, "template<>\n"); - fprintbf(cpp, "DLL_PUBLIC std::string ModelPartForRoot< %s >::rootName(\"%s\");\n\n", + fprintbf(cpp, "std::string ModelPartForRoot< %s >::rootName(\"%s\");\n\n", type, name); fprintbf(cpp, "template<>\n"); - fprintbf(cpp, "DLL_PUBLIC std::string ModelPartForRoot< IceUtil::Optional< %s > >::rootName(\"Optional%s\");\n\n", + fprintbf(cpp, "std::string ModelPartForRoot< IceUtil::Optional< %s > >::rootName(\"Optional%s\");\n\n", type, name); + + fprintbf(cpp, "template class ModelPartForRoot< %s >;\n\n", type); + fprintbf(cpp, "template class ModelPartForRoot< IceUtil::Optional< %s > >;\n\n", type); } bool @@ -164,7 +161,7 @@ namespace Slicer { fprintbf(cpp, "template<>\n"); auto typeId = metaDataValue("slicer:typeid:", c->getMetaData()); - fprintbf(cpp, "DLL_PUBLIC std::string ModelPartForClass< %s >::typeIdProperty(\"%s\");\n\n", + fprintbf(cpp, "std::string ModelPartForClass< %s >::typeIdProperty(\"%s\");\n\n", typeToString(decl), typeId ? *typeId : "slicer-typeid"); @@ -194,17 +191,17 @@ namespace Slicer { } fprintbf(cpp, "}\n\n"); - fprintbf(cpp, "template<>\nDLL_PUBLIC TypeId\nModelPartForClass< %s >::GetTypeId() const\n{\n", + fprintbf(cpp, "template<>\nTypeId\nModelPartForClass< %s >::GetTypeId() const\n{\n", typeToString(decl)); fprintbf(cpp, "\tauto id = ModelObject->ice_id();\n"); fprintbf(cpp, "\treturn (id == \"%s\") ? TypeId() : ModelPart::ToExchangeTypeName(id);\n}\n\n", c->scoped()); - fprintbf(cpp, "template<>\nDLL_PUBLIC Metadata ModelPartForComplex< %s >::metadata ", + fprintbf(cpp, "template<>\nMetadata ModelPartForComplex< %s >::metadata ", c->scoped()); copyMetadata(c->getMetaData()); - fprintbf(cpp, "templateMODELPARTFOR(::IceInternal::Handle< %s >, ModelPartForClass);\n\n", + fprintbf(cpp, "MODELPARTFOR(::IceInternal::Handle< %s >, ModelPartForClass);\n\n", c->scoped()); classNo += 1; @@ -227,11 +224,11 @@ namespace Slicer { auto name = metaDataValue("slicer:root:", c->getMetaData()); defineRootName(c->scoped(), name ? *name : c->name()); - fprintbf(cpp, "template<>\nDLL_PUBLIC Metadata ModelPartForComplex< %s >::metadata ", + fprintbf(cpp, "template<>\nMetadata ModelPartForComplex< %s >::metadata ", c->scoped()); copyMetadata(c->getMetaData()); - fprintbf(cpp, "templateMODELPARTFOR(%s, ModelPartForStruct);\n\n", + fprintbf(cpp, "MODELPARTFOR(%s, ModelPartForStruct);\n\n", c->scoped()); return true; @@ -243,7 +240,7 @@ namespace Slicer { if (!cpp) return; fprintbf(cpp, "template<>\n"); - fprintbf(cpp, "DLL_PUBLIC ModelPartForComplex< %s >::Hooks ", + fprintbf(cpp, "ModelPartForComplex< %s >::Hooks ", it->scoped()); fprintbf(cpp, "ModelPartForComplex< %s >::hooks {\n", it->scoped()); @@ -350,7 +347,7 @@ namespace Slicer { auto name = metaDataValue("slicer:root:", e->getMetaData()); defineRootName(e->scoped(), name ? *name : e->name()); - fprintbf(cpp, "templateMODELPARTFOR(%s, ModelPartForEnum);\n\n", + fprintbf(cpp, "MODELPARTFOR(%s, ModelPartForEnum);\n\n", e->scoped()); } @@ -365,7 +362,7 @@ namespace Slicer { fprintbf(cpp, "// Sequence %s\n", s->name()); fprintbf(cpp, "template<>\n"); - fprintbf(cpp, "DLL_PUBLIC ChildRefPtr ModelPartForSequence< %s >::GetChildRef(const std::string & name, const HookFilter & flt)\n{\n", + fprintbf(cpp, "ChildRefPtr ModelPartForSequence< %s >::GetChildRef(const std::string & name, const HookFilter & flt)\n{\n", s->scoped()); auto iname = metaDataValue("slicer:item:", s->getMetaData()); if (iname) { @@ -378,26 +375,26 @@ namespace Slicer { fprintbf(cpp, "\treturn GetAnonChildRef(flt);\n}\n\n"); fprintbf(cpp, "template<>\n"); - fprintbf(cpp, "DLL_PUBLIC ModelPartPtr\n"); + fprintbf(cpp, "ModelPartPtr\n"); fprintbf(cpp, "ModelPartForSequence< %s >::elementModelPart(typename %s::value_type & e) const {\n", s->scoped(), s->scoped()); - fprintbf(cpp, "\treturn ModelPartFor(e);\n}\n\n"); + fprintbf(cpp, "\treturn ModelPart::CreateFor(e);\n}\n\n"); fprintbf(cpp, "template<>\n"); auto ename = metaDataValue("slicer:element:", s->getMetaData()); - fprintbf(cpp, "DLL_PUBLIC std::string ModelPartForSequence< %s >::elementName(\"%s\");\n\n", + fprintbf(cpp, "std::string ModelPartForSequence< %s >::elementName(\"%s\");\n\n", s->scoped(), ename ? *ename : "element"); auto name = metaDataValue("slicer:root:", s->getMetaData()); defineRootName(s->scoped(), name ? *name : s->name()); - fprintbf(cpp, "template<>\nDLL_PUBLIC Metadata ModelPartForSequence< %s >::metadata ", + fprintbf(cpp, "template<>\nMetadata ModelPartForSequence< %s >::metadata ", s->scoped()); copyMetadata(s->getMetaData()); - fprintbf(cpp, "templateMODELPARTFOR(%s, ModelPartForSequence);\n\n", + fprintbf(cpp, "MODELPARTFOR(%s, ModelPartForSequence);\n\n", s->scoped()); } @@ -413,12 +410,12 @@ namespace Slicer { fprintbf(cpp, "// Dictionary %s\n", d->name()); auto iname = metaDataValue("slicer:item:", d->getMetaData()); fprintbf(cpp, "template<>\n"); - fprintbf(cpp, "DLL_PUBLIC std::string ModelPartForDictionary< %s >::pairName(\"%s\");\n\n", + fprintbf(cpp, "std::string ModelPartForDictionary< %s >::pairName(\"%s\");\n\n", d->scoped(), iname ? *iname : "element"); fprintbf(cpp, "template<>\n"); - fprintbf(cpp, "DLL_PUBLIC ModelPartForComplex< ModelPartForDictionaryElement< %s > >::Hooks ", + fprintbf(cpp, "ModelPartForComplex< ModelPartForDictionaryElement< %s > >::Hooks ", d->scoped()); fprintbf(cpp, "ModelPartForComplex< ModelPartForDictionaryElement< %s > >::hooks {\n", d->scoped()); @@ -451,11 +448,11 @@ namespace Slicer { auto name = metaDataValue("slicer:root:", d->getMetaData()); defineRootName(d->scoped(), name ? *name : d->name()); - fprintbf(cpp, "template<>\nDLL_PUBLIC Metadata ModelPartForDictionary< %s >::metadata ", + fprintbf(cpp, "template<>\nMetadata ModelPartForDictionary< %s >::metadata ", d->scoped()); copyMetadata(d->getMetaData()); - fprintbf(cpp, "template<>\nDLL_PUBLIC Metadata ModelPartForComplex<ModelPartForDictionaryElement< %s > >::metadata ", + fprintbf(cpp, "template<>\nMetadata ModelPartForComplex<ModelPartForDictionaryElement< %s > >::metadata ", d->scoped()); copyMetadata(d->getMetaData()); @@ -470,7 +467,7 @@ namespace Slicer { d->scoped(), d->scoped()); - fprintbf(cpp, "templateMODELPARTFOR(%s, ModelPartForDictionary);\n\n", + fprintbf(cpp, "MODELPARTFOR(%s, ModelPartForDictionary);\n\n", d->scoped()); } diff --git a/slicer/slicer/slicer.h b/slicer/slicer/slicer.h index 8a439d9..267b597 100644 --- a/slicer/slicer/slicer.h +++ b/slicer/slicer/slicer.h @@ -18,7 +18,7 @@ namespace Slicer { DeserializeAnyWith(DeserializerPtr deserializer) { Object object; - deserializer->Deserialize(new ModelPartForRoot<Object>(object)); + deserializer->Deserialize(ModelPart::CreateRootFor<Object>(object)); return object; } @@ -40,7 +40,7 @@ namespace Slicer { void SerializeAnyWith(Object object, SerializerPtr serializer) { - serializer->Serialize(new ModelPartForRoot<Object>(object)); + serializer->Serialize(ModelPart::CreateRootFor<Object>(object)); } template <typename Serializer, typename Object, typename ... SerializerParams> diff --git a/slicer/test/compilation.cpp b/slicer/test/compilation.cpp index bd869d9..da13652 100644 --- a/slicer/test/compilation.cpp +++ b/slicer/test/compilation.cpp @@ -11,15 +11,9 @@ BOOST_TEST_DONT_PRINT_LOG_VALUE(std::type_info); #define TypeTest(Var, Expr, Explicit, Expected) \ Var obj = Expr; \ - Slicer::ModelPartPtr mpp = new Slicer::Explicit<Var>(obj); \ + Slicer::ModelPartPtr mpp = Slicer::ModelPart::CreateFor(obj); \ BOOST_REQUIRE_EQUAL(Slicer::Expected, mpp->GetType()); \ - \ - Slicer::ModelPartPtr autoMpp = Slicer::ModelPartFor(obj); \ - BOOST_REQUIRE_EQUAL(Slicer::Expected, autoMpp->GetType()); \ - \ - Slicer::ModelPartPtr autoPtrMpp = Slicer::ModelPartFor(&obj); \ - BOOST_REQUIRE_EQUAL(Slicer::Expected, autoPtrMpp->GetType()); \ -\ + \ auto mppvalue = mpp.get(); \ auto amppvalue = mpp.get(); \ auto apmppvalue = mpp.get(); \ |